夜雨聆风学习资料网

ARTICLE · 1344430

D0326. PostgreSQL 源码编译安装(RHEL 族系):PGDG 不给 EL7 出 PG16 了,老系统想上 18

D0326. PostgreSQL 源码编译安装(RHEL 族系):PGDG 不给 EL7 出 PG16 了,老系统想上 18
个人开发了一个小程序,主要用于 A3 格式内容切分或缩小 A4 大小,两张 A5 发票合并为一个 A4 文档,方便打印。

生产机想上 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,工具链和坑全部实测过。

一、什么时候才需要源码编译

先分清三种动机,别为编而编:

场景
包源安装行不行
源码编译的增量
RHEL9 / Ubuntu 装最新 PG18
行(PGDG 源直接给)
一般不划算,除非要自定义编译选项
EL7 老系统要 PG15 以上
不行,PGDG EL7 止于 PG15
想上 18 只能源码,且被 OpenSSL 卡住(见下)
审计要求"只信官方 tarball + 自己编"
不行
编译选项、优化项全可控
同一台机多版本并存
可以(PGDG 也能)
--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 也兼容

平台
gcc
OpenSSL
结论
CentOS 7.9
4.8.5
1.0.2k
PG18 的 SSL 编译直接过不了(要 1.1.1),实顶是 PG15(PG15 官方最低 1.0.1)
Rocky 9 / RHEL9
11.x
1.1.1
全套满足,直接编 PG18

这里有个反直觉的点:卡 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"的争论。

维度
PGDG 包源
源码编译(本文)
版本可达
EL7 止 PG15,EL9 到 PG18
跟源码走,不受发行版卡
升级
dnf update
 一键
小版本 = 重新拉 tarball 编 + 换二进制
卸载
dnf remove
 干净
手动删 prefix + unit,数据目录自己留
自定义
编译选项定死
--with-*
 全可控(zstd/lz4/ssl/系统库)
运维负担
低
unit 手写、依赖路径自己管

八、升级策略

小版本(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、依赖路径、升级重编)是长期负债,只有在"包源断供 + 必须上新版本"这个交集里才值得还。

现象
根因
处理
EL7 编 PG18,configure 后 make 报 OpenSSL 版本
系统 1.0.2k < 1.1.1
EL7 实顶 PG15;或先编 OpenSSL 1.1.1 再编 PG
起服务报 error while loading shared libraries
库在 /usr/local/pgsqlXX/lib 默认搜索路径外
写 /etc/ld.so.conf.d/pgsql.conf 指过去 + ldconfig
initdb
 报目录非空/权限
数据目录没 chown 给 postgres 或已有数据
空目录 + chmod 700,属主必须是运行用户
跨大版本升级(15→18)
物理升级只能 pg_upgrade 且新旧二进制/库路径要对齐
编译前把旧版 prefix 留着;跑 pg_upgrade -b 旧bin -B 新bin,先做 pg_dump 兜底
卸载"干净"
源码安装卸载 = 删 prefix 目录 + 删 unit,数据目录不会自动删
systemctl disable pgsql15
 → 删 /etc/systemd/system/pgsql15.service → 数据目录单独处置

上一篇:D0325. Nacos 使用管理与运维 | 下一篇:D0327. PostgreSQL 源码编译安装(Ubuntu 24.04)

#DevOps  #PostgreSQL  #源码编译  #devtoolset  #RHEL族系  #运维实战 

回首页,搜索你想要的文档

在首页搜索框输入关键词,快速定位资料

文库首页搜索指引 立即搜索

相关学习资料