4. 逻辑备份工具mongodump实战

mongodump 是 MongoDB 官方提供的逻辑备份工具,它通过读取集合中的文档并以 BSON 格式写入磁盘,形成一组 .bson 数据文件与 .metadata.json 元数据文件。与物理备份(如文件系统快照)不同,逻辑备份不依赖存储引擎的底层文件布局,因此可以在不同版本、不同部署形态之间迁移数据,也便于按库、按集合做精细化备份。本节围绕 mongodump 的三种典型备份粒度、压缩选项与查询过滤,以及 mongorestore 的对应恢复操作展开。

一、备份粒度:全实例、单库、单集合

mongodump 的粒度由参数组合决定,核心参数是 --uri(或 --host/--port)、--db 与 --collection。三者都不指定时,默认备份实例中所有数据库(全实例备份);只指定 --db 时备份单个数据库;同时指定 --db 与 --collection 时只备份单个集合。需要注意,--collection 必须与 --db 搭配使用,单独指定集合名不会生效。

# 全实例备份,输出到 /backup/full_20240601
mongodump --uri="mongodb://dba:pass@127.0.0.1:27017" \
  --out=/backup/full_20240601

# 单库备份:只备份 shop 库
mongodump --uri="mongodb://dba:pass@127.0.0.1:27017" \
  --db=shop --out=/backup/shop_20240601

# 单集合备份:只备份 shop.orders
mongodump --uri="mongodb://dba:pass@127.0.0.1:27017" \
  --db=shop --collection=orders --out=/backup/orders_20240601

输出目录结构遵循 out/<db>/<collection>.bson 与同名 .metadata.json 的约定。metadata 文件保存了集合的索引定义、选项(如分片键、校验规则),恢复时会据此重建索引。若只拷贝 bson 文件而丢失 metadata,恢复后集合将没有索引,这一点在手工搬运备份文件时极易被忽略。

二、压缩与查询过滤

默认情况下 mongodump 输出未压缩的 BSON,体积较大。使用 --gzip 可将每个集合输出为 .bson.gz,通常能获得 3~5 倍的压缩比,代价是备份与恢复时增加 CPU 开销。压缩后的文件在 mongorestore 时必须同样加 --gzip,否则会因无法识别文件格式而报错。

查询过滤通过 --query 实现,它接受一个 JSON 查询文档,只导出匹配的文档。例如只备份 2024 年 6 月之后的订单:

mongodump --uri="mongodb://dba:pass@127.0.0.1:27017" \
  --db=shop --collection=orders \
  --query='{"createdAt":{"$gte":{"$date":"2024-06-01T00:00:00Z"}}}' \
  --gzip --out=/backup/orders_recent

使用 --query 时要注意两点:一是查询条件中的日期需用 Extended JSON 的 $date 形式表达,直接写字符串可能匹配不到 BSON Date 类型;二是过滤只作用于文档,索引等元数据仍会完整导出。此外,--query 只能配合单集合使用,对全实例或整库备份无意义。

三、mongorestore 的对应恢复

mongorestore 的粒度控制与 mongodump 对称:--nsInclude 按命名空间过滤要恢复的集合,--nsExclude 排除指定命名空间,--db 可将数据恢复到另一个库名。恢复压缩备份必须加 --gzip。

# 恢复整个备份目录
mongorestore --uri="mongodb://dba:pass@127.0.0.1:27017" \
  /backup/full_20240601

# 只恢复 shop.orders,并重命名到 shop.orders_bak
mongorestore --uri="mongodb://dba:pass@127.0.0.1:27017" \
  --gzip --nsInclude="shop.orders" \
  --nsFrom="shop.orders" --nsTo="shop.orders_bak" \
  /backup/orders_recent

# 恢复到不同库:把 shop 库数据导入 shop_test
mongorestore --uri="mongodb://dba:pass@127.0.0.1:27017" \
  --nsFrom="shop.*" --nsTo="shop_test.*" \
  /backup/shop_20240601

恢复前建议先用 --dryRun 预演,它会解析备份文件并打印将要执行的操作而不真正写入,便于确认命名空间映射是否正确。默认情况下 mongorestore 遇到已存在的集合会追加文档而非覆盖;若希望先删除再恢复,需加 --drop。生产环境执行 --drop 前务必确认目标库,避免误删。

mongodump 备份粒度与 mongorestore 恢复映射 源 MongoDB 实例 shop 库 orders 集合 users 集合 (其他库略) mongodump 粒度 全实例:无 --db 单库:--db=shop 单集合:--db + --collection --query 仅单集合可用 备份产物(--out 目录) shop/orders.bson(.gz) + .metadata.json shop/users.bson(.gz) + .metadata.json --gzip 压缩,体积约降 3~5 倍 metadata 保存索引与集合选项 mongorestore 恢复映射 粒度过滤 --nsInclude="shop.orders" --nsExclude 排除命名空间 --gzip 对应压缩备份 命名空间重映射 --nsFrom="shop.orders" --nsTo="shop.orders_bak" --db 指定目标库 写入控制 --dryRun 预演不写入 --drop 先删后恢复 默认追加,不覆盖 读取备份

四、关键参数速查与常见误区

参数作用适用工具
--out指定备份输出目录mongodump
--db限定数据库两者
--collection限定集合,须配合 --dbmongodump
--queryJSON 查询过滤,仅单集合mongodump
--gzip压缩输出 / 读取压缩备份两者
--nsInclude按命名空间过滤恢复mongorestore
--nsFrom/--nsTo命名空间重映射mongorestore
--drop恢复前删除已有集合mongorestore
--dryRun预演,不实际写入mongorestore
常见误区:一是备份时用了 --gzip,恢复时忘记加,导致 mongorestore 报 "not a valid bson file";二是只复制了 .bson 而遗漏 .metadata.json,恢复后索引全部丢失;三是误以为 --query 能用于整库备份,实际它只对单集合生效;四是在生产库直接执行 --drop 恢复,未先做 --dryRun 确认目标命名空间。
实践建议:备份完成后立即用 mongorestore --dryRun 对备份目录做一次可读性校验,确认文件完整、命名空间符合预期;对重要库采用"全实例 + 单库"双份策略,全实例用于整体回滚,单库用于快速定点恢复。压缩备份在跨机房传输前可再叠加 tar 打包,进一步减少小文件数量。

掌握以上粒度、压缩与过滤参数后,mongodump 与 mongorestore 已能覆盖大多数逻辑备份场景。实际生产中还需结合备份窗口、磁盘容量与恢复时间目标(RTO)来选择合适的粒度与压缩策略,并将备份命令固化为可重复执行的脚本,配合校验与告警形成闭环。