mongodb的oplog是固定大小的capped collection,会静默覆盖最老条目而非报错;若secondary宕机超oplog保留时长,需代价高昂的全量同步;wiredtiger引擎下,默认oplogsize为50gb(磁盘≥50gb时)。

Oplog 大小不是无限的,它有硬性上限且会主动覆盖
不能。MongoDB 的 oplog 是固定大小的 capped collection,即使磁盘还有大量空间,它也不会无限制增长。一旦达到配置上限(或默认值),新写入的操作就会从最老的条目开始覆盖——不是“满了报错”,而是静默覆盖。这意味着:如果 secondary 节点宕机时间超过 oplog 能保留的最小时长,它就无法通过常规复制追上主节点,只能重新全量同步(initial sync),代价极高。
默认 oplogSize 到底多大?别信“5%”这个模糊说法
默认值取决于多个条件,且不同版本/存储引擎行为不一致,容易误判:
- 对于
wiredTiger引擎(绝大多数生产环境):若可用磁盘空间 ≥ 50 GB,oplogSize默认为50GB;若 5%,但下限是990MB - 注意:“可用磁盘空间”指
mongod数据目录所在分区的剩余空间,不是整个机器磁盘 - 内存引擎(
inMemory)默认用192MB物理内存,但极少用于副本集生产场景 - 你看到的“5%”只是常见估算值,实际必须查:
db.getReplicationInfo()中的maxSize字段才是真实值
怎么安全地调大 oplogSize?别重启,也别直接改配置文件
从 MongoDB 4.0+ 开始,推荐用 replSetResizeOplog 命令在线调整,无需重启、不影响复制:
- 连接到 primary 节点后执行:
db.adminCommand({replSetResizeOplog: 1, size: 10240})—— 单位是 MB,这里设为 10 GB - 该命令会触发一次 oplog 截断 + 重建,耗时取决于当前 oplog 大小和 I/O 负载,期间复制延迟可能短暂升高
- 务必提前确认磁盘余量:新
oplogSize至少应 ≥ 当前写入速率 × 期望保留小时数(例如:每秒写入 2MB,想保留 24 小时 → 至少需 172 GB) - 切勿在 secondary 上执行此命令;只对 primary 有效,且会自动同步给其他成员
为什么调大了还是很快被覆盖?排查这三点
调完发现 db.getReplicationInfo().timeDiff(oplog 可回溯小时数)依然只有几小时?常见原因:
-
oplog所在磁盘分区空间不足:即使总磁盘够,若dbpath分区只剩 20GB,而你设了 30GB oplog,MongoDB 会静默降级回默认值(比如 990MB),且不报错 - 写入突增未被监控:批量导入、索引重建、大文档更新等操作会瞬间放大 oplog 写入量,日常平均速率参考价值低
- 副本集内节点 oplog 大小不一致:某些节点曾手动修改过,或初始化时磁盘空间不同导致默认值不同;用
rs.printSecondaryReplicationInfo()对比各节点oplogSize和optimeDate
真正关键的是:oplog 不是日志归档,它是复制的“滑动窗口”。窗口太窄,故障恢复就不可靠——这个窄,往往不是因为没调大,而是没看懂它和磁盘、写入模式、节点状态之间的咬合关系。










