这里我们把复制集中可用的方法都实验一遍,帮助我们更好地来理解复制集。提前说明这些方法的使用是基于Mongodb3.2版本来的,看这篇文章之前需要先看上一篇文章。
介绍一下复制集可用的相关方法
rs.help()
#查看(rs)复制集相关的方法.
rs.status()
#返回复制集的当前状态,使用的数据来源于副本集中其他成员发送的心跳包.
rs.initiate()
#简单初始化一个新的复制集.
rs.initiate(cfg)
#配置复制集,采用新的复制集配置对象(配置文件).
rs.conf()
#返回复制集配置文件.
rs.reconfig(cfg)
#通过重新应用复制集配置文件来为复制集更新新配置,这个操作只能在主节点执行,会短暂断开连接.
rs.add(hostportstr)
#添加一个成员到复制集,会短暂断开连接.
rs.add(membercfgobj)
#添加一个成员到配置文档,会短暂断开连接.
rs.addArb(hostportstr)
#添加一个ARBITER成员到复制集.
rs.stepDown([stepdownSecs, catchUpSecs])
#让当前的主节点变为从节点并触发选举,会短暂断开连接.
rs.syncFrom(hostportstr)
#设置复制集节点从哪个节点处同步数据,将会覆盖默认选取逻辑.
rs.freeze(secs)
#控制当前节点在一段时间内选举成为主节点.
rs.remove(hostportstr)
#从复制集中移除一个成员,会短暂断开连接.
rs.slaveOk()
#用来开启从节点是否有查询权限,值为true时表示开启查询(需要在从节点执行rs.slaveOk).
rs.printReplicationInfo()
#检查主节点oplog大小和时间范围.
rs.printSlaveReplicationInfo()
#检查从节点复制状态.
db.isMaster() & rs.isMaster()
#检查谁是主节点,如果isMaster为true则表示此节点为主节点,而应用程序就是靠isMaster来识别主从节点并且isMaster对隐藏节点不可见,而rs.status可以显示所有成员信息.
rs.stepDown([stepdownSecs, catchUpSecs])
让当前主节点成为从节点并触发选举,并可以在切换时给一个时间(秒),表示在这个时间内此节点不能被选为主节点。这里我的主节点是27017.
192.168.60.10:27017
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
ywnds:PRIMARY> rs.stepDown(600) 2016-02-04T12:08:20.694+0800 DBClientCursor::init call() failed 2016-02-04T12:08:20.694+0800 Error: error doing query: failed at src/mongo/shell/query.js:81 2016-02-04T12:08:20.697+0800 trying reconnect to 192.168.60.10:27017 (192.168.60.10) failed 2016-02-04T12:08:20.701+0800 reconnect 192.168.60.10:27017 (192.168.60.10) ok ywnds:SECONDARY> ywnds:SECONDARY> rs.isMaster() { "setName" : "ywnds", "setVersion" : 1, "ismaster" : false, "secondary" : true, "hosts" : [ "192.168.60.10:27017", "192.168.60.10:27018" ], "arbiters" : [ "192.168.60.10:27019" ], "primary" : "192.168.60.10:27018", "me" : "192.168.60.10:27017", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2016-02-04T04:20:37.953Z"), "maxWireVersion" : 2, "minWireVersion" : 0, "ok" : 1 } |
你可以看到,当主节点执行延迟2秒进行主从切换操作后,主节点立马会变成从节点,标识符PRIMARY会变成SECONDARY,使用rs.isMaster看看状态信息,发现主从已经调换但投票节点还是投票节点,它不会有任何改变。
192.168.60.10:27018
看看从节点会话,标识符会立马从SECONDARY变成PRIMARY。
1 2 |
ywnds:SECONDARY> ywnds:PRIMARY> |
rs.reconfig(cfg)
通过重新应用复制集配置文件来为复制集更新新配置,这个操作只能在主节点执行。复制集的配置文档存在local.system.replset集合中。
1 2 3 |
ywnds:PRIMARY> config = db.system.replset.findOne() ywnds:PRIMARY> rs.reconfig(config) { "ok" : 1 } |
rs.remove(hostportstr)
从复制集中移除一个成员,会短暂断开连接,现在我们来移除ARBITER节点,目前复制集还有两个成员,一个主节点(192.168.60.10:27018)和一个从节点(192.168.60.10:27017).具体操作如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
ywnds:PRIMARY> rs.remove("192.168.60.10:27019") 2016-02-15T04:08:01.615+0800 DBClientCursor::init call() failed 2016-02-15T04:08:01.615+0800 Error: error doing query: failed at src/mongo/shell/query.js:81 2016-02-15T04:08:01.619+0800 trying reconnect to 192.168.60.10:27018 (192.168.60.10) failed 2016-02-15T04:08:01.620+0800 reconnect 192.168.60.10:27018 (192.168.60.10) ok ywnds:PRIMARY> rs.status() { "set" : "ywnds", "date" : ISODate("2016-02-14T20:08:13Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "192.168.60.10:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 12, "optime" : Timestamp(1455480481, 1), "optimeDate" : ISODate("2016-02-14T20:08:01Z"), "lastHeartbeat" : ISODate("2016-02-14T20:08:13Z"), "lastHeartbeatRecv" : ISODate("2016-02-14T20:08:13Z"), "pingMs" : 0, "lastHeartbeatMessage" : "syncing to: 192.168.60.10:27018", "syncingTo" : "192.168.60.10:27018" }, { "_id" : 1, "name" : "192.168.60.10:27018", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 864061, "optime" : Timestamp(1455480481, 1), "optimeDate" : ISODate("2016-02-14T20:08:01Z"), "electionTime" : Timestamp(1455480326, 1), "electionDate" : ISODate("2016-02-14T20:05:26Z"), "self" : true } ], "ok" : 1 } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
ywnds:PRIMARY> rs.conf() { "_id" : "ywnds", "version" : 4, "members" : [ { "_id" : 0, "host" : "192.168.60.10:27017" }, { "_id" : 1, "host" : "192.168.60.10:27018" } ] } |
移除完192.168.60.10:27019节点后,可以看到复制集状态信息中已经没有这个节点的信息了,包括复制集配置文档中也没有此节点信息了。当复制集还剩下两个节点时,如果此时有一个节点挂掉的话,那么复制集容灾就不满足2/1原则(剩余节点没有大于总节点数),那么接下来剩余的一个节点就会是从节点故而整个复制集变得不可用。下面模拟27017故障然后看看27018节点的变化。
192.168.60.10.:27017
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
ywnds:SECONDARY> rs.isMaster() { "setName" : "ywnds", "setVersion" : 4, "ismaster" : false, "secondary" : true, "hosts" : [ "192.168.60.10:27017", "192.168.60.10:27018" ], "primary" : "192.168.60.10:27018", "me" : "192.168.60.10:27017", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2016-02-14T20:56:09.904Z"), "maxWireVersion" : 2, "minWireVersion" : 0, "ok" : 1 } [root@node1 ~]# cat /mongodb/pid/pid27017/mongod.pid 93840 [root@node1 ~]# kill -2 93840 |
192.168.60.10.:27018
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
ywnds:PRIMARY> 2016-02-15T04:16:16.354+0800 DBClientCursor::init call() failed 2016-02-15T04:16:16.382+0800 trying reconnect to 192.168.60.10:27018 (192.168.60.10) failed 2016-02-15T04:16:16.382+0800 reconnect 192.168.60.10:27018 (192.168.60.10) ok ywnds:SECONDARY> ywnds:SECONDARY> rs.isMaster() { "setName" : "ywnds", "setVersion" : 4, "ismaster" : false, "secondary" : true, "hosts" : [ "192.168.60.10:27018", "192.168.60.10:27017" ], "me" : "192.168.60.10:27018", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2016-02-14T20:18:08.922Z"), "maxWireVersion" : 2, "minWireVersion" : 0, "ok" : 1 } |
rs.addArb(hostportstr)
添加一个ARBITER成员到复制集,只能在主节点上操作,所以我们要先把27017节点启动起来,重新选举一个主节点。
192.168.60.10:27017
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[root@node1 ~]# mongod -f /mongodb/conf/conf27017/mongod.conf about to fork child process, waiting until server is ready for connections. forked process: 99692 child process started successfully, parent exiting [root@node1 ~]# mongo 192.168.60.10:27017 MongoDB shell version: 2.6.0 connecting to: 192.168.60.10:27017/test ywnds:SECONDARY> ywnds:SECONDARY> ywnds:SECONDARY> ywnds:PRIMARY> ywnds:PRIMARY> rs.addArb("192.168.60.10:27019") { "ok" : 1 } |
192.168.60.10:27019
1 2 3 4 5 6 7 8 9 10 11 12 |
[root@node1 ~]# mongo 192.168.60.10:27019 MongoDB shell version: 2.6.0 connecting to: 192.168.60.10:27019/test ywnds:REMOVED> ywnds:REMOVED> ywnds:REMOVED> ywnds:REMOVED> ywnds:REMOVED> ywnds:REMOVED> ywnds:REMOVED> ywnds:ARBITER> ywnds:ARBITER> |
rs.add(hostportstr)
添加一个成员到复制集,会短暂断开连接。下面创建一个新的节点(27010)并启动,然后加入到现在的复制集中。
192.168.60.10:27010
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
[root@node1 ~]# mkdir /mongodb/conf/conf27010 [root@node1 ~]# mkdir /mongodb/data/data27010 [root@node1 ~]# mkdir /mongodb/pid/pid27010 [root@node1 ~]# mkdir /mongodb/log/log27010 [root@node1 ~]# cp /mongodb/conf/conf27017/mongod.conf /mongodb/conf/conf27010/ [root@node1 ~]# vi /mongodb/conf/conf27010/mongod.conf #/etc/mongod.conf logpath = /mongodb/log/log27010/mongod.log logappend = true dbpath = /mongodb/data/data27010 port = 27010 bind_ip=192.168.60.10 fork = true pidfilepath = /mongodb/pid/pid27010/mongod.pid logRotate = rename timeStampFormat = ctime #Replica Set oplogSize = 1024 replSet = ywnds replIndexPrefetch = _id_only [root@node1 ~]# mongod -f /mongodb/conf/conf27010/mongod.conf about to fork child process, waiting until server is ready for connections. forked process: 101491 child process started successfully, parent exiting |
192.168.60.10:27017
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
ywnds:PRIMARY> rs.add("192.168.60.10:27010") { "ok" : 1 } ywnds:PRIMARY> rs.conf() { "_id" : "ywnds", "version" : 8, "members" : [ { "_id" : 0, "host" : "192.168.60.10:27017" }, { "_id" : 1, "host" : "192.168.60.10:27018" }, { "_id" : 2, "host" : "192.168.60.10:27019", "arbiterOnly" : true }, { "_id" : 3, "host" : "192.168.60.10:27010" } ] } |
192.168.60.10:27010
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[root@node1 ~]# mongo 192.168.60.10:27010 MongoDB shell version: 2.6.0 connecting to: 192.168.60.10:27010/test ywnds:SECONDARY> ywnds:SECONDARY> ywnds:SECONDARY> show dbs admin (empty) local 2.077GB ywnds 0.078GB ywnds:SECONDARY> use ywnds switched to db ywnds ywnds:SECONDARY> show tables 2016-02-15T06:16:18.362+0800 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:131 ywnds:SECONDARY> rs.slaveOk() ywnds:SECONDARY> show tables system.indexes ywnds ywnds:SECONDARY> db.ywnds.find() { "_id" : ObjectId("56b174aed239dcb7b2dacc1f"), "name" : "ywnds", "age" : "20", "gender" : "B" } |
rs.printReplicationInfo()
检查主节点oplog大小和时间范围.
1 2 3 4 5 6 |
ywnds:PRIMARY> rs.printReplicationInfo() configured oplog size: 1958.92041015625MB log length start to end: 1023492secs (284.3hrs) oplog first event time: Wed Feb 03 2016 09:56:23 GMT+0800 (CST) oplog last event time: Mon Feb 15 2016 06:14:35 GMT+0800 (CST) now: Mon Feb 15 2016 06:18:57 GMT+0800 (CST) |
rs.printSlaveReplicationInfo()
检查从节点复制状态.
1 2 3 4 5 6 7 |
ywnds:SECONDARY> rs.printSlaveReplicationInfo() source: 192.168.60.10:27018 syncedTo: Mon Feb 15 2016 06:14:35 GMT+0800 (CST) 0 secs (0 hrs) behind the primary source: 192.168.60.10:27010 syncedTo: Mon Feb 15 2016 06:14:35 GMT+0800 (CST) 0 secs (0 hrs) behind the primary |