DBAtlas · 数据库运维图谱

复制延迟/停止

备库/副本落后于主库,或复制完全停止。此决策树逐步缩小延迟的类型(增长、恒定或停止),以找到根本原因,如应用错误、单线程瓶颈、恢复冲突或损坏。

延迟表现如何?

先评估现状。查看副本流和延迟指标:延迟是随时间增长、停在恒定水平,还是应用已完全停止?据此将排查分为三个主要分支。

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 通过延迟应用或取消查询来解决。

根本原因:副本落后太多/已损坏——重建

副本落后太多无法恢复、所需日志已被删除,或数据不一致。最安全的做法是从新的备份重建。

在 DBAtlas 中打开 →