MongoDB 4.4+ 支持在线扩容 oplog,需满足版本≥4.4、fcv设为"4.4"、在Primary执行replSetResizeOplog命令;4.2及更早版本只能滚动重建,否则触发initial sync或同步中断;判断oplog不足须在Secondary验证ts可读性,而非仅依赖timeDiffHours。

直接扩容是可行的,但必须先确认版本和状态——MongoDB 4.4+ 支持在线执行 replSetResizeOplog,4.2 及更早版本无法热扩,强行操作只会触发 initial sync 或同步中断。
怎么判断 oplog 窗口真不够了
别只看 db.getReplicationInfo() 返回的 timeDiffHours。这个值是主节点按当前写入速率反推的估算窗口,不反映从节点实际能拉到哪儿。
- 在 Secondary 上执行:
db.oplog.rs.findOne({ts: {$lt: ObjectId("...")}}),其中ObjectId来自主节点rs.status().members[0].optime.ts;返回null就说明该时间点前的 oplog 已被覆盖 - Secondary 日志反复出现
OplogStartMissing或Need to reclone collection due to oplog gap -
rs.printSlaveReplicationInfo()显示 lag 持续增长,且timeDiffHours (比如 lag 最高到 3600 秒,oplog 窗口只剩 0.8 小时)
4.4+ 版本在线扩容实操要点
前提是所有节点已升级到 4.4+,且 featureCompatibilityVersion 已设为 "4.4"(用 db.adminCommand({setFeatureCompatibilityVersion: "4.4"}) 确认)。
- 只在 Primary 上执行:
db.adminCommand({replSetResizeOplog: 1, size: Double(10240)})(单位 MB,例如扩到 10GB) - 不能对处于
STARTUP2、RECOVERING或正在 initial sync 的节点执行该命令 - 执行后立刻验证:
db.getReplicationInfo().maxSizeMB是否更新;再用上面的findOne方法在 Secondary 上确认旧ts是否可读 - 后台会新建 capped 集合 → 复制旧内容 → 切换指针 → 删除旧集合;读写不受影响,仅写入有毫秒级短暂阻塞
4.2 及更早版本只能滚动重建
没有“在线扩容”这回事。所谓清空 local.oplog.rs 或用 captrunc,会破坏 capped 属性,节点可能无法启动。
- 逐个下线 Secondary:停
mongod→ 删除其data/db/local.oplog.rs.wt文件(不是删集合!)→ 启动时加参数--oplogSize 10240→ 触发 initial sync - Primary 必须最后处理,且确保重建期间至少一个 Secondary 在线提供写服务,否则写能力丢失
- 滚动过程中,oplog 窗口实际为零(新节点从头同步),业务需容忍临时延迟或降级
最容易被忽略的是:扩容后同步仍慢,问题往往不在 oplog 大小,而在 applyOps 回放瓶颈——比如从节点磁盘 I/O 不足、CPU 被挤占、或存在大量大文档更新。先查 db.currentOp({secs_running: {$gt: 5}}) 看长耗时操作,再决定是否调大 oplog。


















