config server全挂≠集群完全不可用,因mongos缓存路由表可继续转发读写请求;但元数据更新操作全部失败,需按序恢复config副本集并手动执行flushRouterConfig刷新缓存。

配置服务器全部宕机后,分片集群元数据立即变为只读,config.shards、config.chunks等关键集合无法写入,均衡器自动停摆,新 chunk 迁移和拆分全部冻结——但业务读写仍可继续,前提是 mongos 路由缓存未过期且目标分片在线。
为什么 config server 全挂 ≠ 集群完全不可用
mongos 启动时会从 config server 拉取一份完整元数据快照并缓存在内存中;只要不重启 mongos,它仍能根据已有路由表转发请求。这意味着:
- 已存在的 chunk 分布信息有效,
find、insert、update等常规操作照常执行 - 如果某个分片本身也宕了,对应数据才真正不可访问;config server 故障本身不阻断数据面通信
- 但任何需要更新元数据的操作都会失败:比如
sh.splitAt()、sh.moveChunk()、添加新分片、修改片键等 - mongos 缓存有 TTL(默认 300 秒),超时后若 config server 仍未恢复,mongos 将拒绝新连接或返回路由错误
抢修必须按顺序启动三个 config server 成员
config server 必须以副本集方式部署,且三节点需全部在线才能写入元数据。任意一个成员缺失,选举无法达成多数派,主节点无法产生,config 数据库保持只读状态。抢修要点:
- 先确认三个 config server 的
mongod进程是否真的全部停止,还是仅网络不通(检查netstat -tulnp | grep :27019或对应端口) - 若进程已死,逐个启动:必须先启动原主节点(或任一能提供最新 oplog 的节点),再依次启动其余两个,确保它们能通过复制追上
- 启动命令必须带
--configsvr和正确的--replSet名称,例如:mongod --configsvr --replSet configRepl --dbpath /data/configdb --port 27019 - 启动后连上任一 config server,运行
rs.status(),确认状态为"stateStr" : "PRIMARY"且其他成员"health" : 1
config server 恢复后必须手动触发元数据同步
即使三个节点都起来了,mongos 不会自动重新拉取 config 数据——它只在启动时加载一次。必须强制刷新路由缓存:
- 对每个正在运行的
mongos实例,连接其admin数据库,执行:db.runCommand({flushRouterConfig: 1}) - 该命令立即清空本地路由缓存,并从 config server 重新加载全量元数据
- 执行后立刻检查:
sh.status()应能正常输出,sh.getBalancerState()应可读取,且不再报not master或config server unavailable - 若某 mongos 执行失败,说明它尚未连上可用 config 主节点,需检查其
--configdb参数指向是否正确(应为configRepl/hostname1:27019,hostname2:27019,hostname3:27019)
最易被忽略的致命细节:config server 副本集初始化状态
如果三个 config server 同时宕机时间过长(比如超过 oplog 回滚窗口),重启后可能出现两个节点无法加入副本集、或初始化失败的问题。此时 rs.status() 显示 "stateStr" : "STARTUP2" 卡住不动。根本原因不是数据损坏,而是副本集尚未完成初始化握手。必须人工干预:
- 连上其中一个 config server(非 mongos),在
admin数据库下执行:rs.initiate() - 注意:仅当整个副本集无任何历史配置时才用此命令;若曾成功初始化过,应使用
rs.reconfig()强制重载已有配置 - 配置内容需严格匹配原始
rs.conf():_id、members[n].host、members[n].priority、members[n].votes一个都不能错,否则后续 mongos 无法认证 - 一旦副本集状态恢复正常,立刻执行
db.runCommand({flushRouterConfig: 1}),否则 mongos 仍认为 config 不可用

















