存储引擎(Storage Engine)是MongoDB的核心组件,负责管理数据如何存储在硬盘(Disk)和内存(Memory)上。从MongoDB 3.2 版本开始,MongoDB 支持多数据存储引擎(Storage Engine),MongoDB支持的存储引擎有:WiredTiger,MMAPv1和In-Memory。

从MongoDB 3.2 版本开始,WiredTiger成为MongDB默认的Storage Engine,用于将数据持久化存储到硬盘文件中,WiredTiger提供文档级别(Document-Level)的并发控制,检查点(CheckPoint),数据压缩和本地数据加密( Native Encryption)等功能。

Oplog 的默认储存大小

对于 unix 系统和 windows 系统

Storage Engine

Default Oplog Size

Lower Bound

Upper Bound

In-Memory Storage Engine

5% of physical memory

50 MB

50 GB

WiredTiger Storage Engine

5% of free disk space

990 MB

50 GB

MMAPv1 Storage Engine

5% of free disk space

990 MB

50 GB

Oplog 存储在 local 库的 oplog.rs 集合里面。对于一般的线上环境来说,默认的 Oplog 值就已经足够了。当达到储存大小的日志时,新的记录会将老的记录覆盖。

查看 Oplog 的状态:rs.printReplicationInfo()

查看当前的 Oplog 存储设置的大小:db.oplog.rs.stats().maxSize

查看 Oplog 最大大小和现在占用的大小,以及记录时长和时间 :db.getReplicationInfo()

local库下的每个集合分别记录的内容
local库下面的replset.minvalid集合保存了数据库最新操作的时间戳
local库下面的startup_log集合记录这mongod每一次的启动信息
local库下面的system.indexes集合记录当前库的所有索引信息
local库下面的system.replset记录着复制集的成员配置信息rs.conf()读取这个集合
local库下面的oplog.rs集合记录着所有操作,MongoDB就是通过oplog.rs来实现数据同步的。当Primary节点插入一条数据后,oplog.rs集合中就会多一条记录

oplog数据结构

通过下面的命令取出一条oplog:

db.oplog.rs.find().skip(1).limit(1).toArray()
  • ts: 8字节的时间戳,由4字节unix timestamp + 4字节自增计数表示。这个值很重要,在选举(如master宕机时)新primary时,会选择ts最大的那个secondary作为新primary
  • op:1字节的操作类型
  • "i": insert
  • "u": update
  • "d": delete
  • "c": db cmd
  • "db":声明当前数据库 (其中ns 被设置成为=>数据库名称+ '.')
  • "n": no op,即空操作,其会定期执行以确保时效性
  • ns:操作所在的namespace
  • o:操作所对应的document,即当前操作的内容(比如更新操作时要更新的的字段和值)
  • o2: 在执行更新操作时的where条件,仅限于update时才有该属性

查询oplog里的insert记录,对应op为i的记录:
db.oplog.rs.find({"op" : "i"}).pretty().limit(3)
查update操作命令:
 db.oplog.rs.find({"op" : "u"}).pretty().limit(3)
查delete操作命令:
test:PRIMARY> db.oplog.rs.find({"op" : "d"}).pretty().limit(3)
根据时间范围查操作:
db.oplog.rs.find({"o.createTime": {$gte:new Date(2017,9,1)}}).limit(3)
查时间段的操作记录:
 db.oplog.rs.find({"o.createTime": {$gte:new Date(2017,9,1),$lte:new Date(2017,10,31)}}).limit(3)
我们查查对test集合进行操作的所有的 oplog 记录
test:PRIMARY> db.oplog.rs.find({ns : "db.test"})