oplog同步中断的直接证据是secondary日志中反复出现oplogstartmissing或need to reclone,表明oplog起点ts不可达;需用db.oplog.rs.findone验证ts是否在窗口内,若返回null则确认中断;同时lag超过timediffhours×3600即注定掉出窗口,且local磁盘空间不足也会间接导致同步失败。

从Secondary日志里找OplogStartMissing或Need to reclone
这是最直接的证据。Secondary节点一旦拉不到起点ts,就会在日志中反复打印OplogStartMissing或Need to reclone collection due to oplog gap。这类错误不是偶发警告,而是同步已断裂的明确信号。
别等它自动恢复——MongoDB不会“重试”丢失的oplog,只会卡住或退回到initial sync。
- 检查路径通常是
/var/log/mongodb/mongod.log或你配置的systemLog.path - 用
grep -i "oplogstartmissing\|reclone" /var/log/mongodb/mongod.log快速定位 - 注意时间戳:如果该错误出现在某次主节点大写入(如批量导入、索引重建)之后,基本可锁定oplog覆盖
在Secondary上执行findOne验证ts是否可达
db.getReplicationInfo()返回的timeDiffHours只是主节点视角的估算,不能代表从节点实际能读到什么。真正要测的是:从节点还能不能定位到主节点当前optime.ts往前推的那个时间点。
操作步骤:
- 先在Primary上查:
rs.status().members[0].optime.ts(假设index 0是primary),拿到类似ObjectId("65a1b2c3d4e5f67890123456")的值 - 再到Secondary上执行:
db.oplog.rs.findOne({ts: {$lt: ObjectId("65a1b2c3d4e5f67890123456")}}) - 如果返回
null,说明oplog窗口已经收缩到连这个ts都覆盖不到了——同步中断根源在此
对比rs.printSlaveReplicationInfo()里的lag和timeDiffHours
当Secondary的延迟(lag)持续增长,且最大lag值(单位秒)已超过db.getReplicationInfo().timeDiffHours * 3600时,就是典型的“追赶速度 > oplog保留窗口”的失衡状态。
例如:
-
rs.printSlaveReplicationInfo()显示某Secondary lag最高达3800秒(约1.06小时) - 但
db.getReplicationInfo().timeDiffHours只有0.92小时(约3312秒) - 这意味着哪怕它全力追赶,也注定会掉出oplog窗口——不是慢,而是必断
这种差值不是误差,是倒计时。
别只盯着Primary的oplog大小,Secondary的local数据库空间也要看
oplog本身是local.oplog.rs这个capped集合,但它不是孤立存在的。Secondary在同步过程中会把拉取到的oplog暂存、回放、构建索引,这些中间数据都落在local库下(比如local.temp_initiate_sync类临时集合)。
- 如果
local所在磁盘分区使用率 > 90%,即使oplog size够大,也可能因空间不足导致applyOps卡住,间接表现为同步延迟飙升 - 执行
db.getSiblingDB("local").getCollectionNames()看看有没有异常大体积的临时集合残留 -
df -h确认local数据目录挂载点的真实可用空间
oplog过小常是表象,底层磁盘空间吃紧才是那个没被看见的推手。











