滚动升级前必须确认:1. sh.status() 中所有shard状态为OK且mongos连接数稳定;2. rs.status()中各副本集仅有一个PRIMARY且健康;3. 所有节点db.version()版本统一。

滚动升级前必须确认的 3 个分片组件状态
MongoDB 分片集群滚动升级不是简单地逐台重启,而是要严格按组件依赖顺序操作:先升级 mongos,再升级 config server(副本集模式下),最后升级 shard 副本集成员。任意跳步或并行升级都可能触发元数据不一致或路由失效。
执行前务必验证:
-
sh.status()输出中所有shard状态为OK,且mongos连接数稳定无激增 -
rs.status()在每个 config server 副本集和每个 shard 副本集中均显示"stateStr" : "PRIMARY"成员唯一且健康 - 所有节点
db.version()返回值统一(避免混用 6.0 和 7.0 的 config server)
mongos 升级为什么必须最先做且不能跨大版本?
mongos 是客户端流量入口,它对 config server 的协议兼容性极敏感。例如 6.0 的 mongos 无法解析 7.0 config server 写入的新格式 chunk 元数据,会导致分片路由失败、查询返回空结果或 OperationNotSupportedInTransaction 错误。
实操要点:
- 停掉旧
mongos进程后,必须用新二进制启动,并确认日志中出现Connected to config server at ...且无Failed to load config - 禁止从 5.0 直接升到 7.0:中间必须经过 6.0,因为 5.0
mongos不识别 6.0+ 引入的featureCompatibilityVersion (fCV)字段 - 升级期间客户端连接会短暂中断(通常 NetworkTimeout
shard 副本集滚动升级时 PRIMARY 切换的坑
单个 shard 是副本集,升级必须逐成员进行,但 PRIMARY 成员不能直接 kill -9 或 systemctl stop —— 这会触发一次不必要的选举,导致写入阻塞 10–30 秒,且新 PRIMARY 可能尚未加载完升级后的存储引擎参数。
安全做法是主动降级再升级:
- 对当前 PRIMARY 执行
rs.stepDown(30),等待其变为 SECONDARY(rs.status()中"stateStr"变更) - 确认新 PRIMARY 已完全接手写入(查看
rs.printSecondaryReplicationInfo()的延迟是否 - 再停掉原 PRIMARY 节点的
mongod,替换二进制,用相同配置启动;它将以 SECONDARY 身份加入,同步追平后再参与选举 - 切勿在
writeConcern: {w: "majority"}场景下跳过 stepDown —— 否则未同步完的 oplog 会被截断,造成数据丢失
fCV(featureCompatibilityVersion)什么时候设、设成啥?
fCV 不是升级时自动设置的,它控制的是“是否启用新版本特性”,必须在所有节点完成二进制升级后,由管理员显式执行。设早了(比如 config server 还没升完就设),会导致旧节点崩溃;设晚了(比如 shard 全升完但忘了设),新功能如 $merge on sharded collections 就不可用。
标准节奏:
- 全部
mongos和config server升级完成后,在任一mongos中执行db.adminCommand({setFeatureCompatibilityVersion: "7.0"}) - 等待该命令返回
"ok" : 1且 config server 日志出现Feature compatibility version updated to 7.0 - 最后才对每个 shard 副本集执行相同命令(必须逐个副本集执行,不能批量)
- 注意:一旦设为 7.0,就不能再降级回 6.0 集群,二进制可降,但数据目录不可逆
最常被忽略的是 config server 的 fCV 设置时机——它必须在所有 mongos 升完之后、任何 shard 升级之前完成,否则 shard 升级过程中会因元数据格式不匹配而拒绝加入集群。


















