复制延迟/停止
备库/副本落后于主库,或复制完全停止。此决策树逐步缩小延迟的类型(增长、恒定或停止),以找到根本原因,如应用错误、单线程瓶颈、恢复冲突或损坏。
延迟表现如何?
先评估现状。查看副本流和延迟指标:延迟是随时间增长、停在恒定水平,还是应用已完全停止?据此将排查分为三个主要分支。
SELECT client_addr, state, write_lag, flush_lag, replay_lag,
pg_wal_lsn_diff(sent_lsn, replay_lsn) AS bytes_behind
FROM pg_stat_replication;- 应用已完全停止/存在错误
- 延迟持续增长(追不上)
- 延迟恒定,但怀疑有长查询
- 落后很多/看起来不一致
应用错误说的是什么?
若复制已停止,通常是正在应用的某个事件出错。查看错误消息:是目标上缺少行/表、主键冲突,还是连接/网络中断?
SHOW REPLICA STATUS\G -- Last_Error, Last_SQL_Error, Replica_IO_Running, Replica_SQL_Running- 行或表冲突/缺失错误
- 网络/连接中断,IO 线程已停止
为什么追不上?
若延迟持续增长,说明副本跟不上主库的写入速率。瓶颈是单线程应用,还是副本的磁盘/IO 慢?查看应用工作线程状态和 IO 等待。
SHOW REPLICA STATUS\G -- Seconds_Behind_Source and apply thread state
SELECT * FROM performance_schema.replication_applier_status_by_worker;- 单线程应用 + 繁重的写入负载
- 副本的磁盘/IO 慢
备库上是否有长查询?
在只读备库上运行的长查询可能阻塞应用(恢复)。在 PostgreSQL 中,恢复冲突就是这样产生的。查看备库上的活动查询和冲突计数器。
SELECT now()-query_start AS dur, pid, state, query
FROM pg_stat_activity WHERE state='active' ORDER BY query_start;
SELECT confl_snapshot, confl_lock, confl_bufferpin FROM pg_stat_database_conflicts WHERE datname=current_database();- 是的,有长查询阻塞了应用
- 没有查询,但仍然落后
根本原因:应用错误(数据冲突)
副本卡在一个无法应用的事件上:目标上缺少行、主键冲突或缺少表。修复不一致的原因,而不是盲目跳过。
根本原因:连接/网络中断
接收(IO/receiver)线程无法连接主库。问题可能在于网络、认证,或已累积/被清除的日志段。
根本原因:单线程应用瓶颈
主库并行写入,而副本按单一顺序应用变更,跟不上。将应用并行化。
根本原因:副本 IO 瓶颈
应用线程在等待磁盘而不是 CPU。副本的存储跟不上主库的写入速率。
根本原因:备库恢复冲突
备库上长时间运行的只读查询阻塞了来自主库的变更应用(vacuum/锁冲突)。PostgreSQL 通过延迟应用或取消查询来解决。
根本原因:副本落后太多/已损坏——重建
副本落后太多无法恢复、所需日志已被删除,或数据不一致。最安全的做法是从新的备份重建。