postgresql高可用需流复制、故障切换、访问入口三者协同:流复制靠wal参数与pg_basebackup初始化,patroni/repmgr选型依运维能力,keepalived vip须联动角色检测。

PostgreSQL 在 Linux 上实现高可用,核心不是堆组件,而是理清角色分工:流复制保证数据不丢,故障切换机制保证服务不中断,访问入口保证应用无感。三者缺一不可,任意一环配置不当,都会导致“看似高可用,实则单点故障”。
PostgreSQL 流复制是高可用的地基
主库必须开启 WAL 流式推送能力,仅靠 pg_basebackup 备份是不够的。关键参数必须显式设置(以 PostgreSQL 15+ 为例):
-
listen_addresses = '*':从库 walreceiver 需主动连接,localhost 不够用 -
wal_level = replica:低于此值无法启用流复制;logical仅在需要逻辑订阅时开启 -
max_wal_senders >= 从库数量:每个从库占用一个 sender 连接,设为 0 则复制通道关闭 -
wal_keep_size = 1GB(推荐):防止从库短暂断连后 WAL 被清理,避免requested WAL segment has already been removed错误 -
archive_mode = on+archive_command:非强制但强烈建议,为 PITR 和备份兜底提供基础
从库初始化必须使用 pg_basebackup,带 -R 和 -X stream 参数:
pg_basebackup -h 10.197.167.145 -D /var/lib/pgsql/15/data \ -U replicator -P -v -Fp -X stream -R
该命令会自动生成 standby.signal、正确配置 primary_conninfo,并确保起点 WAL 位点一致。手写 recovery.conf(PG
pg_hba.conf 权限必须分两层配,顺序不能错
主库的 pg_hba.conf 需同时放行两类连接,且 replication 规则必须放在普通连接规则之前(否则被 host all all ... 拦截):
# 先放行复制连接(只允许指定 IP + 复制用户) host replication replicator 10.197.167.146/32 scram-sha-256 # 再放行应用连接 host all all 0.0.0.0/0 scram-sha-256
注意:replication 是固定数据库名关键字,不能写成 postgres 或 all;认证方式统一用 scram-sha-256,避免明文传输密码。改完后执行 pg_ctl reload -D /path/to/data,不要 restart。
选 Patroni 还是 repmgr?看运维成熟度
- Patroni + etcd:适合中大型生产环境。它通过 etcd 协调选主、状态同步和自动故障转移,支持 pg_rewind 快速回切,能处理网络分区场景(配合仲裁策略)。需独立部署 etcd 集群(至少 3 节点),并确保所有节点可双向免密连接 PostgreSQL 实例。
- repmgr:轻量、易上手,适合中小团队或过渡阶段。依赖本地文件或 PostgreSQL 自身做元数据存储,无需额外中间件。但故障检测较简单,脑裂防护弱于 Patroni,需人工干预场景更多。
二者都要求:所有节点 PostgreSQL 用户权限一致、SSH 免密互通、时间同步(chrony 或 ntpd)、防火墙开放对应端口(如 Patroni REST API 8000、etcd 2379、PostgreSQL 5432)。
Keepalived 提供虚拟 IP,让应用“看不见”切换
VIP(如 192.168.1.100)漂移本身不等于主从切换,必须配合脚本联动 PostgreSQL 角色变更:
- 主库上
notify_master脚本:VIP 漂入时,确保本机是 promoted 状态(SELECT pg_is_in_recovery()返回 false) - 从库上
notify_backup脚本:VIP 漂出时,检查是否已升主;若未升主,拒绝接管 VIP - 使用
track_script检测pg_is_in_recovery()和pg_is_wal_receiver_connected(),比单纯 ping 端口更真实
这样,应用始终连接 VIP,主库宕机后 Keepalived 检测失败 → 触发切换 → Patroni/repmgr 升备为主 → Keepalived 将 VIP 漂移到新主 → 应用连接自动恢复。
不复杂但容易忽略











