必须连接Primary节点执行rs.reconfig(),Secondary不接受配置变更;修改priority需深拷贝配置、递增version、确保priority与votes匹配,并配合rs.stepDown()触发选举。

连哪个节点执行 rs.reconfig() 才有效
必须连到当前 Primary 节点执行,否则 rs.reconfig() 会直接报 NotMaster 错误。Secondary 节点不接受配置变更请求,这点和读写权限无关,是副本集协议强制要求。
常见错误现象:在 Secondary 上运行 cfg = rs.conf() 看起来成功了,但后续 rs.reconfig(cfg) 失败——不是因为配置错,而是根本没连对节点。
确认方式很简单:rs.isMaster().ismaster 返回 true 才算对;或者直接看 shell 提示符,比如 myRepl:PRIMARY>。
修改 priority 前必须深拷贝并递增 version
rs.conf() 返回的是只读对象,不能原地改 cfg.members[0].priority = 5 就完事。MongoDB 会静默忽略或在 rs.reconfig() 时拒绝应用,报错如 "new configuration not greater than current"。
正确做法是:
- 用
cfg = rs.conf()拿到配置 - 手动定位目标成员(别硬记索引,用
cfg.members.find(m => m.host === "node2:27017")更可靠) - 赋值:比如
cfg.members[1].priority = 3 - 必须加一:
cfg.version = cfg.version + 1(少这步 100% 失败)
priority 取值范围是 0 到 1000 的浮点数,默认是 1;设为 0 表示永不参选,但依然参与复制、可读(需客户端配 readPreference=secondary)。
改完 priority 为什么 Primary 没切换
因为 rs.reconfig() 本身不触发选举。它只是更新配置,现有 Primary 只要健康在线,就会继续服役——哪怕你刚把另一个节点的 priority 调到了 10。
想立刻让高优先级节点上位,得配合 rs.stepDown():
- 在当前 Primary 上执行
rs.stepDown(60),让它主动退位并禁选 60 秒,给新节点留出窗口 - 或者更激进:
db.adminCommand({replSetStepDown: 30, force: true}),强制降级且不等同步进度 - 千万别直接
db.shutdownServer()关 Primary,网络抖动时可能引发多数派失联,整个副本集不可写
注意:如果目标节点 optime 落后超过 10 秒,即使 priority 最高,Primary 也不会自动 stepDown,这是 MongoDB 防脑裂的保护机制。
priority 和 votes 必须匹配,否则 reconfig 会失败
priority > 0 的节点,votes 字段必须为 1;反过来,votes: 0 的节点,priority 必须是 0。违反这个约束,rs.reconfig() 会报校验错误。
典型踩坑场景:
- 想把一个
hidden: true节点调高 priority 来做灾备主,但忘了它默认votes: 0 - 副本集已有 7 个投票节点(上限),再试图给第 8 个节点设
priority=1,会失败 - 一次
rs.reconfig()不能同时改多个节点的votes,得拆成多次操作
检查方式:rs.conf().members[n] 里看 votes 和 priority 是否满足上述互锁关系。不匹配就先调 votes,再调 priority。











