MongoDB 的Replication是通过一个日志来存储写操作的,这个日志就叫做oplog。oplog记录了主节点上的每一次写操作。oplog是主节点上local数据库中的一个固定集合,备份节点通过查询该集合
就可以知道需要进行复制的操作。每个备份节点都维护着自己的oplog,记录着每次从主节点复制数据的操作(每备份节点从同步源获取需要执行的操作并应用到自身,最后将这些操作记录到自己的oplog)。
在默认情况下,oplog分配的是空闲磁盘空间的5%。通常而言,这是一种合理的设置。最大不超过50G空间。可以通过mongod –oplogSize来改变oplog的日志大小。
oplog是capped collection,因为oplog的特点(不能太多把磁盘填满了,固定大小)需要,MongoDB才发明了capped collection(the oplog is actually the reason capped collections were invented).
oplog的位置
oplog在local库:
master/slave 架构下
local.oplog.$main;
replica sets 架构下:
local.oplog.rs
sharding 架构下,mongos下不能查看oplog,可到每一片去看。
Oplog和数据刷新到磁盘的时间是60s,对于复制来说,不用等到oplog刷新磁盘,在内存中就可以直接复制到Sencondary节点。
oplog是 特殊的capped collection ,用来滚动保存mongodb中所有数据操作的日志。
oplog 数据结构格式:
{ts:...,op:...,ns:...,o:...,o2:...}
ts: 8字节的时间戳,由4字节unix timestamp+4字节自增计数表示。在选举新primary时,会选择ts最大的那个secondary作为primary
op:1字节的操作类型(i 代表insert,d代表 delete,u代表update,c代表db cmd,db代表声明当前数据库,n代表空操作)
ns:操作所在的namespace。
o:操作所对应的document,即当前操作的内容。
o2:在执行更新时的where条件,仅限于update时才有该属性。
查看oplog的内容
local 库中的集合 oplog.rs 记录了oplog 操作日志内容。
use local
show collections;
db.oplog.rs.find();
oplog的大小是维护工作时间的重要窗口。即有多长时间可以用以修复各种错误,所以oplog能够保存几天几周的数据,以留够时间处理问题
查看oplog大小
通过 db.printReplicationInfo() 命令查看 oplog 状态
db.printReplicationInfo()
修改oplog大小
启动mongod时指定 oplogsize 单位为MB
占用大量oplog空间的操作
1、在同一时刻更新多个文档
2、在插入操作同时删除相同大小数据
3、大量的in-place更新操作。
运行中修改oplog大小
1、如果当前服务器是主节点则,让它退位,接着关闭当前服务器,再以单机模式启动(用不同的端口)。
2、临时将oplog中的最后一条insert操作保存到其他集合中:use local
var cursor=db.oplog.rs.find({"op":"i"})
var lastInsert=cursor.sort({"$natural":-1}).limit(1).next()
db.tempcollectionLastOp.save(lastInsert)
db.tempcollectionLastOp.findOne()#确认是否保存成功
3、删除当前的oplog
db.oplog.rs.drop()
4、创建新的oplog
db.createCollection("oplog.rs",{"capped":true,"size":1024})
5、将最后一条insert操作写回oplog
var tmp=db.tempcollectionLastOp.findOne()
db.oplog.rs.insert(tmp)
db.oplog.rs.findOne()#同样确认是否已成功写回
6、重新将该服务器以源副本集的端口方式重新启动。