oplog: 执行日志—mongodb用来实现statement-based replication的文件
oplog将每次“写”操作对应的update,delete,insert记录,存放在local 库中一个capped collection中。
特点:
- oplog具有幂等性,无论重复执行多少次,依然得到的是相同结果。
- 对于一个document的操作会存放在一个oplog中。 ( 同一次operation中,不同document的操作,在primary上,会被分成不同oplog。如果修改了1万个documents那么就会产生1万份oplog。 )
- 当大批量BULK操作对于同一个document发生的时候,很可能oplog会溢出。所以需要设置合理的oplog size来满足业务需求。
设计合理的oplog size:
比如:
- 大小满足一次fullsync
- 以维护窗口时间为标准:oplog长度恢复需要小于维护窗口时间。
修改oplog size:
(1):初始化时,通过oplogSizeMB选项来设置一个较大的oplog文件大小。
(2): 运行中的集群,调整集群中某一台机器的oplog大小(不造成数据丢失):
- 如果是primary,先退位,然后等待其他服务器同步最新数据
- shut down服务器,以standalone 模式重新启动
- 保存最后一条oplog记录。
use local>
var cursor = db.oplog.rs.find({“op” : “i”})
var lastInsert = cursor.sort({“$natural” : -1}).limit(1).next() // finds the last insert
db.tempLastOp.save(lastInsert)
// make sure it was saved! It’s very important that you don’t lose this op
db.tempLastOp.findOne()
4.删除当前oplog文件
db.oplog.rs.drop()
5.新建oplog文件
db.createCollection(“oplog.rs”, {“capped” : true, “size” : 10000})
6.恢复最后一条oplog 记录 (这里我人为目的不是恢复数据,而是让服务器有一个oplog最后更新的时间记录,在与其他节点同步时才有一个判断)
var temp = db.tempLastOp.findOne()
db.oplog.rs.insert(temp)
// make sure that this was actually inserted
db.oplog.rs.findOne()
7.以集群方式重启服务
Replica set中的数据同步:
没有投票权的成员,不能成为被同步的对象。
初始化同步:
(1)在线初始化
- 复制除了Local 以外的所有库。通过插入的方式,插入目标数据库。如果现有数据库中有已存在的对象,mongd会先删除他们。
- 在document被复制的同时,index也会被建立。
- 复制期间,目标数据库所在节点会拉去复制期间产生的oplog记录到local数据库中(所以,初始化时需要保证LOCAL足够大)
- 如果在复制的期间,document 可能会有’写’操作发生在源。后面可能replicate的时候可能就失败。那么恢复拉取的oplog的时候就可能会对有缺失的部分重新clone。
- 笼统的说,把源插入到目标的时候,源需要同步的数据都会先抓取到自己的内存中,这样就会造成一些常用的数据被挤出内存。影响源的日常运行。
- 建议不要再生产环境使用initial sync 同步方式,因为会为primary造成额外的压力影响生产环境正常运行。
(2)离线初始化
通过backup, restore 的方式离线初始化。
Stale
通过oplog同步会带来的问题,当oplog中需要处理的事务/记录的量,目标节点大程度跟不上源节点的“写”速度时。目标节点会进入stale状态。停止从源通过oplog方式同步。
比如:
- 源oplog已经删了,目标找不到需要用来同步的oplog
- 源和目标的性能差异太大。目标无法handle。
Replica set 工作状态:
STARTUP :初次加入并启动的时候,通过rs.config
STARTUP2 : 整个initial sync 过程。或者正常节点正常启动一个连接,线程的时候(瞬时状态)。
RECOVERING: 不能接受read。
- 1.stale即为一种RECOVERING状态。节点需要重新做一个sync或者restore。
- 2.手动使用replSetMaintenance,使节点进入recovering状态
ARBITER : 仲裁节点特有的状态
DOWN: 无法找到节点(网络原因或者关闭)
UNKNOWN : 网络通,但是无法识别状态
REMOVED: 被删除的节点
ROLLBACK: 节点正在回滚
Replica set 中index的同步的问题:
- 索引复制会很消耗资源,可以考虑使用stanalone模式 分别离线完成索引建立。
- secondary上可以建立额外的索引,但是必须设置为prioriy:0。
- 创建唯一索引的话,应当在primary上完成。因为,如果secondary有唯一索引,但primary插入了重复记录的话,会造成secondary复制错误/失败。(此时,secondary会自动down机。需要在standalone模式重启,删掉唯一索引,再以集群方式重启)
- 对于纯备份,离线任务节点。应该考虑使用”buildIndexes” : false 来禁止该节点生成INDEX。通过reconfig 不能让该节点重新支持建立索引,只能删除节点重新加入。因为不能建立索引,所以无法成为primary