Ubuntu 20下PostgreSQL 17.6 源码编译安装,排除doc包
前些年写了一个PostgreSQL自动化安装的shell脚本,这几年一直在用,中间有微调过但都可以正常一键安装,今天尝试安装一个最新版的PostgreSQL 17.6(Aug. 11, 2025发布的),发现编译过程中死活过不去,遇到如下几个错误
1,ERROR: `xmllint' is missing on your system.,安装libxml2-utils依赖包后没有出现了
sudo apt update
sudo apt install libxml2-utils
2,postgres.sgml:24: element book: validity error : No declaration for attribute id of element book
是在 PostgreSQL 源码编译文档(make world 会编译 doc) 时出现的 XML/SGML 校验错误。请教大佬后说是“从17开始,与源码包同时提供了doc包”。
默认(make world)会编译docs,但是编译docs会有一系列的依赖,经过安装如下依赖包后依旧无解。。。。。。sudo apt update
sudo apt install docbook docbook-dsssl docbook-xml docbook-xsl
sudo apt install xsltproc fop
3,移除docs的编译
参考:https://www.postgresql.org/docs/current/install-make.html#CONFIGURE-OPTIONS
翻阅了一下官方文档,提示说If you want to build everything that can be built, including the additional modules (contrib), but without the documentation, type instead:
make world-bin
If you built the world without the documentation above, type instead:
make install-world-bin
因此编译时用make world-bin替代原来的make world,安装时用make install-world-bin替代原来的make install-world,来绕过docs的编译,随后安装成功。


附,PostgreSQL 17 自动化安装代码
#!/bin/bash
# 1,PostgreSQL源码包名称(假设已下载并位于当前目录的同级目录中)
POSTGRESQL_SRC="postgresql-17.6.tar.gz" # 替换XX.X为你的PostgreSQL版本
POSTGRESQL_DIR="postgresql-17.6" # 解压后的目录名,同样替换XX.X
# 2,安装目录
INSTALL_DIR="/usr/local/pgsql17/server"
# 3,端口号
PORT=1800
# 4,初始密码(通过参数传入,默认为空)
INIT_PASSWORD="postgres_init_pwd"
if [ $# -gt 0 ]; then
INIT_PASSWORD="$1"
fi
# 实例目录
INSTANCE_DATA_DIR="/usr/local/pgsql18/pg${PORT}/data"
INSTANCE_LOG_DIR="/usr/local/pgsql18/pg${PORT}/log"
# 创建postgres用户(如果尚未存在)
if ! id postgres &>/dev/null; then
echo "Creating postgres user..."
sudo groupadd postgres
sudo useradd -m -g postgres postgres -s /bin/bash
echo "Postgres user created successfully."
else
echo "Postgres user already exists."
fi
# 检查目录是否存在
if [ ! -d "$INSTALL_DIR" ]; then
echo "dir '$INSTALL_DIR' not existing,creating..."
mkdir -p "$INSTALL_DIR"
echo "dir '$INSTALL_DIR' created"
else
echo "dir '$INSTALL_DIR' existing"
fi
# 检查实例目录是否存在
if [ ! -d "$INSTANCE_DATA_DIR" ]; then
echo "dir '$INSTANCE_DATA_DIR' not existing,creating..."
mkdir -p "$INSTANCE_DATA_DIR"
mkdir -p "$INSTANCE_LOG_DIR"
echo "dir '$INSTANCE_DATA_DIR' created"
else
echo "dir '$INSTANCE_DATA_DIR' existing"
fi
# 安装编译依赖项
echo "############################Installing build dependencies... "
sudo apt update -y > /dev/null 2>&1
sudo apt install -y systemtap-sdt-dev libicu-dev libreadline-dev zlib1g-dev libssl-dev libpam0g-dev libxml2-dev libxslt1-dev libldap2-dev libsystemd-dev tcl-dev libpython3-dev libperl-dev libicu-dev pkg-config > /dev/null 2>&1
echo "############################Done."
# 解压源码包
echo "############################Extracting PostgreSQL source code... "
tar -xzvf "$POSTGRESQL_SRC" > /dev/null 2>&1
echo "############################Done."
# 进入解压后的目录
cd "$POSTGRESQL_DIR"
# 配置PostgreSQL(这里使用默认配置,但可以添加--prefix等选项)
echo "############################Configuring PostgreSQL... "
#make clean
./configure --prefix="$INSTALL_DIR" --with-openssl > /dev/null 2>&1
echo "############################Done."
# 编译PostgreSQL
echo -n "############################Compiling PostgreSQL (this may take a while)... "
# pg 17之前,用make world -j$(nproc) > /dev/null 2>&1
make world-bin -j$(nproc) > /dev/null 2>&1
echo "############################Done."
# 安装PostgreSQL
echo "############################Installing PostgreSQL... "
# pg 17之前,用make install-world > /dev/null 2>&1
sudo make install-world-bin > /dev/null 2>&1
echo "############################Done."
# 初始化数据库(使用postgres用户)
echo "############################Initializing PostgreSQL database..."
chown -R postgres:postgres $INSTALL_DIR
chmod 700 -R $INSTALL_DIR
chown -R postgres:postgres $INSTANCE_DATA_DIR
chmod 700 -R $INSTANCE_DATA_DIR
chown -R postgres:postgres $INSTANCE_LOG_DIR
chmod 700 -R $INSTANCE_LOG_DIR
sudo -u postgres $INSTALL_DIR/bin/initdb -D $INSTANCE_DATA_DIR
# 1. 创建systemd服务(使用指定模板)
echo "############################Creating systemd service..."
cat <<EOF | sudo tee /etc/systemd/system/postgresql${PORT}.service
[Unit]
Description=PostgreSQL database server
After=network.target
[Service]
Type=forking
User=postgres
Group=postgres
OOMScoreAdjust=-1000
Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
Environment=PG_OOM_ADJUST_VALUE=0
#PGSTARTTIMEOUT should be less than TimeoutSec value.
Environment=PGSTARTTIMEOUT=300
Environment=PGDATA=${INSTANCE_DATA_DIR}
ExecStart=${INSTALL_DIR}/bin/pg_ctl start -D \${PGDATA} -s -w -t \${PGSTARTTIMEOUT}
ExecStop=${INSTALL_DIR}/bin/pg_ctl stop -D \${PGDATA} -s -m fast
ExecReload=${INSTALL_DIR}/bin/pg_ctl reload -D \${PGDATA} -s
TimeoutSec=300
KillMode=mixed
[Install]
WantedBy=multi-user.target
EOF
# 2. 修改pg_hba.conf
echo "############################Modifying pg_hba.conf..."
sudo -u postgres sed -i "s/^host.*all.*all.*127.0.0.1\/32.*trust/host all all 0.0.0.0\/0 md5/" ${INSTANCE_DATA_DIR}/pg_hba.conf
sudo -u postgres sed -i "s/^host.*all.*all.*::1\/128.*trust/host all all ::0\/0 md5/" ${INSTANCE_DATA_DIR}/pg_hba.conf
# 3. 修改postgresql.conf
echo "############################Modifying postgresql.conf..."
sudo -u postgres sed -i "s/^#listen_addresses = 'localhost'/listen_addresses = '*'/" ${INSTANCE_DATA_DIR}/postgresql.conf
sudo -u postgres sed -i "s/^#port = 5432/port = ${PORT}/" ${INSTANCE_DATA_DIR}/postgresql.conf
# 打开日志
sed -i "s/^#logging_collector.*/logging_collector = on/" ${INSTANCE_DATA_DIR}/postgresql.conf
sed -i "s/^#log_destination.*/log_destination = 'stderr, csvlog'/" ${INSTANCE_DATA_DIR}/postgresql.conf
sed -i "s|^#log_directory.*|log_directory = 'log'|" ${INSTANCE_DATA_DIR}/postgresql.conf
sed -i "s/^#log_filename.*/log_filename = 'postgresql-%Y-%m-%d.log'/" ${INSTANCE_DATA_DIR}/postgresql.conf
sed -i "s/^#log_rotation_age.*/log_rotation_age = 1d/" ${INSTANCE_DATA_DIR}/postgresql.conf
# 启用并启动服务
echo "############################Starting PostgreSQL service..."
sudo systemctl daemon-reload
sudo systemctl enable postgresql${PORT}
sudo systemctl start postgresql${PORT}
# 4. 修改postgres用户密码(如果提供了初始密码)
if [ -n "$INIT_PASSWORD" ]; then
echo "Changing postgres user password..."
sleep 5 # 等待PostgreSQL完全启动
sudo -u postgres ${INSTALL_DIR}/bin/psql -p ${PORT} -c "ALTER USER postgres WITH PASSWORD '${INIT_PASSWORD}';"
echo "Postgres user password changed successfully."
else
echo "No initial password provided, keeping default password."
fi
# 5. 修改环境变量
echo "############################Checking and setting up PostgreSQL environment variables in /etc/profile..."
ENV_CONTENT="# PostgreSQL Environment (added by install script)
export PGHOME=${INSTALL_DIR%}
export PATH=\$PATH:\$PGHOME/bin"
# 检查是否已存在相关配置
if ! grep -q "PGBASE=${INSTALL_DIR%}" /etc/profile; then
echo "Adding PostgreSQL environment variables to /etc/profile..."
echo "$ENV_CONTENT" | sudo tee -a /etc/profile > /dev/null
source /etc/profile
echo "Environment variables added successfully."
else
echo "PostgreSQL environment variables already exist in /etc/profile, skipping..."
fi
# 打印完成消息
echo "############################PostgreSQL installation and database initialization completed."
echo "############################PostgreSQL is now running on port ${PORT}"
if [ -n "$INIT_PASSWORD" ]; then
echo "You can connect using: psql -h 127.0.0.1 -p ${PORT} -U postgres -W"
echo "Password: ${INIT_PASSWORD}"
else
echo "You can connect using: psql -h 127.0.0.1 -p ${PORT} -U postgres"
fi
# 回到脚本的起始目录(如果需要的话)
cd -
浙公网安备 33010602011771号