
直接上手mongodump 和 mongorestore 备份恢复实战做 MongoDB 运维和开发早晚会遇到数据备份和迁移的需求。可能是测试环境要复制一份生产数据做联调可能是某个集合被人手抖删了要恢复也可能是换机房要整体搬迁。这时候最常用的两个工具就是 mongodump 和 mongorestore。我最初用这两个工具的时候也是只看命令能跑就行后来在好几次数据恢复场景中踩了坑才逐渐把各种参数、场景和坑摸透。这篇文章就把我实际使用中的经验完整梳理一遍从基础命令到高级参数从常见恢复到排错技巧尽量做到拿来就能用。如果你刚接触 MongoDB或者已经用过但没深入研究过 mongodump 和 mongorestore这篇内容都适合你。我用的 MongoDB 版本是 4.4 和 5.0但文中的逻辑和大部分参数在 3.6 之后都是通用的。1. mongodump 和 mongorestore 到底是什么1.1 工具定位备份恢复工具的核心价值mongodump 是 MongoDB 官方自带的逻辑备份工具它不直接拷贝数据库文件而是通过访问 MongoDB 服务把数据以 BSON 格式导出到磁盘。mongorestore 则是反向操作把 mongodump 导出的数据重新写回 MongoDB。这里有个关键认知它俩是逻辑备份不是物理备份。物理备份是直接复制 mongo 数据目录底下的文件逻辑备份是通过查询接口把数据读出来再写成文件。两者适用场景差别很大。逻辑备份的优点很明显备份文件是标准的、可解析的 BSON/JSON 结构能做到精确到某个集合甚至某个文档可以在不同版本、不同平台之间迁移数据可以通过参数过滤指定的查询条件。缺点也客观存在备份速度比物理拷贝慢尤其是数据量大的时候恢复时逐条插入文档效率相对低。所以我要先给一个明确的产品定位mongodump mongorestore 最适合的场景是中小型数据库的日常备份、开发测试环境的数据同步、跨版本的逻辑迁移、误删数据后的快速恢复。如果你的数据库已经到 TB 级别或者对恢复时间要求是分钟级那应该考虑文件系统快照或复制集定期全量oplog 增量方案而不是死抱着 mongodump。1.2 与 mongoexport/mongoimport 的区别很多人容易把这几兄弟搞混。mongodump/mongorestore 是一对mongoexport/mongoimport 是另一对。mongodump 导出的是 BSON 格式的二进制文件包含完整的 BSON 类型信息比如 Date、ObjectId、Decimal128 这些类型都能完整保留。mongoexport 导出的是 JSON 或 CSV 格式JSON 虽然也是基于 BSON 转换的但某些类型转换后会丢失精度或者变成字符串特别是日期类型和 Decimal128 这种精度敏感的数值类型。我自己碰到过一个真实案例某团队用 mongoexport 导出数据再导到另一个环境结果发现价格字段的小数精度变了当时排查了半天才意识到是 JSON 导出惹的祸。从那以后凡是涉及完整数据的备份迁移我都默认用 mongodump只有给别人出报表、需要导入其他分析工具的时候才用 mongoexport 导出 CSV。一句话总结mongodump/mongorestore 是备份恢复的正规军 mongoexport/mongoimport 更适合数据交换和临时格式转换。2. mongodump 实战从基础命令到完整备份方案2.1 环境准备与第一步备份mongodump 是跟着 MongoDB 数据库一起安装的不需要单独部署。如果是自己本机折腾安装 MongoDB 之后bin 目录下就有 mongodump 和 mongorestore 两个可执行文件。最简单的用法mongodump --host 127.0.0.1 --port 27017这条命令会连接本机的 MongoDB 实例默认把所有数据库都导出到当前目录下的 dump 文件夹。注意默认不包含 local 库因为 local 库是副本集内部使用的备份它没有意义。如果你只想备份某一个数据库mongodump --host 127.0.0.1 --port 27017 --db myapp导出完成后目录结构大概是这样的dump/ └── myapp/ ├── users.bson ├── users.metadata.json ├── orders.bson └── orders.metadata.json每个集合对应两个文件.bson 文件存储数据.metadata.json 文件存储集合的索引信息和选项配置。恢复的时候mongorestore 会先根据 metadata.json 创建集合和索引再导入数据。这个细节很多人会忽略但很重要因为它决定了 mongodump 导出的索引信息能不能带过去。2.2 核心参数清单与选择逻辑以下是我高频使用的参数每个都标注了使用场景参数作用我的使用场景--host/--port指定连接地址和端口连接远程实例时必用-u/-p用户名密码认证启用了认证的环境--authenticationDatabase认证库用户建在 admin 库时必须指定--db指定数据库只备份单个库时--collection指定集合只备份某个表时--query导出符合条件的文档增量备份、按条件筛选--gzip压缩 BSON 文件减少磁盘占用--archive输出到归档文件远程传输、整体打包--out指定输出目录改变默认位置--readPreference读偏好备份从节点降低主库压力特别说明一下--archive参数。普通模式导出的是目录加散文件如果用--archive可以直接输出成单个归档文件方便用管道直接传输到别的机器。比如备份到远程服务器mongodump --archive /backup/backup.archive mongorestore --archive /backup/backup.archive这样省去了打包解包的操作步骤而且归档文件可以和 --gzip 结合压缩传输一步搞定。2.3 认证连接的那些坑MongoDB 开认证之后mongodump 连接就需要注意参数配合。最常见的错误是只写了用户名密码没写认证数据库。正确做法mongodump --host 10.0.0.5 --port 27017 \ -u backup_user -p 密码 \ --authenticationDatabase admin \ --db myapp \ --out /data/backup我见过不少同学把--authenticationDatabase admin这一项省略结果报Authentication failed。原因很简单MongoDB 需要知道用户的身份信息存在哪个库。如果用户是在 admin 库创建的就必须指定 admin如果是在某个业务库里创建的就指定那个业务库。另一个坑是密码中包含特殊字符。命令行直接传密码的情况下、#、$这些符号可能被 Shell 解释导致连接失败或者密码错误。我的做法是优先使用环境变量方式export MONGODB_PASSWORD复杂密码 mongodump --username backup_user --password $MONGODB_PASSWORD --authenticationDatabase admin或者干脆用 MongoDB 的连接串形式配合--urimongodump --uri mongodb://backup_user:复杂密码10.0.0.5:27017/admin?authSourceadmin -d myapp但连接串里的密码同样需要做 URL 编码特殊字符较多时反而容易出错所以环境变量方式最稳妥。2.4 用 --query 做增量备份的思路mongodump 不是天然的增量备份工具但只要数据里有时间字段就可以手动构造一个近似增量的备份。核心思路是用--query参数导出指定时间范围的数据配合一个记录上次备份时间点的游标。比如你的 orders 集合里有 create_time 字段上次备份到 2025-05-01 00:00:00那这次的增量备份命令就是mongodump --db shop --collection orders \ --query {create_time: {$gte: ISODate(2025-05-01T00:00:00Z)}} \ --out /data/backup/incremental注意--query后面跟的是 JSON 过滤器但里面可以用ISODate()函数辅助构造日期对象。这个参数在命令行里传的时候引号处理很容易出问题。我建议用单引号包 JSON里面再用双引号这样 Shell 不会做变量展开。增量备份有个前提要搞清楚这种方式只适合追加型数据。如果业务里有大量更新已有的文档--query只按 create_time 过滤是抓不到更新的需要额外处理 update_time 字段把条件改成{$or: [{create_time: ...}, {update_time: ...}]}。但这样又可能产生重复文档恢复时需要用 mongorestore 的 upsert 参数避免重复插入。所以对我来说增量方案在实战中一般用于日志类追加数据核心业务表还是全量备份更稳妥。3. mongorestore 实战三种恢复模式全解析3.1 恢复模式一完整恢复最直接的使用方式就是把 mongodump 导出的 dump 目录整个导回去mongorestore --host 127.0.0.1 --port 27017 /data/backup/dump不指定--db的情况下mongorestore 会按照 dump 目录原有的库名、集合名原样恢复。注意目录路径是 dump 文件夹本身不要带上一层也不要只指到某个库目录除非你就是想恢复那一个库。有个细节mongorestore 默认不会删除目标库里已经存在的集合。也就是说如果目标库已经有一个 users 集合mongorestore 会尝试往这个集合里继续插入数据。假如目标集合里已有相同 _id 的文档默认会报duplicate key error然后跳过该文档。这很容易造成恢复出来的数据不完整。如果你希望恢复成一个干净状态我一般会先手动删掉目标库再执行 mongorestoremongo --eval db.getSiblingDB(myapp).dropDatabase() mongorestore --db myapp /data/backup/dump/myappdropDatabase是删数据最快的命令没有之一。文件系统快照级别删除都没有它快因为它直接删文件。3.2 恢复模式二指定库/集合恢复mongorestore 也支持只恢复某个库或某个集合。恢复单个数据库mongorestore --db myapp /data/backup/dump/myapp恢复单个集合mongorestore --db myapp --collection users /data/backup/dump/myapp/users.bson注意恢复单个集合的时候一定要同时指定--db和--collection而且路径要直接指到 .bson 文件不是目录。我在实际使用中发现一个容易混淆的地方--db参数在 mongodump 里是导出哪个库在 mongorestore 里是导入到哪个库两边是对应的。如果 mongorestore 不带--db它会从 dump 目录结构里自动推断库名如果带了--db那目录就随便命名只按照库名的对应关系导入。这种灵活性在实际操作中很有用。比如我从生产库 myapp 导出数据但想恢复到测试环境的 myapp_dev 库可以这样mongorestore --db myapp_dev /data/backup/dump/myapp命令不复杂但确确实实解决了环境隔离的问题。我在理想状态下开发环境和生产环境应该用不同的库名避免误操作连错库。3.3 恢复模式三归档流式恢复前面提到--archive参数恢复时对应使用mongorestore --archive/data/backup/backup.archive归档模式下mongorestore 不需要知道目录结构因为归档文件内部就包含完整的库集合信息。如果还想对归档内容做检查也可以配合--gzip解压mongorestore --archive/data/backup/backup.archive.gz --gzip这种模式特别适合跨机器传输的场景。我之前帮某团队做迁移生产库在机房 A测试库在机房 B网络带宽一般。直接备份目录再传输既占流量又容易漏文件。用mongodump --archive --gzip先压缩再传输文件大小能缩小很多网络传输的压力小多了。3.4 恢复时如何单集合插入刚才说了恢复单集合最好用--db--collection指定。但还有一个细节需要关注metadata.json 文件是否存在于目标位置。如果只给你一个单独导出的 orders.bson 文件没有对应的 metadata.json直接用它恢复的时候索引信息就丢了。有时候这是好事比如你希望只恢复数据索引自己手动建但更多时候是麻烦因为你会丢失原本精心设计的索引。解决方案让 mongorestore 帮您重建集合的基础结构。其实 mongorestore 在处理单个 bson 文件时如果发现目标集合不存在会默认创建集合。索引丢失就得靠另一道防线导出时尽量保留整个集合目录而不是只拿 .bson 文件。我在实际项目中会把导出后的完整目录打包存储这样任何时候恢复都能带索引。4. 常见问题与排查技巧实录4.1 版本兼容性跨版本迁移要注意什么MongoDB 社区有一个常见现象用新版本导出的数据往旧版本导回大概率出问题。反过来旧版本导出的往新版本导基本没问题因为新版本兼容旧格式的 BSON 和集合选项。我在 5.0 上执行的 mongodump尝试把数据恢复到 4.0 的实例时就遇到过报错。解决思路有两个要么升级目标库要么用目标库版本的 mongodump 工具重新导出。更稳妥的做法是做跨版本迁移之前先查看两边的版本号确认兼容关系再操作。如果确实需要从高版本往低版本迁我一般会先在中间版本导出一次再逐级导到目标版本虽然笨但可靠。检查版本的方法:mongod --version mongo --eval db.version()4.2 认证失败和连接超时报错排查先说认证失败。如果报Authentication failed按这个顺序排查用户名、密码是否写对密码有没有被 Shell 转义掉--authenticationDatabase是否正确用户在当前库有没有读写权限MongoDB 是否真的启用了认证db.runCommand({connectionStatus: 1})可以查看当前连接的用户信息再说连接超时。mongodump 默认连接超时时间比较短如果目标实例在网络另一头可能要加--connectTimeoutMS参数mongodump --host 10.0.0.5 --port 27017 --connectTimeoutMS 60000如果备份过程中断,可能是数据量大导致的。这时可以开启--verbose模式看详细输出确认卡在哪个集合上。4.3 恢复太慢怎么办性能优化路子mongorestore 导入数据的时候默认不是用批量插入它一行一行解析 BSON 并插入。数据量大时这个速度很难看。实测下来几十 GB 的数据量用默认参数恢复到本地也要半小时以上如果目标库是远程的还要更慢。常见的优化手段在这操作参数/做法效果批量插入加大--batchSize减小网络往返提高吞吐关掉自动索引--noIndexRestore数据先导完再补索引避免建索引卡住指定主副本指向 primary 或者配置合理的 readPreference写操作直接到主节点少一次路由并行恢复多个 mongorestore 进程不同集合利用多核 CPU我最常用的组合是mongorestore --host 127.0.0.1 --port 27017 --db myapp \ --noIndexRestore --batchSize 5000 \ /data/backup/dump/myapp等数据导入完成后再手动操作创建索引。这样做的好处是导入阶段不会被建索引的耗时卡住全过程耗时明显缩短。代价是要记得补索引所以我会把创建的索引语句单独存成一个脚本恢复流程跑完就执行脚本不用心记。有一种情况不建议你用--noIndexRestore数据量不大但业务马上要用且索引本身很复杂的情况。直接恢复带索引虽然慢一点点但恢复结束就能直接无障碍查询省得后面再排查缺索引的调用问题。实操中的选择标准就是数据量100 GB 以上推荐分两步小数据量直接恢复就好。4.4 关于副本集和分片集群的备份恢复如果你的 MongoDB 是副本集架构mongodump 连接时建议指定--readPreferencesecondaryPreferred优先读从节点避免备份流量把主节点压垮mongodump --host 副本集名/节点1地址,节点2地址 --readPreferencesecondaryPreferred这个方法实测效果明显尤其是每天定时备份的服务器配合从节点做备份几乎是标配方案。需要注意连接串里节点地址写多个时要用逗号分隔主机名或 IP 要与副本集配置一致。如果是分片集群mongodump 理论上可以做全量备份但恢复时要把每个分片的库集合分别恢复到对应分片非常麻烦。我基本上不推荐在分片集群环境用 mongodump 作为主要备份手段更合理的方案是结合集群特性做物理备份、快照或者统一归档。如果你只为了救某一个库那倒可以直接从 mongos 上 mongodump 特定库恢复时再导入。4.5 实战自查清单最后整理一份我在每次备份恢复前后都会过一遍的检查清单贴在下面用电脑做数据恢复前最好核对一下备份前确认 mongodump 版本和数据库版本匹配备份前确认认证参数正确避免跑了一半报错备份后检查 dump 目录大小和源库统计信息对比备份后抽查几个集合的文档数确认没有漏数据恢复前确认目标库可写、没有同名集合干扰恢复前backup 的归档文件完整性检查恢复后检查索引数量、关键集合文档数、字段类型是否正确恢复后用几条已知数据做校验查询这套清单救了我很多次。尤其是抽查文档数这一条某次备份脚本里--query条件写错了导致导出的数据少了一个月的记录如果没做文档数对比就继续往下走后面恢复出来的业务数据会缺一大块排查起来非常痛苦。还有一个容易被忽视的问题mongodump 备份过程中如果源库有大量写操作可能导致备份出来的数据在时间点上不一致。应对方法就是尽量在业务低峰期执行全量备份或者在副本集上指定从节点去读最小化对业务的影响。5. 几个我踩过且值得记下来的经验备份恢复工具就是这样平时安安静静关键时刻就靠它的可靠性。我自己的习惯是每套环境都必须有一个可以一键执行的备份脚本而且一定要定期做恢复演练。只是备份成功不代表能恢复成功这话听起来像废话但太多人栽在这上面没注意。另外备份文件一定要放到独立的存储介质或远程目录避免和数据库在同块磁盘上机器宕了备份跟着一起没了就麻烦大了。如果你也正在做 MongoDB 的备份恢复方案我个人建议先把 mongodump 和 mongorestore 的通用逻辑吃透再结合自己的业务量评估合适策略。对于绝大多数中小型项目这套工具完全够用而且官方维护、兼容性好不用担心第三方工具的维护问题。最后再分享一个小技巧在备份完成后顺手把生成的 dump 目录打个包并附带一份备份时间和版本的说明文件。这样三个月后你从存储里翻出这份备份时才知道它能恢复到什么时间点、适用于什么版本的 MongoDB省去了很多额外摸索的时间。