PostgreSQL v13流复制故障:重启后只读副本卡在recovery模式求助
PostgreSQL v13流复制备库卡在recovery模式的恢复方案
核心问题定位
从备库日志来看,invalid record length at 0/177B5D8: wanted 24, got 0是关键错误——这说明备库尝试读取该位置的WAL记录时,发现数据不完整(大概率是主库重启时WAL未正常刷盘,或备库本地WAL文件损坏)。而started streaming WAL from primary at 0/1000000 on timeline 1显示备库回退到更早的WAL位置启动流复制,和之前达成的一致性位点(0/177B5D8)冲突,最终导致复制停滞。
优雅恢复步骤(优先保留原主备架构)
1. 确认主库状态
- 登录主库,检查服务运行状态:
pg_ctl status -D /path/to/primary_data_dir - 验证对应位点的WAL完整性:
前往主库-- 查询当前主库WAL位点 SELECT pg_current_wal_lsn(); -- 转换目标位点为WAL文件名 SELECT * FROM pg_walfile_name_offset('0/177B5D8');pg_wal目录,确认对应WAL文件(如000000010000000000000017)存在且文件大小正常(通常为16MB左右)。 - 若使用复制槽,检查槽状态:
确保备库对应的复制槽未被删除,且SELECT slot_name, restart_lsn FROM pg_replication_slots;restart_lsn不晚于0/177B5D8。
2. 修复备库WAL异常
- 停止备库服务:
pg_ctl stop -D /path/to/standby_data_dir - 进入备库
pg_wal目录,删除异常位点对应的WAL文件(如000000010000000000000017),若存在后续不完整的WAL文件也一并删除。 - 调整备库
postgresql.conf参数,优化同步效率:recovery_min_apply_delay = 0 wal_receiver_status_interval = 10 - 启动备库服务:
pg_ctl start -D /path/to/standby_data_dir - 查看备库日志,确认是否出现
started streaming WAL from primary at [最新LSN] on timeline 1,且无invalid record length类错误。
3. 验证复制状态
在备库执行以下SQL,确认复制恢复正常:
SELECT pg_is_in_recovery(); -- 应返回true,说明仍处于备库模式 SELECT pg_last_wal_receive_lsn(); -- 接收的最新WAL位点 SELECT pg_last_wal_replay_lsn(); -- 已回放的最新WAL位点
这两个位点应逐步接近主库的pg_current_wal_lsn(),说明复制流已正常运行。
不推荐的操作(仅适用于极端场景)
- 直接删除Standby.signal并重启:这会让备库脱离恢复模式,成为独立主库,但此时备库数据与原主库不一致,后续无法再作为原主库的备库使用,仅适合放弃原主库、将备库转为新主库的场景。
- 直接提升备库为主库:执行
pg_ctl promote -D /path/to/standby_data_dir会让备库结束恢复模式成为主库,但原主库必须立即停止使用(否则会出现双主数据冲突),之后需将原主库重新配置为新主库的备库,或重建整个复制环境。
总结
优先通过修复WAL异常、重新同步主库WAL的方式恢复流复制,这是最优雅且能保留原架构的方案。只有当主库彻底不可用且无法修复时,再考虑提升备库为主库。
内容的提问来源于stack exchange,提问作者Marchetemsncom
相关产品推荐
相关产品推荐

