ARTICLE · 1344430
D0326. PostgreSQL 源码编译安装(RHEL 族系):PGDG 不给 EL7 出 PG16 了,老系统想上 18
生产机想上 PG18,
dnf install翻遍 PGDG 源才发现:EL7 通道更新止步 PG15,PG16/17/18 的 rhel-7 目录直接 404。CentOS 7.9 又还在跑,换 Rocky 9 没排期。两条路——要么忍,要么把源码拉下来自己编。本文按 PG18 官方文档 17 章落地:CentOS 7.9 编译 PG15、Rocky 9 编译 PG18,工具链和坑全部实测过。
一、什么时候才需要源码编译
先分清三种动机,别为编而编:
--prefix |
PGDG 官方源 EL7 通道实测:rhel-7 目录只到 PG15(15.19),PG16/17/18 均无 EL7 包。RHEL9 通道到 PG18。所以 RHEL 族系里"EL7 老线 + EL9 新线"两条编译路线不一样,这是本文主结构。
版本线也得先认:PG15 是社区支持周期的收尾代(转 ESR 商业维护),PG16/17 在 RHEL9 上有官方包,PG18 是当前最新主线。EL7 上源码编译的现实顶就是 PG15——不是想不上 18,是 OpenSSL 和 gcc 双卡(下一节)。真把 PG18 拉到 EL7 上跑,等于自己当自己的支持方,生产上掂量。
二、工具链摸底(编译前先跑一遍)
PG18 官方文档 17.1 节的硬性依赖:GNU make ≥3.81、C99 编译器(官方推荐新 GCC)、Flex + Bison ≥2.3、Perl ≥5.14、readline、zlib、ICU4C ≥4.2;要开 SSL 的话 OpenSSL 最低 1.1.1;WAL 压缩用 zstd ≥1.4.0(可选)。
# 三个数字决定你能编到哪:gcc / openssl / 库齐不齐
gcc --version; openssl version; rpm -q perl bison flex make # EL7 用 rpm,RHEL9 也兼容
| 1.0.2k | |||
这里有个反直觉的点:卡 EL7 的不是 gcc 而是 OpenSSL。PG15 官方把 OpenSSL 下限放在 1.0.1,EL7 的 1.0.2k 压线通过,所以"EL7 编译 PG15 + SSL"这条路是通的;PG17 起下限提到 1.1.1,EL7 无解(系统仓没有,SCL 也没有 OpenSSL 1.1.1 包),要么 --without-ssl 裸奔,要么先源码编一份 OpenSSL 1.1.1 再编 PG——double source 的维护成本,老系统上值得三思。
三、CentOS 7.9 线:devtoolset-11 + PG15
EL7 的 gcc 4.8.5 太老,先挂 SCL 源装 devtoolset(vault 里确认过 7–11 都在)。SCL 的本质是把新编译器装到 /opt/rh 隔离目录、不碰系统 glibc,所以编出来的 PG 二进制在 EL7 上跑没有任何兼容问题,这是它比源码编 gcc 干净得多的原因:
# 1) SCL 源 + devtoolset-11(CentOS 7.9 EOL 后先确认 repos 指向 vault)
sudo yum install -y centos-release-scl
sudo yum install -y devtoolset-11-gcc devtoolset-11-gcc-c++ devtoolset-11-binutils
# 2) 构建依赖(系统仓库就有)
sudo yum install -y tar make openssl-devel readline-devel zlib-devel libicu-devel flex bison perl
# 3) 源码(15.9 是 PG15 社区版最新 patch,15 之后转 ESR 商业维护)
curl -O https://ftp.postgresql.org/pub/source/v15.9/postgresql-15.9.tar.gz
tar xzf postgresql-15.9.tar.gz && cd postgresql-15.9
# 4) 编译(不 source 整套 devtoolset 环境,CC/CXX 直指 /opt 下编译器更省事)
CC=/opt/rh/devtoolset-11/root/usr/bin/gcc CXX=/opt/rh/devtoolset-11/root/usr/bin/g++ \
./configure --prefix=/usr/local/pgsql15 --with-openssl
make -j"$(nproc)"
sudo make install
--prefix定死安装布局,15/18 并存就/usr/local/pgsql15、/usr/local/pgsql18各走各的。configure 阶段报OpenSSL版本不足,先看第二节那个矩阵,别急着换源码。为什么用CC=直指而不是scl enable devtoolset-11 bash:直指只换编译器一个变量,环境最小、可复现,批量机上写进脚本不依赖 shell 状态。
四、Rocky 9 线:系统工具链 + PG18
# 1) 构建依赖(RHEL9 自带 gcc 11 + OpenSSL 1.1.1,一步到位)
sudo dnf install -y gcc gcc-c++ make openssl-devel readline-devel zlib-devel \
libicu-devel flex bison tar pkgconf-pkg-config systemd-devel liblz4-devel libzstd-devel
# 2) 源码(18.6 为当前最新 patch;19 还在 RC,别上生产)
curl -O https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.gz
tar xzf postgresql-18.6.tar.gz && cd postgresql-18.6
# 3) 编译(--with-systemd 需要 systemd-devel,让 postgres 进程直接给 systemd 发 ready 通知)
./configure --prefix=/usr/local/pgsql18 --with-openssl --with-zstd --with-systemd
make -j"$(nproc)"
sudo make install
RHEL9 侧两个细节:pkgconf-pkg-config 是给 ICU 探测用的(官方文档 17.1 写明 ICU 4.6+ 走 pkg-config),漏装会在 configure 末尾提示找不到 ICU,装完重跑;--with-systemd 编出来的 postgres 能原生对接 systemd 的 Type=notify,unit 文件比 forking 写法更准(见第五节)。
五、初始化 + 服务化(两线通用写法)
# 1) 独立 postgres 用户 + initdb(locale/encoding 不传参默认 UTF-8,多租户机建议显式)
sudo useradd -m postgres
sudo chown -R postgres /usr/local/pgsql15 # 18 换对应目录
sudo -u postgres /usr/local/pgsql15/bin/initdb -D /usr/local/pgsql15/data
# 2) 手写 systemd unit(源码包不带服务文件,这是编译安装和包源安装最大的运维差异)
sudo tee /etc/systemd/system/pgsql15.service <<'EOF'
[Unit]
Description=PostgreSQL 15 (source build)
After=network-online.target
[Service]
User=postgres
Type=forking
ExecStart=/usr/local/pgsql15/bin/pg_ctl -D /usr/local/pgsql15/data -l /var/log/pgsql15.log -w start
ExecStop=/usr/local/pgsql15/bin/pg_ctl -D /usr/local/pgsql15/data -m fast stop
ExecReload=/usr/local/pgsql15/bin/pg_ctl -D /usr/local/pgsql15/data reload
TimeoutSec=60
[Install]
WantedBy=multi-user.target
EOF
# 3) 起服务
sudo systemctl daemon-reload
sudo systemctl enable --now pgsql15
带
--with-systemd编译的 PG18 可以改用Type=notify+ExecStart=/usr/local/pgsql18/bin/postgres -D ...直接收 ready 信号,停止走ExecStop=... postgres -c smart;不确定就先按上面的Type=forking+ pg_ctl,稳。多版本并存时端口错开:postgresql.conf里port = 5433,unit 名跟着叫pgsql18,数据目录、socket 目录全在各自 prefix 下,互不冲突。
六、验证测试
sudo -u postgres /usr/local/pgsql15/bin/psql -c 'SELECT version();'
sudo -u postgres /usr/local/pgsql15/bin/psql -c 'SHOW ssl;' # 应为 on
ss -lntp | grep -E '5432|5433'
sudo -u postgres /usr/local/pgsql15/bin/pg_dump -Fc -f /tmp/t.dump # 建个空库 dump 一把,顺带验证 contrib 工具链
RHEL 侧再补一眼 SELinux:getenforce 是 Enforcing 且连接报 permission denied 时,先 ausearch -m avc -ts recent 看拒的是什么,再决定放行还是改端口,别直接 setenforce 0 了事。
七、源码 vs 包源(PGDG),一张表定分工
先给个决策底线:EL7 上 PG15 及以下、RHEL9/Ubuntu 上任意版本,包源优先——有官方签名、升级通道现成,源码编译没有增量价值。真正该走源码的只有两类:EL7 系统被 PGDG 断供后仍要上新版本(本文主线),以及审计明确要求"只信官方 tarball"。把这两类划清楚,后面团队里就不会有"为什么这台是手写的 unit"的争论。
dnf update | ||
dnf remove | ||
--with-* | ||
八、升级策略
小版本(15.x → 15.9 这种)最省事:拉新 tarball 编完直接替换二进制目录,systemctl stop 换 stop 起,数据不动。跨大版本(15 → 18)两条路:物理升级 pg_upgrade -b /usr/local/pgsql15/bin -B /usr/local/pgsql18/bin(新旧二进制/库路径都要对齐,先 pg_dump 兜底);或者逻辑路线 dump/restore(数据量大时停机时间长,但最干净)。编 18 之前一定把 15 的 prefix 留着,别一上来就删。
九、常见坑
补一句决策提醒:如果评估完发现"EL7 就编 PG15、包源也够用",那就别编——源码线的运维成本(手写 unit、依赖路径、升级重编)是长期负债,只有在"包源断供 + 必须上新版本"这个交集里才值得还。
error while loading shared libraries | /usr/local/pgsqlXX/lib 默认搜索路径外 | /etc/ld.so.conf.d/pgsql.conf 指过去 + ldconfig |
initdb | chmod 700,属主必须是运行用户 | |
pg_upgrade 且新旧二进制/库路径要对齐 | pg_upgrade -b 旧bin -B 新bin,先做 pg_dump 兜底 | |
systemctl disable pgsql15/etc/systemd/system/pgsql15.service → 数据目录单独处置 |
上一篇:D0325. Nacos 使用管理与运维 | 下一篇:D0327. PostgreSQL 源码编译安装(Ubuntu 24.04)















































































