必须先升级mongos,因其承担路由、聚合、事务协调等关键逻辑且协议层不兼容;低版本mongos连接高版本config server会报“Unsupported version”,连shard可能静默丢包;升级需逐台重启、验证sh.status()无警告,并确保Balancer已停用。

必须先升级 mongos,否则新 config server 或 shard 启动后,旧 mongos 会直接拒绝连接或静默丢包——这不是配置问题,是协议层不兼容。
为什么 mongos 必须第一个升
客户端所有请求都经过 mongos,它不存数据,但承担路由、聚合、事务协调等关键逻辑。从 MongoDB 6.0 起,clusterTime 格式、oplog 批量读取协议、writeConcern 校验逻辑都有变更。低版本 mongos 连接高版本 config server 时,常见报错是 Unsupported version;连高版本 shard 则可能无错误返回,但写入实际未落盘。
- 升级前查官方 Release Notes 中 “Compatibility” 表,确认当前
mongos版本 ≥ 目标config server和shard的最低兼容版本 - 逐台重启,不要批量停机;新旧
mongos可共存,但混用期间禁止执行sh.addShard()或sh.removeShard() - 验证命令:
sh.status()必须能完整返回分片拓扑,且无WARNING: mongos is older than config servers
升级 config server 前必须确认三节点副本集状态
4.2+ 版本强制要求 config server 是三成员副本集(csrs),单节点或两节点升级会触发 ConfigServerNotFound 错误,整个集群不可用。
- 执行
rs.status()确保三个节点状态均为PRIMARY或SECONDARY,不能有STARTUP、RECOVERING或ROLLBACK - 按
SECONDARY → PRIMARY顺序滚动升级:先关一个SECONDARY,替换二进制,启动;等其同步完成、stateStr变回SECONDARY后再操作下一个 - 最后对
PRIMARY执行rs.stepDown(30),等新PRIMARY完全接管后再升级原节点 - 升级后立刻运行
db.adminCommand({getCmdLineOpts: 1}),确认configsvr: true仍在配置中,且storage.engine没被意外重置(尤其避免 WiredTiger → MMAPv1)
升级 shard 副本集时必须停掉 Balancer
shard 升级过程中若发生 chunk 迁移,新旧版本对 moveChunk 协议理解不一致(如 7.0 加入了 writeConcern 强校验),会导致迁移卡住、sh.status() 显示 chunk(s) under migration,甚至元数据错乱。
- 升级前执行
sh.stopBalancer(),并轮询sh.getBalancerState()和sh.isBalancerRunning(),直到两者均返回false(可能需数分钟) - 每个
shard副本集内,同样按SECONDARY → ARBITER → PRIMARY顺序滚动升级;升级PRIMARY前必须先rs.stepDown() - 切勿在
writeConcern: {w: "majority"}场景下跳过stepDown—— 否则未同步完的 oplog 会被截断,造成数据丢失 - 每个
shard升级完成后,用db.runCommand({collStats: "any_collection"})验证能否正常访问数据,再继续下一节点
整个过程最易被忽略的是 mongos 兼容性检查和 Balancer 停止确认——它们不报错,但会让后续所有操作处于“看似成功、实则失效”的状态。升级不是换二进制那么简单,本质是协调多个组件在协议演进中的步调一致。


















