← 返回题目列表

MongoDB 的 oplog 是什么?复制延迟怎么排查?

高频 中等 第 4 / 31 题 更新于 2026/07/29
MongoDBoplog复制集复制延迟

简化版

oplog 是复制集里记录写操作历史的特殊 capped collection,Secondary 通过拉取并重放 Primary 的 oplog 来同步数据。复制延迟通常要看写入压力、网络、磁盘、索引、长事务、Secondary 负载和 oplog 窗口是否足够。

详细版

MongoDB 复制不是简单拷贝数据文件,而是 Primary 记录逻辑写操作到 oplog,Secondary 按顺序应用这些操作。oplog 是固定大小的循环集合,写入太快而 Secondary 追不上时,旧 oplog 可能被覆盖,节点就需要重新同步。

排查复制延迟时可以看 rs.printSecondaryReplicationInfo()、复制状态、网络 RTT、磁盘 I/O、慢操作、索引构建、长事务和读流量是否压在 Secondary 上。回答时要强调:oplog 是复制基础,复制延迟不是单一原因,要从写入速度、应用速度和 oplog 保留窗口一起分析。

完整版教学

一、oplog 是复制集同步的操作日志

MongoDB 复制集里,Primary 负责接收写入,并把写操作记录到 oplog。Secondary 持续读取 Primary 或其他同步源的 oplog,然后在本地重放这些操作。

它记录的是逻辑操作,而不是完整数据文件拷贝。这样复制可以持续增量进行,也便于 Secondary 从某个时间点继续追。

client write
   |
   v
Primary data change
   |
   v
local.oplog.rs
   |
   v
Secondary pull and apply

记忆钩子:复制集的数据同步靠 oplog 接力,Primary 写一笔,Secondary 追一笔。

二、oplog 为什么是 capped collection

oplog 是一个特殊的 capped collection,也就是固定大小、按插入顺序循环覆盖的集合。它不会无限增长。

这个设计有好处:空间可控,顺序写入和顺序读取效率高。但它也带来一个关键指标:oplog window,也就是从最老一条 oplog 到最新一条 oplog 覆盖的时间范围。

写入速度oplog 大小oplog window风险
可能数天节点短暂停机可追上
可能几小时Secondary 容易追丢
突增不变快速缩短批量导入时要特别关注

如果 Secondary 落后时间超过 oplog window,旧操作已经被覆盖,它就不能靠增量复制追上,通常需要重新同步。

三、复制延迟的本质是生产速度大于消费速度

复制延迟可以理解为 Primary 生成 oplog 的速度,超过了 Secondary 拉取和应用 oplog 的速度。

常见原因包括:

  1. Primary 写入太猛,比如批量导入、热点更新。
  2. Secondary 磁盘慢,应用 oplog 跟不上。
  3. 网络抖动,拉取 oplog 不稳定。
  4. Secondary 同时承担读请求、备份或分析任务。
  5. 索引过多,每次写入在 Secondary 上也要维护索引。
  6. 长事务或大事务让提交和复制压力集中。

面试里不要只说“加机器”,要能讲清楚延迟来自哪里。

四、复制延迟会影响读一致性和故障恢复

如果业务把读请求路由到 Secondary,复制延迟会导致读到旧数据。比如用户刚改昵称,下一次请求读 Secondary,可能仍然看到旧昵称。

T0 Primary: name = "Alice"
T1 update name = "Alicia"
T2 Secondary still lag 5s
T3 read from Secondary -> "Alice"

延迟还会影响故障恢复。如果 Primary 宕机,某个落后的 Secondary 被选为新 Primary,就可能丢失尚未复制到多数节点的写入。实际风险与 write concern、选举、节点状态有关。

所以复制延迟不是监控好看不好看的问题,而是直接关系到读新鲜度和高可用质量。

五、排查复制延迟要看 3 类指标

可以把排查分成 3 层。

层次关注指标典型动作
生产端写 QPS、oplog 增长速度、慢写降低批量写峰值,减少无效索引
传输端网络 RTT、丢包、同步源检查跨机房链路,调整同步源
消费端Secondary I/O、CPU、锁、慢操作减少读压,升级磁盘,拆分任务

常用命令包括:

rs.status()
rs.printSecondaryReplicationInfo()
db.getSiblingDB("local").oplog.rs.find().sort({ $natural: -1 }).limit(1)

命令只是入口,关键是把结果和业务写入模式联系起来。

六、oplog 窗口不足怎么处理

如果 oplog window 太短,可以考虑增大 oplog 大小。但只增大 oplog 不是根治,它只是让 Secondary 有更长时间追赶。

还需要处理根因:

写入突增 -> 削峰批处理
索引过多 -> 删除无用索引
Secondary 负载高 -> 读写隔离或独立分析库
磁盘瓶颈 -> 提升 IOPS
跨地域复制 -> 接受延迟或调整架构

对生产环境,尤其是大批量导入、重建索引、迁移数据前,要提前评估 oplog window,避免操作进行一半发现从库追丢。

七、常见误区与追问

  • 误区:oplog 是普通业务日志。 oplog 是复制机制使用的操作历史,位于 local 库,不是给业务审计随便消费的日志。
  • 误区:Secondary 落后一点无所谓。 如果读走 Secondary,会影响读新鲜度;如果窗口不够,还可能导致重新同步。
  • 误区:复制延迟只和网络有关。 写入压力、磁盘 I/O、索引维护、长事务和 Secondary 读负载都可能导致延迟。
  • 追问:oplog window 是什么? 是 oplog 当前能覆盖的时间跨度,决定落后节点还能靠增量复制追多久。
  • 追问:为什么 oplog 是 capped collection? 固定空间、顺序写读效率高,但旧记录会被循环覆盖。
  • 追问:怎么降低复制延迟? 先定位生产、传输、消费哪一层慢,再针对写峰值、网络、磁盘和从库负载处理。

八、加强记忆

MongoDB oplog 题可以记成“写入产生、从库追赶、窗口兜底”。Primary 把逻辑写入放进 oplog,Secondary 拉取并重放;oplog 是固定大小的 capped collection,所以有窗口概念;复制延迟本质是生成速度大于应用速度。排查时沿着 Primary 写入、网络传输、Secondary 应用三段看,别把问题简单归因成网络慢。