从节点卡在RECOVERING且apply.queued持续不降,说明oplog已拉取但回放堵塞,主因是Secondary本地applyOps线程被慢查询或建索引抢占资源,需检查oplog窗口、同步源路径及并发配置。

从节点卡在RECOVERING且apply.queued持续不降
这说明oplog拉到了,但回放不过来——不是网络慢,是Secondary本地applyOps线程被拖住。常见诱因就是慢查询抢占资源,尤其是那些没走索引、全表扫描或大数组遍历的查询。
- 执行
db.serverStatus().metrics.repl.apply.queued,若值长期 > 0(比如稳定在50+),基本可锁定apply阶段堵塞 - 检查
db.currentOp({secs_running: {$gt: 5}}),看是否有长时间运行的读操作正在消耗CPU或锁住WiredTiger cache - Secondary默认允许大量并发读,
maxConcurrentOps默认是512;压到64–128能显著释放applyOps线程调度权 - 临时禁用非必要后台任务:
db.runCommand({setParameter: 1, diagnosticDataCollectionEnabled: false}),避免diagnostic.data采集干扰
Performance Advisor里出现“建议索引”但Secondary仍落后
Performance Advisor识别出慢查询并推荐索引,但Secondary不会自动建索引——它只被动回放Primary上已执行的操作。如果Primary刚建了一个耗时很长的索引(比如对10亿文档集合建复合索引),Secondary就得同步重建,期间apply.queued会飙升,optimeDate停滞不前。
- 查Primary最近是否执行了
createIndex:在Primary上运行db.currentOp({secs_running: {$gt: 30}, "command.createIndexes": {$exists: true}}) - Secondary上
db.serverStatus().metrics.repl.apply.totalTimeMs若远高于fetchTotalMillis,说明apply耗时异常,大概率在建索引或处理大文档更新 - 下次在Primary建大索引,务必加
{background: true},否则Secondary会被卡死数小时 - 注意:
background: true只是不阻塞Primary写入,但apply阶段仍需完整执行,只是不抢锁——延迟依然存在,只是不中断服务
日志里反复出现"could not find base oplog entry"
这不是同步慢,是同步断了。根本原因是oplog被覆盖——Secondary还没来得及拉取某条oplog,它就被新写入挤掉了。此时Performance Advisor看到的“慢查询”其实是结果,不是原因;真正要查的是oplog窗口是否够用。
- 在PRIMARY上运行
db.getReplicationInfo(),重点关注timeDiffHours字段:生产环境必须 ≥ 24,写入密集场景建议48–72 - 若该值只有2–3小时,而业务写入峰值持续5小时以上,Secondary必然追不上,反复触发initial sync
- 4.4+版本可在线扩容oplog:
db.adminCommand({replSetResizeOplog: 1, size: 10240})(单位MB,必须整数) - 扩容后立刻验证:
db.getReplicationInfo().maxSizeMB和timeDiffHours是否更新;若没变,说明命令未生效或节点未重载配置
syncSourceHost指向另一个SECONDARY而非PRIMARY
链式复制(chained replication)会让慢查询的影响放大。比如PRIMARY → node2 → node3,node2上一个慢查询导致apply延迟5分钟,node3就会比PRIMARY落后至少5分钟,且无法绕过node2直连PRIMARY。
- 运行
rs.status(),找目标SECONDARY的syncingTo字段;若值为"node2:27017"而非"primary:27017",即启用链式复制 - 禁用需修改配置:
conf = rs.conf(); conf.settings.chainingAllowed = false; rs.reconfig(conf) - 注意:
rs.reconfig()必须在PRIMARY上执行,且version要自增;所有节点版本必须 ≥ 4.0 - 禁用后,所有SECONDARY将直连PRIMARY,主节点网络/IO压力会上升,需提前评估
排查到这里,多数“从节点落后”问题其实跟查询本身关系不大,而是oplog窗口、同步源路径、apply资源争抢这三个点没控住。最容易被忽略的是:把timeDiffHours当成次要指标,直到它掉到2小时以下才意识到问题——而这时节点早已开始反复重同步了。











