修改priority需先赋值cfg=rs.conf()再改cfg.members[i].priority,递增cfg.version,调用rs.reconfig()后执行rs.stepDown(60)触发选举,priority=0节点仍同步数据但不参选。

改 priority 本身很简单,但改完不生效、改完报错、改完 Primary 没切换——这些才是真问题。关键不在“怎么输命令”,而在每一步的约束和副作用。
rs.conf() 返回的是只读对象,不能直接改成员 priority
很多人写 rs.conf().members[0].priority = 5,回车没报错,但 rs.reconfig() 后发现没变。因为 rs.conf() 返回的是副本集配置的快照,不是可修改引用。
- 必须先赋值给变量:
cfg = rs.conf() - 再通过索引定位并赋值:
cfg.members[1].priority = 2(注意索引从 0 开始,别数错) - 如果目标节点是隐藏节点或仲裁节点,确认它没被
hidden: true或arbiterOnly: true锁死逻辑——这两类节点默认priority: 0,强行改高也没用
rs.reconfig() 前必须手动递增 cfg.version
不加这步,90% 的失败都卡在这儿。MongoDB 会拒绝应用“版本号不大于当前”的配置,报错像 "new configuration not greater than current" 或静默忽略修改。
- 务必执行:
cfg.version = cfg.version + 1 - 不要用
cfg.version++,某些 shell 环境下可能不触发类型转换 - 如果副本集刚做过一次 reconfig,
cfg.version可能已是大整数,仍要 +1,不能设固定值
priority 改了,Primary 却没切换?那是你没触发选举
rs.reconfig() 只更新配置,不强制重新选举。只要原 Primary 还在线、健康、有投票权,它就继续当主节点。
- 想立刻让高优先级节点上位,得配合
rs.stepDown(60):让当前 Primary 主动退位,并禁选 60 秒 - 更激进可用:
db.adminCommand({replSetStepDown: 30, force: true}),强制降级且不等同步完成 - 千万别直接
db.shutdownServer()关 Primary——网络抖动时可能造成多数派失联,整个副本集不可写
priority=0 的节点不是“废节点”,而是有明确用途的
设成 0 不代表它退出集群,只是放弃参选资格。这类节点常用于读扩展、备份、延迟恢复等场景,但容易被误删或误配。
- priority 为 0 的节点仍参与 Oplog 复制,数据是实时同步的
- 客户端需显式设置
readPreference=secondary才能路由到它 - 如果同时设了
votes: 0,那它连投票权都没了——这种组合常见于备份专用节点,但要注意:非投票节点的priority必须为 0,反过来不成立 - PSA(Primary-Secondary-Arbiter)拓扑下,修改
votes可能触发拓扑校验失败,错误信息里会带"PSA topology"字样,需按文档分步调整
真正麻烦的从来不是改一个数字,而是改完之后——状态是否同步、version 是否递增、stepDown 是否及时、客户端读写路由是否适配。漏掉任意一环,都可能让高优先级变成摆设。

















