mongodump --oplog 在分片集群上直接对mongos执行无效,因其仅捕获mongos自身路由元数据,不包含任何分片上的业务数据变更;各shard独立维护本地oplog.rs,必须分别连接每个shard primary显式执行mongodump --oplog并记录ts对齐恢复点。

mongodump --oplog 在分片集群上为什么无效
直接在 mongos 上执行 mongodump --oplog,**不会捕获任何业务数据变更**。因为分片集群没有全局 oplog,每个 shard 是独立副本集,oplog.rs 只存在于各 shard 的成员本地;mongos 自身的 oplog 仅记录路由元数据(如 chunk 拆分、迁移日志),不包含用户写入。
常见错误现象:mongorestore --oplogReplay 恢复后发现大量数据丢失或时间点不一致——根源就是备份时只抓了 mongos 的空 oplog。
- 必须显式连接到每个
shard的primary(或带--readPreference=secondary的secondary)单独执行mongodump --oplog -
--host参数必须指定具体节点地址(如shard1-primary:27017),不能用mongos地址代理 - 所有
shard的备份操作需严格串行,并记录每个 dump 输出中oplog.bson末尾的ts字段值,用于后续对齐恢复点
如何停写并锁定分片集群做全量一致性备份
从 MongoDB 7.0.2 / 6.0.11 / 5.0.22 起,db.fsyncLock() 已支持在 mongos 上调用,但仅适用于 WiredTiger 引擎且 journal 关闭——这在生产环境极不推荐。更稳妥的做法是应用层停写 + 停 balancer。
实操关键步骤:
- 先执行
sh.stopBalancer(),再用sh.getBalancerState()确认返回false - 确保无正在进行的 chunk 迁移(查
config.migrations集合为空)、无重分片、无集合创建/删除等 schema 操作 - 在业务低峰期协调应用停写(比依赖
fsyncLock更可靠,避免锁住整个集群导致超时失败) - 停写确认后,并行执行
mongodump备份所有shard和config server(注意:config server 必须单独备份,含config.chunks等关键元数据)
mongorestore 恢复分片集群时最常踩的坑
直接把某个 shard 的 dump 用 mongorestore 导回原集群,99% 会导致元数据错乱:chunk 边界失效、balancer 拒绝工作、查询返回空或重复数据。
正确恢复顺序不可颠倒:
- 先恢复
config数据库(含chunks、shards、databases、collections),目标必须是 config server 实例,且使用--drop - 再逐个恢复各
shard数据,每个shard必须连对应节点执行,不能走mongos - 若备份含
--oplog,恢复时加--oplogReplay,但必须确保所有shard的oplog截止ts对齐(否则跨分片事务状态不一致) - 恢复完成后,手动触发
sh.startBalancer(),并检查sh.status()中 chunk 分布是否合理
什么时候不该用 mongodump 做分片集群备份
当你的集群规模较大(比如 >50 个 shard)、写入压力高、或要求 RPO mongodump 基本不可行——串行 dump 所有 shard 耗时太长,停写窗口难协调,oplog 对齐误差易放大。
此时应切换方案:
- 云托管服务:阿里云 MongoDB 分片集群的“物理备份”、MongoDB Atlas 的 “Cluster-wide Snapshot”,底层用存储卷快照,天然一致
- 文件系统快照:停 balancer + 应用停写后,对所有
shard和config server数据目录同时打 LVM/XFS freeze 快照(注意加密引擎需加--eseDatabaseKeyRollover) - 企业级工具:MongoDB Ops Manager 或 Cloud Manager,通过持续拉取各
shard的oplog实现准实时备份
真正难的不是命令怎么敲,而是判断「此刻该不该用 mongodump」——它只适合中小规模、能接受分钟级停写、且无强一致 SLA 要求的场景。











