单个分片宕机不影响集群读写但需尽快恢复,否则迁移、分裂、均衡全部卡住且数据不可用;分片副本集全失联时需人工介入,操作顺序为停均衡器→清理残留chunk→removeShard→重建副本集→addShard→验证状态与孤儿chunk。

单个分片宕机不影响整个集群读写,但必须尽快恢复或替换——否则 chunk 迁移、split、balance 全部卡住,且该分片上数据彻底不可用。
分片副本集成员全部不可达时的直接表现
mongos 路由查询会报 ShardNotFound 或 FailedToSatisfyReadPreference;sh.status() 中对应分片显示 status: "DOWN";config server 的 config.shards 里该分片状态仍为 "up",但实际无法连接。
注意:只要不是所有副本集成员同时挂掉(比如只剩一个 secondary 还活着),MongoDB 通常能自动完成故障转移。真正要人工介入的是「整个分片副本集完全失联」的情况。
- 检查是否只是网络隔离:从 mongos 执行
db.runCommand({ping: 1})连目标分片地址,确认是服务未启、端口拒连,还是 DNS/防火墙问题 - 确认副本集状态:登录任一存活的分片节点,运行
rs.status(),看是否出现"stateStr": "STARTUP", "REMOVED", "UNKNOWN"等异常状态 - 别急着删节点:如果某个 secondary 因 oplog 断档太久被踢出,它可能还持有部分 chunk 数据,直接删成员会导致孤儿 chunk
分片副本集全部宕机后恢复的实操顺序
核心原则:先让 config server 认清“这个分片暂时不存在”,再重建或替换它,最后触发元数据同步。不能一边恢复分片一边跑 balance。
- 立即停均衡器:
sh.stopBalancer()—— 防止 mongos 在分片不可用期间反复尝试迁移 chunk,产生脏状态 - 检查并清理残留 chunk 记录:连 config server 主节点,查
config.chunks中属于该分片的 chunk 是否真实存在(db.getSiblingDB("config").chunks.find({"shard": "shard01"})),若返回为空,说明数据已丢失,需后续人工修复 - 更新分片注册信息:
sh.removeShard("shard01")—— 这个命令不会删数据,只从 config server 移除注册;执行后会提示剩余 chunk 数,若为 0 可直接确认移除;若非 0,说明还有 chunk 没迁走,得先手动 move 或等它恢复 - 重建分片:用原配置拉起新副本集,确保
replSet名称、host地址与之前一致(否则 config server 不认);启动后执行sh.addShard("shard01/xxx:27017")
恢复后必须验证的三个关键点
分片进程起来了不等于它被集群真正接纳。很多故障复发就发生在“以为恢复成功”之后。
- 确认 config server 已同步状态:查
config.shards,看"host"字段是否指向新节点地址,且"updatedAt"是最新时间戳 - 验证 chunk 分布:运行
sh.status(),重点看该分片的"jumbo chunks"是否为 0,以及"chunks"数量是否逐步回升(说明 balance 正在补分布) - 检查是否有孤儿 chunk:对每个曾属于该分片的库集合,执行
db.runCommand({cleanupOrphaned: "db.collection"})—— 尤其当分片曾短暂上线又崩溃过,本地可能残留未清理的_tmp_moveChunk_*文件
最容易被忽略的是 cleanupOrphaned 命令的执行范围:它只作用于指定集合,且要求你明确知道哪些集合曾落在故障分片上;如果靠 sh.status() 推断不准,建议结合 config.chunks 的 shard 字段做全量扫描。


















