Switchover前必须验证:①pg_is_in_recovery()主库为false、备库为true;②备库pg_last_wal_receive_lsn()=pg_last_wal_replay_lsn();③pg_stat_replication.sync_state至少一个为sync或quorum。
主库 Switchover 前必须验证的 3 个状态
switchover 成败不取决于命令多漂亮,而在于主备角色是否真正对齐。常见失败是 pg_stat_replication 显示 state = streaming,但实际 wal 位点已滞后数秒——这会导致 switchover 后新主库丢数据。
- 检查
pg_is_in_recovery():原主库必须返回false,原备库必须返回true - 确认
pg_last_wal_receive_lsn()和pg_last_wal_replay_lsn()在备库上相等(即无 replay lag) - 查
pg_stat_replication.sync_state:至少一个备库为sync或quorum,否则promote后可能脑裂
Switchover 过程中不能跳过的 2 步操作
很多人直接在旧主库执行 pg_switch_wal() 就切流,结果新主库缺最后几个 WAL 段,应用连不上。真正的平滑切换依赖两个不可省略的动作:
- 在旧主库执行
SELECT pg_switch_wal();后,立刻查pg_current_wal_lsn()记下 LSN - 在备库执行
SELECT pg_last_wal_replay_lsn() >= '刚才记下的 LSN';返回true才能pg_promote()
漏掉第二步,等于没等 WAL 完全重放完就切主,PostgreSQL 不会报错,但后续 INSERT 可能触发 ERROR: could not access status of transaction。
Switchover 后备库重建的替代方案
硬件替换场景下,原备库往往要下线换机器,但重建新备库耗时长、IO 压力大。其实只要旧备库还在线且 WAL 归档可用,就能绕过 pg_basebackup:
- 停掉旧备库进程,保留其
data目录和归档路径中的所有.wal文件 - 用新机器初始化空集群:
initdb -D /new/data,然后配置recovery.conf(或standby.signal+postgresql.conf中的primary_conninfo) - 把旧备库的
pg_wal中未归档的 WAL(如有)和归档目录里最新的一批复制过去,再启动新备库
这个方法本质是“续接”而非重建,恢复时间从小时级降到分钟级,前提是旧备库的 WAL 未被清理、归档完整。
Switchover 后连接池与应用层的隐性风险
数据库角色切换了,但应用不知道。很多连接池(如 HikariCP、pgBouncer)缓存着旧主库地址,pg_promote 后仍往旧 IP 发请求,结果是连接拒绝或超时,而不是明确的错误。
- Switchover 前必须通知负载均衡器或 DNS 切换 VIP 或 SRV 记录,不能只改数据库配置
- 如果用
pgBouncer,需确保server_reset_query包含DISCARD ALL,否则会复用旧事务状态 - 检查应用日志里是否有
FATAL: the database system is shutting down—— 这说明部分连接还在发请求给正在关闭的旧主库
硬件平滑替换最难控的从来不是数据库命令,而是那几十毫秒里连接路由没跟上、WAL 还差一帧没重放、或者某个微服务读了缓存里的旧连接串。这些点不写进 checklist,就一定会出在凌晨三点。










