第一部分 应用情景
oplog的大小不能在正常操作过程中修改。在大多数情况下,默认oplog大小是一个可接受的大小;然而,在某些情况下,您可能需要一个更大或更小的oplog。例如,如果应用程序在短时间内执行大量多更新或删除操作,则可能需要更改oplog大小。
生产环境出现多次Primary写入QPS太高,导致Seconary的同步无法跟上的问题(Secondary上的最新oplog时间戳比Primary上最旧oplog时间戳小),使得Secondary变成RECOVERING状态,这时需要人工介入处理,向Secondary发送resync命令,让Secondary重新全量同步一次。
第二部分 改进方案
2.1 修改oplog的大小
首先关闭该节点
db.shutdownServer()
取消复制集参数,并在不同端口上以独立模式重新启动Secondary节点
net:
port: 57019
#replication:
#oplogSizeMB: 1024
#replSetName: configRS
#secondaryIndexPrefetch: all
备份原有的oplog.rs集合(可选步骤)
mongodump --db local --collection 'oplog.rs' --port 57019
开始重建oplog
保存原有oplog的最后一个条目,切换到local数据库,设置变量,暂存local数据库为db变量,删除临时数据库,确保为空
use local
db = db.getSiblingDB('local')
db.temp.drop()
使用db.collection.save()方法和反向排序查找最后一个条目并将其保存到临时集合中,请执行以下操作
db.temp.save( db.oplog.rs.find( { }, { ts: 1, h: 1 } ).sort( {$natural : -1} ).limit(1).next() )
查看是否保存在temp集合下
db.temp.find()
删除原有的oplog.rs集合,结果返回为true
db = db.getSiblingDB('local')
db.oplog.rs.drop()
创建新的oplog,大小为2GB
db.runCommand( { create: "oplog.rs", capped: true, size: (2 * 1024 * 1024 * 1024) } )
将原来oplog的最后一条记录保存到新的oplog.rs集合中
db.oplog.rs.save( db.temp.findOne() )
查看是否已经保存到新的oplog.rs集合中
db.oplog.rs.find()
关闭数据库,并恢复为原来的配置
use admin
db.shutdownServer()
启动数据库
mongod -f /home/mongod/mongod1.conf
注:对所有可能成为主成员的成员,请重复以上过程。作为以下步骤的一部分,重复主步骤的过程,主库在操作时,需要降级为Secondary,使用:
rs.stepDown()
2.2 加速重放oplog
关闭对应延迟高的Secondary节点服务,配置以下到参数文件
setParameter:
replWriterThreadCount: 32
并重新启动服务
或者以命令行启动方式设置该参数的值,如下
mongod --setParameter replWriterThreadCount=32
注:配置更高的replWriterThreadCount,能够让Secondary加速oplog重放,但是代价是更高的内存开销。