MongoDB journal与oplog解惑

本文详细介绍了MongoDB中Journal与Oplog的作用与工作原理。Journal作为存储引擎层的概念,确保了数据写入的持久性和一致性。Oplog则是在主从复制层面上的概念,通过记录操作日志实现数据同步,确保复制集中各节点数据的一致性。

journal

journal 是 MongoDB 存储引擎层的概念,目前 MongoDB主要支持 mmapv1、wiredtiger、mongorocks 等存储引擎,都支持配置journal。

MongoDB 所有的数据写入、读取最终都是调存储引擎层的接口来存储、读取数据,journal 是存储引擎存储数据时的一种辅助机制。

以wiredtiger 为例,如果不配置 journal,写入 wiredtiger 的数据,并不会立即持久化存储;而是每分钟会做一次全量的checkpoint(storage.syncPeriodSecs配置项,默认为1分钟),将所有的数据持久化。如果中间出现宕机,那么数据只能恢复到最近的一次checkpoint,这样最多可能丢掉1分钟的数据。

所以建议「一定要开启journal」,开启 journal 后,每次写入会记录一条操作日志(通过journal可以重新构造出写入的数据)。这样即使出现宕机,启动时 Wiredtiger 会先将数据恢复到最近的一次checkpoint的点,然后重放后续的 journal 操作日志来恢复数据。

MongoDB 里的 journal 行为 主要由2个参数控制,storage.journal.enabled 决定是否开启journal,storage.journal.commitInternalMs 决定 journal 刷盘的间隔,默认为100ms,用户也可以通过写入时指定 writeConcern 为 {j: ture} 来每次写入时都确保 journal 刷盘。

oplog

oplog 是 MongoDB 主从复制层面的一个概念,通过 oplog 来实现复制集节点间数据同步,客户端将数据写入到 Primary,Primary 写入数据后会记录一条 oplog,Secondary 从 Primary(或其他 Secondary )拉取 oplog 并重放,来确保复制集里每个节点存储相同的数据。

oplog 在 MongoDB 里是一个普通的 capped collection,对于存储引擎来说,oplog只是一部分普通的数据而已。

MongoDB 的一次写入

MongoDB 复制集里写入一个文档时,需要修改如下数据

  1. 将文档数据写入对应的集合
  2. 更新集合的所有索引信息
  3. 写入一条oplog用于同步

上面3个修改操作,需要确保要么都成功,要么都失败,不能出现部分成功的情况,否则

  1. 如果数据写入成功,但索引写入失败,那么会出现某个数据,通过全表扫描能读取到,但通过索引就无法读取
  2. 如果数据、索引都写入成功,但 oplog 写入不成功,那么写入操作就不能正常的同步到备节点,出现主备数据不一致的情况

MongoDB 在写入数据时,会将上述3个操作放到一个 wiredtiger 的事务里,确保「原子性」。

beginTransaction();
writeDataToColleciton();
writeCollectionIndex();
writeOplog();
commitTransaction();

这里写图片描述
wiredtiger 提交事务时,会将所有修改操作应用,并将上述3个操作写入到一条 journal 操作日志里;后台会周期性的checkpoint,将修改持久化,并移除无用的journal。

从数据布局看,oplog 与 journal 的关系

这里写图片描述

谁先写入??

  1. oplog 与 journal 是 MongoDB 里不同层次的概念,放在一起比先后本身是不合理的。
  2. oplog 在 MongoDB 里是一个普通的集合,所以 oplog 的写入与普通集合的写入并无区别。
  3. 一次写入,会对应数据、索引,oplog的修改,而这3个修改,会对应一条journal操作日志。

转自:http://www.mongoing.com/archives/3988

### 启用 MongoDBoplog 功能 在 MongoDB 中,oplog 是副本集(Replica Set)的核心机制之一,用于实现主从节点之间的数据同步。oplog 默认在副本集配置中启用,但需要确保 MongoDB 实例是以副本集模式运行的。以下内容详细说明如何启用 oplog。 #### 1. 配置副本集 MongoDBoplog 功能副本集密切相关。为了启用 oplog,必须将 MongoDB 配置为副本集模式。可以通过以下步骤完成: - 编辑 MongoDB 的配置文件(通常是 `mongod.conf`),添加或修改副本集名称: ```yaml replication: replSetName: "rs0" ``` - 确保存储引擎支持 oplog。从 MongoDB 3.2 开始,默认存储引擎WiredTiger,该引擎支持 oplog[^3]。 #### 2. 启动 MongoDB 实例 以副本集模式启动 MongoDB 实例时,需要指定配置文件或直接通过命令行参数设置副本集名称: ```bash mongod --replSet rs0 --config /etc/mongod.conf ``` #### 3. 初始化副本集 连接到 MongoDB 实例并初始化副本集: ```javascript rs.initiate({ _id: "rs0", members: [ { _id: 0, host: "localhost:27017" } ] }) ``` 初始化后,MongoDB 会在 `local.oplog.rs` 集合中自动创建 oplog,并开始记录操作日志[^4]。 #### 4. 配置 oplog 大小 oplog 的大小可以根据需求进行调整。默认情况下,oplog 的大小会根据系统资源自动分配,通常为磁盘可用空间的5%[^5]。如果需要手动设置 oplog 大小,可以在初始化副本集之前删除现有的 oplog 并重新配置: ```bash # 停止 MongoDB 实例 mongod --dbpath /data/db --shutdown # 删除现有的 oplog rm -rf /data/db/local.* # 启动 MongoDB 并指定 oplog 大小(例如 5GB) mongod --replSet rs0 --oplogSize 5000 --dbpath /data/db ``` #### 5. 验证 oplog 状态 可以通过以下命令检查 oplog 的状态和大小: ```javascript use local db.oplog.rs.stats().maxSize ``` 上述命令返回的值表示 oplog 的最大容量(以字节为单位)[^5]。 --- ### 注意事项 - oplog 只存在于副本集环境中,单实例 MongoDB 不会生成 oplog。 - 如果需要使用点时间恢复(Point-in-Time Recovery),确保开启了 journaling 功能[^4]。 - 调整 oplog 大小可能会影响副本集的回滚能力和数据同步效率。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值