摘要
在 PostgreSQL 高可用架构中,自动故障切换(Failover)是保障数据库业务连续性的核心能力。然而在实际生产环境中,经常出现主节点已经故障,但备节点迟迟未提升(Promote)为新的主节点的情况,导致业务长时间中断。
本文结合实际 PostgreSQL + Keepalived + repmgr 集群案例,从故障现象、架构设计、日志分析、故障定位、原因分析、解决方案、预防措施等多个维度深入分析 PostgreSQL 高可用故障切换失效问题。
本文适用于:
PostgreSQL 主从复制架构
PostgreSQL + Keepalived
PostgreSQL + repmgr
PostgreSQL + VIP高可用
PostgreSQL HA运维人员
数据库管理员(DBA)
一、故障背景
某生产环境部署 PostgreSQL 高可用集群:
集群架构
VIP: 192.168.18.101 | Keepalived | +--------------+--------------+ | | PostgreSQL 主库 PostgreSQL 备库 10.197.167.123 10.197.167.124服务器配置:
| 节点 | IP | 角色 |
|---|---|---|
| node1 | 10.197.167.123 | Primary |
| node2 | 10.197.167.124 | Standby |
| VIP | 192.168.18.101 | 业务访问地址 |
软件版本:
| 软件 | 版本 |
|---|---|
| PostgreSQL | 16 |
| repmgr | 5.x |
| Keepalived | 2.x |
| Rocky Linux | 9 |
业务通过 VIP 访问数据库。
二、故障现象
某日主节点发生异常:
systemctl stop postgresql或者:
kill -9 postgres主库已经停止。
理论上应该发生:
主库故障 ↓ Keepalived检测失败 ↓ VIP漂移 ↓ 备库Promote ↓ 业务恢复但实际情况:
主库停止 ↓ VIP未漂移 ↓ 备库未提升 ↓ 业务中断故障持续超过30分钟。
三、故障现场分析
3.1 查看VIP
主库:
ip a发现:
192.168.18.101 依然存在说明:
Keepalived未降级VIP没有释放。
3.2 查看Keepalived状态
systemctl status keepalived结果:
active (running)Keepalived服务正常。
但VIP未漂移。
说明:
健康检查失效四、检查健康检测脚本
配置:
vrrp_script chk_pgsql { script "/etc/keepalived/check_pg.sh" interval 2 weight -20 }查看脚本:
cat check_pg.sh内容:
ps -ef | grep postgres存在严重问题。
五、错误脚本分析
假设 PostgreSQL 已停止:
ps -ef | grep postgres返回:
postgres 12345 grep postgres脚本判断:
if ps -ef | grep postgres then exit 0 fi结果:
误判存活Keepalived认为:
PostgreSQL正常不会触发切换。
六、正确检测方式
推荐:
pg_isready示例:
pg_isready -h 127.0.0.1 -p 5432正常:
accepting connections异常:
no response脚本:
#!/bin/bash pg_isready \ -h 127.0.0.1 \ -p 5432 \ -U postgres if [ $? -eq 0 ] then exit 0 else exit 1 fi七、第二类故障:数据库进程存在但服务不可用
最常见问题:
Postgres进程存在 但无法连接例如:
ps -ef | grep postgres显示:
postgres running但:
psql连接失败。
原因:
WAL阻塞
IO故障
死锁
磁盘满
此时:
进程检测失效必须采用:
psql -c "select 1"检测。
八、repmgr状态检查
查看:
repmgr cluster show正常:
ID | Name | Role 1 | node1 | primary 2 | node2 | standby故障后:
node1 unreachable node2 standby发现:
node2没有自动提升九、检查repmgrd服务
查看:
systemctl status repmgrd结果:
inactive问题找到。
repmgr虽然安装:
repmgrd未启动因此:
无法自动故障切换十、启动自动切换服务
systemctl enable repmgrd systemctl start repmgrd验证:
repmgr service status结果:
running十一、检查自动提升配置
repmgr.conf:
failover=automatic错误配置:
failover=manual此时:
只告警 不切换修改:
failover=automatic重启:
systemctl restart repmgrd十二、网络脑裂分析
另一种情况:
主库网络断开。
例如:
主库 ↔ 备库 连接中断主库实际上仍在运行。
备库认为:
主库故障发生Promote。
结果:
双主即脑裂。
十三、脑裂危害
例如:
主库写入:
订单10001备库写入:
订单10002网络恢复后:
数据冲突无法自动合并。
造成:数据丢失
数据不一致
业务故障
十四、VIP为什么没有漂移
分析Keepalived日志:
journalctl -u keepalived发现:
Script check_pg.sh returned success说明:
脚本始终返回0VIP自然不会漂移。
十五、脚本权限问题
常见错误:
-rw-r--r--没有执行权限。
导致:
Keepalived无法执行脚本修复
chmod +x check_pg.sh十六、SELinux影响
Rocky Linux 9:
getenforce返回:
Enforcing可能拦截脚本执行。
查看:
ausearch -m avc临时关闭:测试。
十七、sudo权限问题
很多脚本包含:
sudo systemctl stop keepalived但:
keepalived用户无sudo权限导致脚本失败。
配置:
visudo加入:
postgres ALL=(ALL) NOPASSWD:ALL十八、WAL配置问题
检查:
show wal_level;应为:
replica检查:
show max_wal_senders;建议:
10检查:
show wal_log_hints;应:
on否则:
十九、复制状态检查
主库:
select * from pg_stat_replication;正常:
state = streaming异常:
0 rows说明:
复制中断二十、备库状态检查
select pg_is_in_recovery();结果:
t表示:
备库Promote后:
f表示:
主库二十一、故障恢复测试
测试流程:
测试一
关闭主库:
systemctl stop postgresql结果:
VIP漂移成功测试二
查看备库:
select pg_is_in_recovery();结果:
false提升成功。
测试三
业务连接VIP:
psql -h 192.168.18.101连接正常。
二十二、最终解决方案
经过排查发现:
根本原因:
1. Keepalived检测脚本误判 2. repmgrd未启动 3. failover配置错误修复:
优化健康检查 启用repmgrd 开启automatic failover 增加VIP检测 增加日志监控最终实现:
主库故障 ↓ 2秒检测 ↓ VIP漂移 ↓ 备库Promote ↓ 业务恢复恢复时间:
小于10秒满足生产要求。
二十三、最佳实践建议
建议一
不要使用:
ps -ef | grep postgres作为唯一检测依据。
建议二
优先使用:
pg_isready和:
select 1组合检测。
建议三
启用:
repmgrd自动切换。
建议四
定期进行故障演练。
建议:
每月一次Failover测试。
建议五
监控以下关键指标:
PostgreSQL状态
VIP归属
Replication Lag
WAL生成速率
Repmgr状态
Keepalived状态
总结
PostgreSQL 高可用建设并非仅部署主从复制即可完成。真正决定系统可靠性的,是故障检测、自动切换、VIP漂移、脑裂防护以及运维监控体系。
本次案例中,虽然集群已经部署完成,但由于健康检查脚本设计不合理、repmgrd未启动以及自动切换配置错误,导致主库故障后系统未能完成故障转移,最终造成业务中断。
通过完善健康检测逻辑、启用自动故障切换、优化Keepalived配置以及建立标准化故障演练机制,最终实现了PostgreSQL高可用集群在主节点故障情况下10秒内自动恢复业务访问的目标。
对于生产环境而言,建议将故障切换测试纳入日常运维流程,持续验证高可用机制的有效性,确保真正发生故障时系统能够自动、可靠、快速地完成切换,保障业务连续运行。
postgrqsql高可用管理平台推荐:CLup6.x产品手册:CLup简介