背景:
,,原来一个同事问我主从mongodb数据库为什么数据差距很大,我让他察看一下两边有啥不一样,发现
推测是oplog太大了,oplog是类似于mysql的binlog甲骨文的archivelog
Oplog Oplog
为了进一步确认,进入mongodb之后通过
显示dbs
使用本地
显示集合
看到现有的集合
然后
“ns”:“local.oplog。美元主要”,
“uri”:“统计:收集表:本地/- 2 - 1716662444632575459”
就可以确认oplog集合的相应文件,oplog如果太大可以清理和修改大小。
MongoDB oplog是一个限制收集、创建封顶集合时,createCollection可以设置大小(最大字节数)和马克斯(最大文档数)的参数,当这个集合的“总大小超过大小”或”者总文档数超过马克斯”时,在新插入文档时就会自动删除一些集合内最先插入的文档,相当于一片环形的存储空间。
oplog (local.oplog。rs集合)默认情况下配置为可用磁盘空间的5%,当oplog写满时,就会开始删除最先写入的oplog,一次正常的插入操作包含如下步骤:
- <李>
将文档写入指定的集合
李> <李>将写入操作记录到oplog
李> <李>如果oplog满了,删除最先写入的oplog
李>优化策略
MongoDB 3.2为了提升写入性能,使用wiredtiger引擎时,针对local.oplog。rs这个集合的删除策略进行了优化,主要改进:
- <李>
将删除动作从用户的写入路径移除,放到后台线程执行
李> <李>批量删除,并不是oplog一满就立马触发删除,而是一次删除一批
李>实施方案
monogd启动时,会根据oplog的最大字节数将整个集合分为10 - 100个石头(可以理解为oplog的一段数据,包含多个文档,石头的具体个数oplogSizeMB的配置相关)。
WiredTigerRecordStore:: OplogStones: OplogStones (OperationContext *,公司,WiredTigerRecordStore *, rs) ,,,:,_rs (rs), { ,,,//? ,,,unsigned long long maxSize =, rs和;gt; cappedMaxSize (); ,,,const unsigned long long kMinStonesToKeep =, 10妳; ,,,const unsigned long long kMaxStonesToKeep =, 100妳; ,,,unsigned long long numStones =, maxSize /, BSONObjMaxInternalSize; ,,,_numStonesToKeep =, std:: min (kMaxStonesToKeep, std::马克斯(kMinStonesToKeep, numStones)); ,,,_minBytesPerStone =, maxSize /, _numStonesToKeep; ,,,//,… }
其中<代码> _numStonesToKeep> 代码为oplog应该保持的石头个数,而<代码> _minBytesPerStone 代码>代表每个石头的最小字节数。
接下来,会根据oplog当前的大小以及<代码> _minBytesPerStone> 代码来估算下,当前的oplog大致包含的石头数量,并通过采样的方式来获取每个石头的起始位置(不能保证每个石头的大小跟预期完全一样),然后将所有的石头按顺序存储到一个队列中。
mongod在服务写请求的过程中,每次都会记录下新产生oplog的大小,当新产生的oplog的总量超过<代码> _minBytesPerStones> 代码时,就会产生一个新的石头加入到队列中。
void WiredTigerRecordStore: OplogStones: createNewStoneIfNeeded (RecordId lastRecord), { ,,,if (_currentBytes.load(),和lt;, _minBytesPerStone), { ,,,,,,,//,Must have raced 用create a new 石头,someone else already triggered 它。 ,,,,,,,返回; ,,,} ,,,//,… ,,,OplogStones: Stone Stone =, {_currentRecords.swap (0), _currentBytes.swap (0), lastRecord}; ,,,_stones.push_back(石); ,,,_pokeReclaimThreadIfNeeded();,//,唤醒后台回收oplog空间的线程 }
当队列中石头的数量超过<代码> _numStonesToKeep> 代码,后台线程就会删除最老的石头里的数据,来回收oplog的存储空间。
修改mongodb oplog大小
oplog简介:
oplog:操作日志的简写,存储在一个特殊的数据库中(本地),oplog就存储在其中的oplog。美元主要集合里面,这个集合是一个固定集合,新操作会自动替换旧的操作,以保证oplog不会超过预设的大小,其中的每个文档都代表主节点上执行的一个操作,oplog会包含所有对数据有修改的的操作(查询操作不会记录),默认下,oplog大小会占用64位的实例5%的可用磁盘空间。