mongodump不能直接用于分片集群一致性备份——因其不感知分片拓扑,无协调机制与全局快照锁,导致跨分片状态错位、chunk迁移漏文档、config与shard数据时间点不同步、oplog重放不匹配。

mongodump 不能直接用于分片集群一致性备份
直接用 mongodump --uri mongodb://mongos:27017/ 备份分片集群,结果几乎必然不一致——它只是把查询发给各 shard,没有协调机制,也不冻结状态。常见错误现象包括:恢复后 chunks 元数据错乱、部分文档丢失(尤其在 chunk 迁移中)、订单已写入但库存未扣减这类跨分片逻辑断裂。
根本原因在于 MongoDB 分片集群无全局事务时钟,mongodump 本身不提供跨节点快照隔离。即使加 --oplog,各 shard 的 oplog 截止时间也不同步,mongorestore --oplogReplay 会重放不匹配的变更。
实操建议:
- 不要在
mongos上执行带--oplog的mongodump——它只捕获 mongos 自身少量路由日志,**完全不包含任何 shard 的业务数据变更** - 若坚持用
mongodump,必须串行连接每个 shard 的primary节点(用--host显式指定),并记录每个 dump 的 oplogts字段,手动对齐恢复点 - config server 必须单独备份,且导出时间需与所有 shard 尽量接近;否则恢复时
shards、chunks集合与实际数据边界不匹配
文件系统快照是生产环境最可靠的一致性方案
真正能实现纳秒级时间点一致性的,只有存储层快照(如 LVM freeze、XFS xfs_freeze、云厂商 EBS 卷快照)。前提是:所有 shard 和 config server 的数据目录必须位于支持原子快照的同一存储卷或同步快照组中。
关键操作顺序不可颠倒:
- 先停 balancer:
sh.stopBalancer(),否则 chunk 迁移会导致快照内数据重复或缺失 - 再停写:通过应用层控制(推荐)或
db.fsyncLock()(4.2+ 已弃用,仅作备选) - 对所有节点(shard + config server)**同时**触发文件系统 freeze + 快照命令
- 快照完成后立即
db.fsyncUnlock()或释放应用写锁
注意:Amazon EBS RAID 10 配置下,无法保证多盘快照绝对一致,必须使用单卷或启用 EBS Multi-Attach + 一致性组。
Percona Backup for MongoDB(PBM)解决分布式快照协调问题
PBM 不是 mongodump 的包装器,而是通过副本集 oplog 时间戳 + config server 元数据快照,构造分布式一致性快照。它在底层调用 fsyncLock(5.0+ 更稳定),获取所有节点 oplog 最小 ts 作为逻辑快照时间点,并严格记录每个组件的 exactts。
恢复时硬性顺序必须遵守:
- 第一步:只恢复 config server,且必须用
pbm restore --restore-to-time <ts>,不能用mongorestore直接灌库 - 第二步:逐个恢复 shard,每个都连对应 shard 的
primary地址(不是mongos),并加--noIndexRestore - 第三步:全部 shard 数据导入完后,再统一建索引;启动 balancer 前,先
sh.startBalancer(),再手动sh.rebalanceCollection()
版本兼容性容易踩坑:pbm-agent 必须运行在每个 mongod 实例上(含 config server secondary),MongoDB 6.0+ 要求 config server 为副本集而非单节点。
恢复失败最常见的三个根源
68% 的分片集群恢复失败,源于以下任一环节出错:
- config server 恢复时没指定
--restore-to-time,导致元数据时间点与 shard 数据不匹配 - shard 恢复时连了
mongos而非本 shard 的primary,mongorestore写入被路由到错误分片 - 索引在数据导入中途重建,干扰 chunk 边界计算,后续
moveChunk失败甚至阻塞整个 balancer
真正难的不是备份动作本身,而是让 config server、所有 shard、oplog 片段三者在同一个逻辑时间点“定格”。任何试图绕过协调机制(比如靠“同时发起”或“加锁等待”)的方案,在高负载或网络抖动下都会失效。


















