副本集 Oplog
oplog(操作日志)是特殊的固定大小集合,滚动记录修改数据库中存储的数据的所有操作。如果写入操作未修改任何数据或失败,则不会创建 oplog 条目。
与其他固定大小集合不同,oplog 可超过其已配置的大小限制,从而避免删除。
MongoDB 会对主节点应用数据库操作,并在主节点的 oplog 中记录这些操作。然后,从节点成员会在异步流程中复制并应用这些操作。在 local.oplog.rs
集合中,所有副本集成员均包含此 oplog 的副本,从而可维持数据库的当前状态。
为了便于复制,所有副本集成员都会向所有其他成员发送心跳 (ping)。任何次要成员都可以从任何其他成员导入 oplog 条目。
oplog 中的每个操作都是幂等。也就是说,无论对目标数据集应用一次还是多次,oplog 操作都会产生相同的结果。
Oplog 大小
首次启动副本集节点时,如果未指定 oplog 大小,MongoDB 会创建默认大小的 oplog。
- 适用于 Unix 和 Windows 系统
默认 oplog 大小取决于存储引擎:
引擎加密默认 Oplog 大小5% 的可用磁盘空间
5% 的物理内存
默认的 oplog 大小具有以下限制:
最小 oplog 大小为 990 MB。如果 5% 的可用磁盘空间或物理内存(以存储引擎为准)小于 990 MB,则默认的 oplog 大小为 990 MB。
默认最大的 oplog 大小为 50 GB。如果 5% 的可用磁盘空间或物理内存(根据您的存储引擎而定)大于 50 GB,则默认 oplog 大小为 50 GB。
- 对于 64 位 macOS 系统
可用磁盘空间或物理内存的默认 oplog 大小为 192 MB ,具体取决于存储引擎:
引擎加密默认 Oplog 大小192 MB 可用磁盘空间
192 MB 物理内存
在大多数情况下,默认的 oplog 大小是足够使用的。如果 oplog 占可用磁盘空间的 5%,并在 24 小时的运行中被填满,那么从节点可以长达 24 小时停止从 oplog 复制条目,且不会因过时太久导致无法继续复制。然而,大多数副本集的操作量要低得多,它们的 oplog 可以容纳更多的操作。
在 mongod
创建 oplog 之前,可以使用 oplogSizeMB
选项指定其大小。首次启动副本集成员后,使用 replSetResizeOplog
管理命令更改 oplog 大小。可以使用 replSetResizeOplog
动态调整 oplog 的大小,而无需重启 mongod
进程。
最短 Oplog 保留期
您可以指定保留 oplog 条目的最小小时数,在此期间, mongod
仅在以下两个条件都满足时才会删除 oplog 条目:
oplog 已达到最大配置大小。
oplog 条目早于根据主机系统时钟配置的小时数。
默认情况下,MongoDB 不设置最小 oplog 保留期,并自动从最旧的条目开始截断 oplog,以维持配置的 oplog 最大大小。
要在启动 mongod
时配置 oplog 最短保留期,请执行以下任一操作:
将
storage.oplogMinRetentionHours
设置添加到mongod
配置文件中。-或-
添加
--oplogMinRetentionHours
命令行选项。
要在正在运行的 mongod
上配置最短 oplog 保留期,请使用 replSetResizeOplog
。在 mongod
运行时设置最短 oplog 保留期会覆盖启动时设置的任何值。您必须更新相应配置文件设置或命令行选项的值,才能在服务器重启后继续保持这些更改。
Oplog Window
oplog 条目带有时间戳。oplog window 是 oplog
中最新和最旧时间戳之间的时间差。如果从节点与主节点失去连接,则只有在 oplog window 内恢复连接后,它才能使用复制再次进行同步。
可能需要更大 Oplog 的工作负载
如果您预计您副本集的工作负载将类似于以下模式之一,那么您可能需要创建一个比默认值更大的 oplog。相反,如果您的应用程序主要执行读取操作,并且仅执行少量写入操作,则一个较小的 oplog 可能就已足够。
以下工作负载可能需要更大的 oplog。
同时更新多个文档
为保持幂等性,oplog 必须将多次更新转换为单次操作。这会使用大量的 oplog 空间,而数据大小或磁盘用量并未相应增长。
删除的数据量等于插入的数据量
如果删除的数据量与插入的数据量大致相同,则数据库的磁盘使用量不会显著上升,但 operation log 却可能会变得很大。
大量就地更新
如果工作负载的很大一部分是不会增加文档大小的更新操作,则数据库会记录大量操作,但不会更改磁盘上的数据量。
Oplog Status
要查看 oplog 状态,包括操作的大小和时间范围,请执行 rs.printReplicationInfo()
方法。有关 oplog 状态的更多信息,请参阅检查 Oplog 的大小。
复制延迟和流量控制
在各种特殊情况下,从节点的oplog 更新可能会滞后于所需的性能时间。 使用来自从节点成员的db.getReplicationInfo()
和复制状态输出来评估当前的复制状态并确定是否存在任何意外复制延迟。
从 MongoDB 4.2 开始,管理员可以限制主节点应用写入的速率,目标是将 majority
committed
延迟保持在可配置的最大 flowControlTargetLagSeconds
值以下。
默认情况下,流量控制为 enabled
。
注意
要启用流量控制,副本集/分片集群必须具有: featureCompatibilityVersion (fCV) 为 4.2
,且读关注(read concern)为 majority enabled
。也就是说,如果 fCV 不是 4.2
或读关注已被禁用,则已启用的流量控制将不会生效。
更多信息,请参阅复制延迟。
Oplog 应用缓慢
副本集的从节点会记录应用时间超过慢操作阈值的 oplog 条目。这些消息是针对 REPL
组件下的从节点 logged
的,本为 applied op: <oplog entry> took
<num>ms
。
2018-11-16T12:31:35.886-05:00 I REPL [repl writer worker 13] applied op: command { ... }, took 112ms
在从节点上记录缓慢的 oplog 应用程序是:
不受
logLevel
/systemLog.verbosity
级别(或systemLog.component.replication.verbosity
级别)的影响;也就是说,对于 oplog 条目,从节点只记录慢速操作日志条目。增加详细级别不会记录所有 oplog 条目。不被分析器捕获,并且不受分析级别影响。
有关设置慢操作阈值的更多信息,请参阅
profile
命令或db.setProfilingLevel()
Shell 助手方法。
Oplog 集合行为
如果 MongoDB 部署使用 WiredTiger 存储引擎,则无法从任何副本集成员中 drop
local.oplog.rs
集合。无法从独立 MongoDB 实例中删除 local.oplog.rs
集合。如果某一节点出现故障,mongod
则需借助此 oplog 来复制和恢复该节点。
从 MongoDB 5.0 开始,不再支持在作为副本集运行的集群上对 oplog 执行手动写入操作。作为独立实例运行时对 oplog 执行写入操作只能在 MongoDB 支持团队的指导下完成。