同步延迟超过30秒应先执行rs.printslavereplicationinfo()获取真实延迟值,若显示285秒等高延迟,则需排查网络(用iperf3测带宽与丢包)、磁盘i/o(iostat看%util和await)及长查询阻塞(db.currentop查secs_running>10的query)。

同步延迟超过30秒?先看 rs.printSlaveReplicationInfo() 输出
这个命令直接告诉你每个 Secondary 落后主节点多少秒,不是估算,是真实延迟值。如果输出里显示 285 secs 或更高,说明已严重滞后,不能只盯着日志或监控图表——那些可能缓存或聚合过。
常见错误现象:
- 从节点状态长期卡在
STARTUP2或RECOVERING,实际是 oplog 拉取失败但没报错 -
db.currentOp({secs_running: {$gt: 60}})在从节点查出大量applyOps操作,说明重放线程被阻塞
此时别急着调 oplogSize,先确认瓶颈在哪:网络 or 磁盘。
用 iperf3 测副本集成员间真实带宽,别信云厂商控制台数字
云服务器标称“1Gbps 内网”,实际跨可用区或不同安全组时可能只有 40MB/s 甚至更低。MongoDB 同步依赖持续稳定的 TCP 流量,丢包或抖动会触发重传,放大延迟。
实操建议:
- 在
Primary和最慢的Secondary上同时运行:iperf3 -c <peer-ip> -t 30 -P 4</peer-ip>(4线程测) - 重点看
[SUM]行的sender和receiver带宽是否接近、抖动是否 - 如果接收端吞吐只有发送端的 60% 以下,且
retransmits> 0,基本锁定网络问题
注意:不要用 ping 判断——ICMP 包小、优先级高,不代表 MongoDB 的大 oplog batch 包能跑通。
iostat -x 1 看从节点磁盘饱和度,%util > 90% 是硬信号
WiredTiger 引擎在重放 oplog 时,既要写 journal,又要更新数据文件和索引,I/O 压力远高于普通读写。尤其当 cacheSizeGB 设置过小,或热数据远超内存时,每条 oplog 都可能触发多次随机读+顺序写。
关键指标判断:
-
await> 20ms:单次 I/O 响应已严重拖慢 -
r/s+w/s接近磁盘理论 IOPS(如 SATA SSD 约 8K~10K),说明设备已达上限 -
%util长期 95%+,且avgqu-sz> 2:请求排队,复制线程必然卡住
此时加内存比换 CPU 更有效——把 storage.wiredTiger.engineConfig.cacheSizeGB 设为物理内存的 60%,再观察 iostat 是否回落。
从节点执行长查询会直接堵死复制线程,这不是配置问题而是设计限制
MongoDB 3.6+ 的 WiredTiger 引擎中,复制线程(repl writer)和用户查询共用同一个 storage engine session。一旦某个查询持有 page latch 超过几秒(比如全表扫描未建索引的集合),oplog 重放就会等锁,延迟开始累积。
验证方式:
- 在从节点运行:
db.currentOp({secs_running: {$gt: 5}, "secs_running": {$exists: true}}) - 检查返回结果里是否有
secs_running> 10 且ns不是local.oplog.rs的操作 - 特别留意
type: "query"或type: "getMore"的长任务
解决办法不是加索引就完事——从节点默认允许读,但生产环境应设 readPreference=primary,或至少禁止在从节点跑分析类查询。这点容易被忽略,因为错误不报异常,只默默拖慢同步。











