共计 12735 个字符,预计需要花费 32 分钟才能阅读完成。
本文是对 MongoDB 副本集常用操作的一个汇总,同时也穿插着介绍了操作背后的原理及注意点。结合之前的文章:MongoDB 副本集的搭建,大家可以在较短的时间内熟悉 MongoDB 的搭建和管理。
下面的操作主要分为两个部分:
1. 修改节点状态
主要包括:
1> 将 Primary 节点降级为 Secondary 节点
2> 冻结 Secondary 节点
3> 强制 Secondary 节点进入维护模式
2. 修改副本集的配置
1> 添加节点
2> 删除节点
3> 将 Secondary 节点设置为延迟备份节点
4> 将 Secondary 节点设置为隐藏节点
5> 替换当前的副本集成员
6> 设置副本集节点的优先级
7> 阻止 Secondary 节点升级为 Primary 节点
8> 如何设置没有投票权的 Secondary 节点
9> 禁用 chainingAllowed
10> 为 Secondary 节点显式指定复制源
11> 禁止 Secondary 节点创建索引
首先查看 MongoDB 副本集支持的所有操作
> rs.help() | |
rs.status() { replSetGetStatus : 1 } checks repl set status | |
rs.initiate() { replSetInitiate : null } initiates set with default settings | |
rs.initiate(cfg) {replSetInitiate : cfg} initiates set with configuration cfg | |
rs.conf() get the current configuration object from local.system.replset | |
rs.reconfig(cfg) updates the configuration of a running replica set with cfg (disconnects) | |
rs.add(hostportstr) add a new member to the set with default attributes (disconnects) | |
rs.add(membercfgobj) add a new member to the set with extra attributes (disconnects) | |
rs.addArb(hostportstr) add a new member which is arbiterOnly:true (disconnects) | |
rs.stepDown([stepdownSecs, catchUpSecs]) step down as primary (disconnects) | |
rs.syncFrom(hostportstr) make a secondary sync from the given member | |
rs.freeze(secs) make a node ineligible to become primary for the time specified | |
rs.remove(hostportstr) remove a host from the replica set (disconnects) | |
rs.slaveOk() allow queries on secondary nodes | |
rs.printReplicationInfo() check oplog size and time range | |
rs.printSlaveReplicationInfo() check replica set members and replication lag | |
db.isMaster() check who is primary | |
reconfiguration helpers disconnect from the database so the shell will display | |
an error, even if the command succeeds. |
修改节点状态
将 Primary 节点降级为 Secondary 节点
myapp:PRIMARY> rs.stepDown()
这个命令会让 primary 降级为 Secondary 节点,并维持 60s,如果这段时间内没有新的 primary 被选举出来,这个节点可以要求重新进行选举。
也可手动指定时间
myapp:PRIMARY> rs.stepDown(30)
在执行完该命令后,原 Secondary node3:27017 升级为 Primary。
其日志输出为:
原 Primary node3:27018 降低为 Secondary
冻结 Secondary 节点
如果需要对 Primary 做一下维护,但是不希望在维护的这段时间内将其它 Secondary 节点选举为 Primary 节点,可以在每次 Secondary 节点上执行 freeze 命令,强制使它们始终处于 Secondary 节点状态。
myapp:SECONDARY> rs.freeze(100)
注:只能在 Secondary 节点上执行
myapp:PRIMARY> rs.freeze(100) | |
{"ok" : 0, | |
"errmsg" : "cannot freeze node when primary or running for election. state: Primary", | |
"code" : 95, | |
"codeName" : "NotSecondary" | |
} |
如果要解冻 Secondary 节点,只需执行
myapp:SECONDARY> rs.freeze()
强制 Secondary 节点进入维护模式
当 Secondary 节点进入到维护模式后,它的状态即转化为“RECOVERING”,在这个状态的节点,客户端不会发送读请求给它,同时它也不能作为复制源。
进入维护模式有两种触发方式:
1. 自动触发
譬如 Secondary 上执行压缩
2. 手动触发
myapp:SECONDARY> db.adminCommand({"replSetMaintenance":true})
修改副本集的配置
添加节点
myapp:PRIMARY> rs.add("node3:27017")
myapp:PRIMARY> rs.add({_id: 3, host: "node3:27017", priority: 0, hidden: true})
也可通过配置文件的方式
删除节点
第一种方式
myapp:PRIMARY> rs.remove("node3:27017")
第二种方式
myapp:PRIMARY> cfg = rs.conf() | |
myapp:PRIMARY> cfg.members.splice(2,1) | |
myapp:PRIMARY> rs.reconfig(cfg) |
注:执行 rs.reconfig 并不必然带来副本集的重新选举,加 force 参数同样如此。
The rs.reconfig() shell method can trigger the current primary to step down in some situations.
修改节点的配置
将 Secondary 节点设置为延迟备份节点
cfg = rs.conf() | |
cfg.members[1].priority = 0 | |
cfg.members[1].hidden = true | |
cfg.members[1].slaveDelay = 3600 | |
rs.reconfig(cfg) |
将 Secondary 节点设置为隐藏节点
cfg = rs.conf() | |
cfg.members[0].priority = 0 | |
cfg.members[0].hidden = true | |
rs.reconfig(cfg) |
替换当前的副本集成员
cfg = rs.conf() | |
cfg.members[0].host = "mongo2.example.net" | |
rs.reconfig(cfg) |
设置副本集节点的优先级
cfg = rs.conf() | |
cfg.members[0].priority = 0.5 | |
cfg.members[1].priority = 2 | |
cfg.members[2].priority = 2 | |
rs.reconfig(cfg) |
优先级的有效取值是 0~1000,可为小数,默认为 1
从 MongoDB 3.2 开始
Non-voting members must have priority of 0. | |
Members with priority greater than 0 cannot have 0 votes. |
注:如果将当前 Secondary 节点的优先级设置的大于 Primary 节点的优先级,会导致当前 Primary 节点的退位。
阻止 Secondary 节点升级为 Primary 节点
只需将 priority 设置为 0
fg = rs.conf() | |
cfg.members[2].priority = 0 | |
rs.reconfig(cfg) |
如何设置没有投票权的 Secondary 节点
MongoDB 限制一个副本集最多只能拥有 50 个成员节点,其中,最多只有 7 个成员节点拥有投票权。
之所以作此限制,主要是考虑到心跳请求导致的网络流量,毕竟每个成员都要向其它所有成员发送心跳请求,和选举花费的时间。
从 MongoDB 3.2 开始,任何 priority 大于 0 的节点都不可将 votes 设置为 0
所以,对于没有投票权的 Secondary 节点,votes 和 priority 必须同时设置为 0
cfg = rs.conf() | |
cfg.members[3].votes = 0 | |
cfg.members[3].priority = 0 | |
cfg.members[4].votes = 0 | |
cfg.members[4].priority = 0 | |
rs.reconfig(cfg) |
禁用 chainingAllowed
默认情况下,允许级联复制。
即备份集中如果新添加了一个节点,这个节点很可能是从其中一个 Secondary 节点处进行复制,而不是从 Primary 节点处复制。
MongoDB 根据 ping 时间选择同步源,一个节点向另一个节点发送心跳请求,就可以得知心跳请求所耗费的时间。MongoDB 维护着不同节点间心跳请求的平均花费时间,选择同步源时,会选择一个离自己比较近而且数据比自己新的节点。
如何判断节点是从哪个节点处进行复制的呢?
myapp:PRIMARY> rs.status().members[1].syncingTo | |
node3:27018 |
当然,级联复制也有显而易见的缺点:复制链越长,将写操作复制到所有 Secondary 节点所花费的时间就越长。
可通过如下方式禁用
cfg=rs.conf() | |
cfg.settings.chainingAllowed=false | |
rs.reconfig(cfg) |
将 chainingAllowed 设置为 false 后,所有 Secondary 节点都会从 Primary 节点复制数据。
为 Secondary 节点显式指定复制源
rs.syncFrom("node3:27019")
禁止 Secondary 节点创建索引
有时,并不需要 Secondary 节点拥有和 Primary 节点相同的索引,譬如这个节点只是用来处理数据备份或者离线的批量任务。这个时候,就可以阻止 Secondary 节点创建索引。
在 MongoDB 3.4 版本中,不允许直接修改,只能在添加节点时显式指定
从上述测试中可以看出,如果要将节点的 buildIndexes 设置为 false,必须同时将 priority 设置为 0。
参考
1.《MongoDB 权威指南》PDF 下载见 http://www.linuxidc.com/Linux/2016-12/138253.htm
2. MongoDB 官方文档
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2017-05/143913.htm
