Config Server 全部宕机后,mongos 会立即进入元数据只读状态:无法执行分片管理命令,但普通读写不受影响,需手动刷新路由配置或等待心跳恢复。

Config Server 全部宕机后,mongos 会立即进入元数据只读状态
只要所有 config server(即 CSRS 模式下的三个副本)都不可达,mongos 就无法刷新或更新集群元数据缓存。此时它不会报错退出,而是“静默降级”:后续所有涉及分片变更的操作(如 sh.moveChunk、sh.addShard、sh.enableSharding)全部拒绝,错误提示类似 "failed to refresh metadata: config server is unreachable"。
但读写普通集合不受影响——只要路由信息还在缓存里,mongos 仍能正确转发请求到对应 shard。这意味着业务查询和写入照常,只是你再也动不了分片结构了。
- 缓存有效期默认是 30 秒(由
refreshLogicalSessionCacheRefreshPeriodMS和元数据 TTL 共同影响),超时后若 config server 仍未恢复,mongos会停止接受任何需要元数据的操作 - 已有连接的
mongos不会自动重连 config server,需手动重启或等待其后台心跳失败后触发降级逻辑 - 如果你用的是旧版 SCCC 模式(已弃用),宕机直接导致整个集群不可用,但当前主流 CSRS 模式下至少保住了数据面
元数据不可变 ≠ 集群不可用,但所有 sharding 管理命令都会卡住或失败
一旦元数据只读,sh.status() 还能执行(返回缓存快照),但 sh.splitAt()、sh.migrateChunk()、sh.removeShard() 这类命令会阻塞数秒后报错:"cannot acquire global lock for metadata write" 或更直白的 "config server is not available"。
关键点在于:这些操作不是“排队等恢复”,而是被 mongos 主动拦截。它不尝试重试,也不降级为本地执行——因为分片元数据必须强一致,不能靠 shard 自行协商。
-
sh.moveChunk失败后,chunk 位置不会回滚,但也不会继续迁移;原位置数据仍可读写,只是负载不均衡问题被冻结 - 新数据库/集合启用分片(
sh.enableSharding("db"))会失败,且不会留下半截状态;下次重试仍需 config server 在线 - 即使你手动改了 config 数据库(比如直连 config server 副本集 Primary 写入),
mongos也不会主动拉取——它只信任自己维护的缓存版本号
恢复 config server 后,mongos 不会自动同步,得靠人工干预或自然心跳
config server 恢复在线后,mongos 并不会立刻重新加载元数据。它依赖后台心跳检测 config server 可用性,然后触发一次全量刷新。这个过程通常在 1–2 分钟内完成,但取决于配置项 configServerHeartbeatFrequencyMS(默认 10 秒)和网络延迟。
如果等不及,可以强制刷新:db.adminCommand({ "flushRouterConfig": 1 })。注意这不是热重载——它清空本地缓存并立即向 config server 发起新请求,若此时 config server 还没完全同步(比如刚从故障中恢复,oplog 落后),可能拿到过期元数据。
- 执行
flushRouterConfig后,所有正在运行的mongos实例都需要单独调用,它不广播 - 如果 config server 副本集发生主从切换,而
mongos还连着旧 Primary 的地址(比如 DNS 缓存未更新),也会表现为“config server 不可用”,此时要检查mongos的 configDB 连接字符串是否用了副本集名称而非单点地址 - 日志里搜
"refreshing metadata from config server"可确认刷新是否成功,失败则会带具体 socket 错误
真正危险的是 config server 数据损坏,而非短暂宕机
短时间宕机顶多造成管理停滞;但如果 config server 中的 config.databases、config.collections 或 config.chunks 出现数据不一致或损坏(比如人为误删 chunk 记录、手动修改了 version 字段),mongos 恢复后加载的元数据就会出错——轻则路由错乱(请求发到错误 shard),重则整个分片集群拒绝服务。
这种损坏无法靠重启修复,必须从备份恢复 config 数据库,且要求备份时间点早于损坏发生时刻。MongoDB 官方明确不支持对 config 数据库做在线修改,所有变更必须走 sh 系列命令。
- 定期导出 config 库(
mongodump --host "cfgReplSet/config.example.com:27019" -d config -o ./config-backup)比依赖 oplog 更可靠 - 监控项里必须包含
config server的replSetGetStatus成员状态、oplog 延迟、以及mongos日志中元数据刷新失败频率 - 别给 config server 开启
enableMajorityReadConcern以外的读关注——否则某些查询可能读到未提交的中间状态










