错误“requested wal segment has already been removed”明确表明备库请求的wal段已被主库清理,根本原因是备库同步滞后超出主库wal保留能力,需通过日志确认、lsn差值计算和复制槽状态排查定位。

查备库日志确认是否真因WAL被删而掉线
错误信息 requested WAL segment ... has already been removed 是最直接的信号,但它只出现在备库日志里。别急着调参数,先定位是不是这个原因:
- 在备库执行
grep -A 5 "has already been removed" /var/lib/postgresql/*/log/postgresql-*.log(路径按实际调整) - 如果没匹配到,但看到
could not receive data或connection lost,那可能是网络或进程崩溃,不是WAL覆盖问题 - 注意时间戳——若错误发生在备库重启后几秒内,基本可锁定是WAL断档;若发生在持续运行中,则更可能是复制槽卡住或归档延迟
看主库当前WAL位置和备库最后接收点
光看错误不够,得算出“断在哪一段”。关键不是比大小,而是比LSN差值是否超过主库保留能力:
- 在主库查当前WAL位置:
SELECT pg_current_wal_lsn(); - 在备库查它最后一次成功应用的位置:
SELECT pg_last_xact_replay_location();(注意不是pg_last_wal_receive_lsn(),后者只代表收到,不代表已重放) - 用
pg_wal_lsn_diff()算差值:SELECT pg_wal_lsn_diff('0/12345678', '0/87654321');,结果单位是字节;若超 1GB,且wal_keep_segments默认值(通常 128)对应容量约 16GB,那大概率已覆盖
检查复制槽是否活着、是否拖后腿
复制槽(replication slot)是双刃剑:开了能防WAL被删,但一旦卡住,反而会让WAL无限堆积。必须立刻验明正身:
- 主库执行:
SELECT slot_name, active, restart_lsn, confirmed_flush_lsn FROM pg_replication_slots; -
active = false且restart_lsn长期不动 → 僵尸槽,WAL不会清理,但也不会帮备库恢复 -
active = true但restart_lsn落后主库当前LSN超 10GB → 备库同步严重滞后,可能已卡死在某个大事务上 - 特别注意:
confirmed_flush_lsn比restart_lsn还落后?说明备库连确认都发不出,基本是网络层或walreceiver进程挂了
临时绕过WAL断档的实操路径
确认是WAL覆盖后,重建备库不是唯一选项。三种应急方式按风险从低到高排列:
- 若备库只是短暂断连(restore_command 在
recovery.conf(或postgresql.auto.conf中的primary_slot_name)配置正确,备库重启时会自动从归档拉缺失段 - 若归档不可用但主库磁盘还有旧WAL残留(比如
pg_wal/archive_status里还有.done文件):手动把对应WAL文件拷进备库pg_wal/目录,再重启 - 最激进但最稳:用
pg_basebackup -R重拉全量,同时指定--slot=xxx创建新复制槽,避免下次再掉——这步会中断备库服务,但比等WAL追平快得多
真正容易被忽略的是:WAL断档常伴随时间线(timeline)切换。如果主库发生过failover,备库必须用新时间线的WAL,否则即使LSN对得上也会报错。查主库 pg_control 或 pg_controldata 输出里的 Latest checkpoint's TimeLineID,再核对备库 recovery.signal 里是否指定了正确时间线。










