必须逐个替换CSRS节点,每次仅换一个且先Secondary后Primary;新节点须基于快照恢复、正确配置clusterRole和WiredTiger引擎,并确保rs.add()中votes=1、host可连、端口完整;待其进入SECONDARY且optime≤1s后,才可rs.remove旧节点。

必须逐个替换节点,且任意时刻至少保持 2 个可投票成员在线;否则 mongos 立即进入元数据只读状态,sh.moveChunk、sh.enableSharding 等操作全部静默失败。
为什么不能先 rs.remove() 再加新节点?
CSRS 是三节点副本集,法定人数(majority)为 2。若你执行 rs.remove("old:27019") 后,新节点尚未完成同步并进入 SECONDARY 状态,副本集就只剩 1 个可投票节点 —— 此时 mongos 拒绝所有元数据写入,不是延迟或重试问题,而是多数派硬性中断。
观察 rs.status().members[n].statestr 必须是 PRIMARY 或 SECONDARY;STARTUP2、RECOVERING、ROLLBACK 都不算可用。
-
optimeDate落后主节点 >5s 的节点,虽在副本集中但不参与 majority 计算 -
mongos默认每configServerHeartbeatFrequencyMS(默认 10 秒)发心跳,但只在满足 majority 时才刷新缓存 - 一旦 majority 中断,即使所有 shard 读写正常,分片管理已实质瘫痪
新节点启动前必须完成的四件事
新节点不能从空目录初始同步(太慢),必须基于可信快照快速构建状态。否则同步耗时过长,极易触发 majority 中断。
- 用
mongorestore --drop恢复最近一次完整的config库备份(含config.databases、config.chunks等集合) - 配置文件中明确设置:
clusterRole: configsvr(不是shardsvr,也不能留空) - 强制指定
storage.engine: wiredTiger(MongoDB 5.0+ 已弃用 MMAPv1,且 CSRS 强制要求 WiredTiger) - 确保
members[n].buildIndexes: false(CSRS 成员禁止建索引)
rs.add() 时哪些字段绝对不能错?
一个配置错误就会导致节点无法加入 majority,甚至被完全排除在副本集之外。
-
votes: 1必须设为 1(仲裁节点arbiterOnly: true在 CSRS 中不允许) -
priority建议 ≥ 0.5(避免因 priority=0 被永久排除在选举之外) -
host必须可被所有mongos和其他 CSRS 成员直连(注意防火墙、DNS、bindIp配置) - 不要在
rs.add()中遗漏端口(如"10.0.1.13:27019",不是"10.0.1.13")
替换顺序和验证关键点
替换必须按“从 Secondary 开始、最后动 Primary”的顺序进行;每次只换一个,且必须等新节点稳定后再操作下一个。
- 执行
rs.add({...})后,等待rs.status()显示该节点为SECONDARY且optimeDate与主节点差值 ≤1s - 再执行
rs.remove("old_host:port"),确认旧节点彻底消失且rs.status().members数量正确 - 每次替换后,用
sh.getBalancerState()和sh.status()检查集群元数据是否可写、分片状态是否一致 - 严禁在迁移过程中执行任何元数据变更操作(如
sh.addShard、sh.splitAt、创建新数据库等)
最易被忽略的是:新节点的 storage.engine 和 clusterRole 必须在启动前就配对正确 —— 启动后改配置需重启,而 CSRS 节点重启期间若掉出 majority,后果立现。











