MongoDB 副本集管理
版本:3.6
一、以单机模式启动成员节点
有时候出于维护的需要,需要以单机模式启动某个节点而不是一个副本集成员身份。
1).首先查询服务器命令行参数
db.serverCmdLineOpts()
2).关闭当前副本
3).以单机模式启动副本
这里需要指定副本原先的db路径,为了避免可能的其它连接这里可以指定一个新的port启动;也可以直接使用原先的配置文件启动只需要注释掉“replSet”参数即可。
mongod --port 27000 --bind_ip 192.168.137.10,127.0.0.1 --dbpath /mongos27012/data/db4
4).维护完之后再以副本成员身份启动当前服务器。
二、检查写入是否成功
getLastError命令检查写入是否成功
db.runCommand({"getLastError":1,"w":2,"wtimeout":1000});
getLastErrorDefaults默认配置值
conf = rs.config(); conf.settings = {"getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 } }; rs.reconfig(conf);
wtimeout:等待超时时长,如果超过这个时间MongoDB无法在指定时间内将写入操作复制到“w”个成员,返回超时。
w的多个值:
majority:一直等待保证大多数成员都执行完了写入操作
number(数字):w值包含主节点,如果设置1那么只保证主节点写入成功,如果希望被复制到N个节点,那么应该将“w”设置为N+1
三、自定义复制保证规则,设置成员标签
1.设置成员标签
conf = rs.config(); conf.members[0].tags={"dc" : "dc01"}; conf.members[1].tags={"dc" : "dc01"}; conf.members[2].tags={"dc" : "dc02"}; rs.reconfig(conf);
上面操作设置了两个组,分别是dc01和dc02;
注意:
1.tags用来给每一个节点成员设置标签,它是一个集合所以可以像集合一样包含多个值,比如
{"dc": "rack1", disk:"ssd", ssd: "installed"}
2.如果要初始化tags必须先初始化settings.getLastErrorModes
2.配置规则,应用于settings选项
通过配置getLastErrorMode字段实现,每条规则的形式为:"name":{"key":number}.其中name是规则的名字,自己定,key就是上面tags的标识,number表示复制操作至少复制到多少个分组上,每个分组内至少一台机器上.
conf = rs.config(); conf.settings.getLastErrorModes={"eachDC":{"dc":2} } rs.reconfig(conf);
初始化getLastErrorModes
conf = rs.config(); conf.settings.getLastErrorModes={} rs.reconfig(conf);
3.插入记录并应用规则
db.users.insert( { id: "xyz", status: "A" }, { writeConcern: { w:"eachDC" } } );
注意:如果不想数据复制到某个节点,可以不给这个节点配置标签,这样该成员就是隐藏成员。
conf = rs.config(); conf.members[1].tags={}; rs.reconfig(conf);
4.注意事项
conf = rs.conf() conf.members[0].tags = { "dc": "east", "production": "node-1" } conf.members[1].tags = { "dc": "east", "production": "node-2" } conf.members[2].tags = { "dc": "east", "production": "node-3" } rs.reconfig(conf) 下面的规则可以创建成功,因为标签production拥有三个不同的组 conf.settings = { getLastErrorModes: { productionWriteConcern : { "production": 3 } } } 下面的规则不能创建成功,因为标签dc只有一个唯一的组 conf.settings = { getLastErrorModes: { dcWriteConcern : { "dc": 3 } } }
四、副本集配置
副本集的配置在local.system.replSet集合中。副本集中所有成员的的该文档记录都是相同的。
rs.:副本命令,是replSet是缩写,代表副本集。
db.:数据库命令,比如db.printReplicationInfo(),db.printSlaveReplicationInfo()
rs.status:查看成员的复制状态,可以在任意节点执行。
rs.config():可以得到当前副本的配置,修改配置文件,然后将修改后的配置文件传递给 reconfig、initiate命令。
rs.reconfig()(replSetReconfig):修改副本集的配置。rs.reconfig(conf,{"force":true})
rs.initiate():会初始化配置,只需要对副本集中的一个成员调用rs.initiate就可以(一般主节点),收到initiate命令的成员会自动将配置文件传递给副本集中的其他成员
1.创建副本集
1).登入
mongo --port 27010
2).切换admin数据库
use admin
3).验证权限
db.auth("dba","dba")
4).初始化复制集,默认会创建当前节点为主节点的副本集
rs.initiate()
5).重启当前节点
db.shutdownServer()
2.修改副本集成员
1).添加新成员,在主节点执行:
rs.add("192.168.137.10:27011") 可以在添加成员的时设定成员配置,也就是rs.conf中member的参数: rs.add("_id":1,"host":"192.168.137.10:27011", "priority" : 0, "hidden" : true)
2)删除成员
rs.remove("192.168.137.10:27012");
修改副本集成员配置时的限制:
1、不能修改_id;
2、不能将当前执行rs.reconfig命令的成员的优先级设置为 0;
3、不能将仲裁者成员变为非仲裁者成员,反正亦然;
4、不能将buildIndexes由false改为 true;
3.保证主节点不切换
将所有的备份节点的priority和votes都设置为0;这样只有主节点有投票权所以无论备份节点是否存在都不会导致主节点的状态由primary变成other。
conf=rs.config() conf.members[1].priority=0 conf.members[1].votes=0 rs.reconfig(conf)
4.强制重新配置
如果副本集无法选出新的主节点,这时需要重新配置副本集。可以在备份节点上调用rs.reconfig(conf,{"force":ture})强制重新配置副本集。注意conf必须是正确、有效的配置。而且只允许在备份节点执行强制重新配置。
备份节点收到新的配置文件之后,就会修改自身的配置,并且将新的配置发送给副本集中的其他成员。副本集的其他成员收到新的配置文件之后,会判断配置文件的发送者是否是它们当前配置中的一个成员,如果是,才会用心的配置文件对自己进行重新配置。所以,如果新的配置修改了某些成员的主机名,则应该关闭被修改主机名的节点,并以单机模式启动,手动修改locak.system.replset文档,然后以副本集的方式重新启动。
5.修改成员状态
1).把主节点变为备份节点,在主节点执行
rs.stepDown()
rs.stepDown(60):让主节点退化为备份节点,并维持60秒。如果这段时间内没有新的主节点被选举出来,那么当前节点可以要求重新参与进行选举。
2).阻止选举
如果需要对主节点进行维护操作,但是不希望这段时间内其它成员选举为主节点,可以在每个备份节点上执行freeze命令,以强制它们始终处于备份节点的状态。命令以秒为单位。
rs.freeze(3600):保持1个小时处于备份节点状态。 rs.freeze(0):再次在备份节点执行且将时间指定为0就是“释放”备份节点。
注意:如果在退位的备份节点上执行rs.freeze(0),可以让退位的备份节点重新变为主节点。
6.禁用复制链
1).查看复制源
查询节点从哪个节点处复制。在备份节点上运行。
db.adminCommand({"replSetGetStatus":1})['syncingTo'];
也可以运行rs.status(),查看"syncingTo"字段信息。
2.)复制链
MongoDB根据ping时间选择同步源,一个成员向另一个成员发送心跳请求,就知道心跳请求所耗费的时间(rs.status()中的"pingMs"记录了成员到达相关成员的所花费的平均时间)。MongosDB维护着不同成员间请求的平均花费时间。选择同步源时,会选择一个离自己比较近而且数据比自己新的成员。但是同一数据中心的成员可能会从同一数据中心的其他成员处复制,而不是从位于另一个数据中心的主节点处复制(这样可以减少网络流量),所以会出现复制链的情况,复制链越长会导致主节点的操作复制到所有的服务器所花费的时间越长。这对于需要从副本中读取数据的需求这种情况是不希望看到的。
3).修改复制源
db.adminCommand({"replSetSyncFrom":"192.168.137.10:27011"});
4).禁用复制链
conf = rs.conf() conf.settings.chainingAllowed = false rs.reconfig(conf)
在主副本中执行
7.计算延迟
1).查看当前副本集oplog状态
rs.printReplicationInfo()
configured oplog size:oplog配置的大小
log length start to end:oplog包含的操作时长。
oplog first event time:oplog第一条操作的时间。
oplog last event time:oplog最后一条操作的时间。
now:当前时间。
注意:oplog中第一条操作与最后一条操作的时间差就是操作日志的长度。
2).查看复制延迟
rs.printSlaveReplicationInfo()
会显示当前所有的备份节点同步时间,和落后主节点的时长。
8.调整oplog大小
1) 如果是主节点,将主节点变成备份节点。
2) 将oplog中的最后一条insert操作保存到其它集合中。
use local var lastinsert = db.oplog.rs.find({"op":{$in:["i"]}}).sort({"wall":-1}).limit(1).next(); db.tempLastOp20180330.save(lastinsert) db.tempLastOp20180330.find()
3) 关闭当前服务器
4) 以单机模式启动
mongod --port 27000 --bind_ip 192.168.137.10,127.0.0.1 --dbpath /mongos27012/data/db
5) 删除当前oplog
db.oplog.rs.drop();
6) 创建新的oplog
db.createCollection("oplog.rs",{"capped":true,"size":1048576})
7) 将最后一条insert记录写回oplog
var tempLastOp=db.tempLastOp20180330.find().next() db.oplog.rs.insert(tempLastOp) db.oplog.rs.find()
8) 以副本成员身份启动当前服务器
五、复制集监控
1.复制集状态查询:rs.status()
2.查看当前副本集oplog状态:rs.printReplicationInfo()
3.查看复制延迟:rs.printSlaveReplicationInfo()
4.查看服务状态详情:db.serverStatus()
5.查询副本集配置:rs.conf()
6.主副本查询:db.isMaster()
备注: 作者:pursuer.chen 博客:http://www.cnblogs.com/chenmh 本站点所有随笔都是原创,欢迎大家转载;但转载时必须注明文章来源,且在文章开头明显处给明链接,否则保留追究责任的权利。 《欢迎交流讨论》 |