分片集群文件系统快照备份必须严格控制写入、平衡器和密钥状态,否则导致数据不一致或损坏;需先停均衡器、同步锁库、优先备份配置服务器,再快照各分片,恢复时须按序启动config server和分片并验证元数据一致性。

分片集群用文件系统快照做备份,不是“能做就行”,而是必须严格控制写入、平衡器和密钥状态——否则备份要么不一致,要么恢复后数据损坏。
为什么不能直接对运行中的分片集群打快照
分片集群里数据分布在多个分片上,且块(chunk)会动态迁移。如果没停负载均衡器,快照期间某个 chunk 正在从 shard A 迁移到 shard B,就可能在 A 和 B 上都留下部分数据,导致备份里出现重复或缺失;更隐蔽的问题是:配置服务器(config server)的元数据快照时间点和各分片不一致,恢复后 mongos 根本无法正确路由查询。
- 必须执行
sh.stopBalancer(),并确认返回true且sh.getBalancerState()为false - 必须对所有分片 + 配置服务器同时停止写入,仅靠
db.fsyncLock()不够——它只锁单节点,得在每个mongod实例上分别执行 - 若集群启用了加密存储引擎(AES256-GCM),冷快照恢复时必须加
--eseDatabaseKeyRollover启动参数,否则 IV 重用会破坏数据完整性
实际操作顺序不能颠倒
顺序错一步,备份就失去原子性。尤其注意:配置数据库的备份必须在分片快照之前完成,因为它是整个集群的“地图”。
- 先连到任意
mongos,运行sh.stopBalancer(),再用sh.isBalancerRunning()确认已停 - 逐个登录每个分片主节点和 config server 主节点,执行
db.fsyncLock()——注意不是fsync命令行工具,是 shell 里的方法 - 立刻备份 config server 数据目录(通常是
/data/configdb),这是后续恢复的锚点 - 再对每个分片的数据目录(如
/data/shard0)发起文件系统快照(LVM / ZFS / EBS snapshot 等) - 全部快照完成后,逐个执行
db.fsyncUnlock(),最后用sh.startBalancer()恢复均衡
快照恢复时最容易忽略的三个点
恢复不是把文件拷回去重启就完事。分片集群的拓扑信息、chunk 分布、oplog 位点全依赖 config server 和各分片间状态同步。
- 必须先恢复 config server,启动并确认其状态正常(
rs.status()显示 PRIMARY),再启动分片 - 分片启动时若检测到 config server 版本不匹配或元数据校验失败,会拒绝加入集群——此时需检查 config server 快照是否完整,以及是否误用了旧快照
- 恢复后首次连接
mongos时,务必运行sh.status(),重点看chunks数量是否与备份前一致,balancer是否自动重启;如果卡在 “waiting for chunks to become consistent”,说明某分片数据与 config server 元数据不匹配
真正麻烦的从来不是快照本身,而是跨多节点的状态同步窗口——哪怕只差几百毫秒,就足以让 config server 记录了迁移开始,而某个分片还没写完迁移日志。所以别信“近似一致”,要备份就得按秒级协调停写、锁库、拍快照。











