MongoDB 导出和导入完整指南
📦 数据导出 (Export)
1. mongodump (二进制备份)
bash
# 基本用法 - 导出整个数据库
mongodump --db=mydatabase --out=/backup/path
# 导出特定集合
mongodump --db=mydatabase --collection=users --out=./backup
# 带认证导出
mongodump --host localhost --port 27017 \
--username admin --password "password" \
--authenticationDatabase admin \
--db mydatabase \
--out=./backup
# 压缩导出(推荐用于大数据库)
mongodump --uri="mongodb://localhost:27017/mydatabase" \
--gzip \
--out=./backup_compressed
# 导出所有数据库
mongodump --uri="mongodb://localhost:27017" \
--out=./full_backup
# 导出时排除某些集合
mongodump --db=mydatabase \
--excludeCollection=sessions \
--excludeCollection=logs \
--out=./backup
# 导出查询结果
mongodump --db=mydatabase \
--collection=orders \
--query='{"status": "completed", "date": {"$gt": {"$date": "2024-01-01T00:00:00Z"}}}' \
--out=./backup
2. mongoexport (JSON/CSV格式)
bash
# 导出为JSON
mongoexport --db=mydatabase --collection=users --out=users.json
# 导出为CSV
mongoexport --db=mydatabase --collection=users \
--type=csv \
--fields=name,email,age,created_at \
--out=users.csv
# 带查询条件导出
mongoexport --db=mydatabase --collection=products \
--query='{"price": {"$gt": 100}, "inStock": true}' \
--out=expensive_products.json
# 导出特定字段
mongoexport --db=mydatabase --collection=users \
--fields=_id,name,email \
--out=users_basic.json
# 导出漂亮格式的JSON
mongoexport --db=mydatabase --collection=users \
--pretty \
--out=users_pretty.json
# 导出到标准输出
mongoexport --db=mydatabase --collection=users | gzip > users.json.gz
📥 数据导入 (Import)
1. mongorestore (恢复二进制备份)
bash
# 恢复整个数据库
mongorestore --db=mydatabase ./backup/mydatabase/
# 恢复特定集合
mongorestore --db=mydatabase \
--collection=users \
./backup/mydatabase/users.bson
# 恢复压缩备份
mongorestore --gzip --db=mydatabase ./backup_compressed/mydatabase/
# 恢复时保留原数据(默认会删除现有数据)
mongorestore --db=mydatabase --drop ./backup/mydatabase/
# 恢复时重命名数据库
mongorestore --db=newdatabase ./backup/mydatabase/
# 恢复单个集合
mongorestore --db=mydatabase \
--nsFrom="olddb.users" \
--nsTo="mydatabase.users" \
./backup/olddb/users.bson
# 并行恢复(加速大数据库恢复)
mongorestore --numParallelCollections=4 \
--db=mydatabase \
./backup/mydatabase/
2. mongoimport (导入JSON/CSV)
bash
# 导入JSON文件
mongoimport --db=mydatabase --collection=users --file=users.json
# 导入CSV文件
mongoimport --db=mydatabase --collection=users \
--type=csv \
--headerline \
--file=users.csv
# 导入时指定字段
mongoimport --db=mydatabase --collection=users \
--type=csv \
--fields=name,email,age \
--file=users.csv
# 导入并删除原有数据
mongoimport --db=mydatabase --collection=users \
--drop \
--file=users.json
# 导入时忽略重复键错误
mongoimport --db=mydatabase --collection=users \
--stopOnError \
--file=users.json
# 分批导入
mongoimport --db=mydatabase --collection=users \
--batchSize=1000 \
--numInsertionWorkers=4 \
--file=users.json
# 导入时处理日期格式
mongoimport --db=mydatabase --collection=logs \
--columnsHaveTypes \
--fields="timestamp.date(2006-01-02 15:04:05),message.string()" \
--file=logs.csv
🔄 完整导出导入流程示例
场景1:迁移数据库到新服务器
bash
# 1. 在源服务器导出
mongodump --uri="mongodb://source:27017/production" \
--gzip \
--out=./mongobackup
# 2. 压缩备份文件
tar -czf mongobackup.tar.gz mongobackup/
# 3. 传输到目标服务器
scp mongobackup.tar.gz user@target-server:/tmp/
# 4. 在目标服务器恢复
tar -xzf /tmp/mongobackup.tar.gz
mongorestore --uri="mongodb://target:27017/production" \
--gzip \
./mongobackup/production/
场景2:导出为CSV,修改后导入
bash
# 1. 导出为CSV
mongoexport --db=sales --collection=orders \
--type=csv \
--fields=order_id,customer,amount,date \
--out=orders.csv
# 2. 使用Excel或脚本修改CSV文件
# ... 修改数据 ...
# 3. 导入修改后的数据
mongoimport --db=sales --collection=orders_modified \
--type=csv \
--headerline \
--file=orders_modified.csv
场景3:备份和恢复特定时间点的数据
bash
# 创建带时间戳的备份
BACKUP_DIR="/backups/mongodb/$(date +%Y%m%d_%H%M%S)"
mongodump --db=importantdb --out="$BACKUP_DIR"
# 列出所有备份
ls -la /backups/mongodb/
# 恢复到特定备份
mongorestore --db=importantdb \
"/backups/mongodb/20240115_143022/importantdb"
⚡ 性能优化技巧
导出优化
bash
# 并行导出多个集合
mongodump --db=largedb \
--numParallelCollections=8 \
--out=./backup
# 使用更快的压缩
mongodump --db=largedb \
--gzip \
--archive=backup.gz \
--quiet # 减少日志输出
导入优化
bash
# 禁用索引构建(导入后再创建)
mongorestore --db=largedb \
--noIndexRestore \
./backup/largedb/
# 之后手动创建索引
mongosh --eval "db.getSiblingDB('largedb').getCollection('users').createIndex({email: 1})"
# 批量插入优化
mongoimport --db=largedb --collection=users \
--batchSize=10000 \
--numInsertionWorkers=8 \
--file=users.json
🛡️ 安全注意事项
bash
# 使用SSL连接
mongodump --uri="mongodb+srv://username:password@cluster.mongodb.net/db" \
--ssl \
--out=./backup
# 从配置文件读取凭证(避免密码暴露在命令行)
# 创建配置文件 backup.conf
echo '
uri = mongodb://admin:password@localhost:27017
ssl = true
authenticationDatabase = admin
' > backup.conf
mongodump --config=backup.conf --out=./backup
📊 导出导入统计信息
bash
# 导出前查看数据大小
mongosh --eval "
db = db.getSiblingDB('mydatabase');
const stats = db.stats();
print('Database size:', stats.dataSize);
print('Collections:', stats.collections);
"
# 导入后验证数据
mongosh --eval "
db = db.getSiblingDB('mydatabase');
print('Total documents:', db.users.countDocuments());
print('Sample document:', JSON.stringify(db.users.findOne()));
"
🔧 常见问题解决
问题1:ObjectId 转换错误
bash
# 导出时转换ObjectId为字符串
mongoexport --db=mydb --collection=users \
--jsonFormat=canonical \
--out=users.json
# 或使用--legacy格式
mongoexport --db=mydb --collection=users \
--legacy \
--out=users.json
问题2:大文件导入导出
bash
# 分片导出大集合
mongodump --db=mydb --collection=huge_collection \
--query='{"_id": {"$lt": ObjectId("65a1b2c3d4e5f67890123456")}}' \
--out=./part1
# 使用split分割文件
mongoexport --db=mydb --collection=users \
--out=users.json
split -l 100000 users.json users_part_
# 并行导入分片文件
for file in users_part_*; do
mongoimport --db=mydb --collection=users --file="$file" &
done
wait
问题3:版本兼容性
bash
# 导出时指定兼容版本
mongodump --db=mydb \
--compatibilityVersion=4.4 \
--out=./backup
# 查看工具版本
mongodump --version
mongorestore --version
🎯 最佳实践
- 始终在非高峰时段执行大规模导出导入
- 先导出到本地磁盘,再传输到目标
- 验证导出完整性:检查文档数量和文件大小
- 测试恢复流程:定期演练恢复过程
- 使用--gzip压缩:减少传输时间和存储空间
- 记录操作日志:保存所有导出导入命令
- 监控性能影响:使用mongostat监控服务器负载
📝 快速参考表
| 操作 | 命令 | 用途 |
|---|---|---|
| 导出整个DB | mongodump --db=mydb --out=./backup |
二进制备份 |
| 导出为JSON | mongoexport --db=mydb --collection=users --out=users.json |
可读格式 |
| 导出为CSV | mongoexport --db=mydb --collection=users --type=csv --fields=name,email |
表格格式 |
| 恢复DB | mongorestore --db=mydb ./backup/mydb/ |
从备份恢复 |
| 导入JSON | mongoimport --db=mydb --collection=users --file=users.json |
导入JSON |
| 导入CSV | mongoimport --db=mydb --collection=users --type=csv --headerline |
导入CSV |
| 压缩导出 | mongodump --gzip --db=mydb --out=./backup |
节省空间 |
| 并行操作 | --numParallelCollections=4 |
提高速度 |
这个指南涵盖了大多数导出导入场景,根据你的具体需求选择合适的工具和参数即可。
🔍 mongorestore --db=hsrg ./backup导入错误分析
当你使用 mongodump 备份时,它会创建以下结构:
./backup/
└── hsrg/ # 数据库文件夹
├── collection1.bson
├── collection1.metadata.json
└── collection2.bson
但你的 mongorestore 命令指向的是 ./backup 目录,而不是 ./backup/hsrg。
✅ 解决方案
方案1:指定正确的路径
bash
# 正确写法(指定到数据库文件夹)
mongorestore --db=hsrg ./backup/hsrg/
# 或者
mongorestore ./backup/hsrg/
方案2:使用新语法(推荐)
bash
# 使用新的 --nsInclude 语法
mongorestore --nsInclude="hsrg.*" ./backup/
# 或者恢复整个备份目录中的所有数据库
mongorestore ./backup/
📝 正确的完整流程示例
导出时:
bash
# 导出 hsrg 数据库
mongodump --db=hsrg --out=./backup
# 查看导出结果
ls -la ./backup/
# 应该能看到 hsrg 目录
导入时:
bash
# 方法1:直接恢复整个备份目录
mongorestore ./backup/
# 方法2:只恢复 hsrg 数据库到新数据库名
mongorestore --nsFrom="hsrg.*" --nsTo="newhsrg.*" ./backup/
# 方法3:使用新语法
mongorestore --nsInclude="hsrg.*" ./backup/
如果你需要覆盖现有数据:
bash
# 先删除现有数据再恢复
mongorestore --drop --db=hsrg ./backup/hsrg/
🔧 验证备份结构
bash
# 先查看备份目录结构
tree ./backup/
# 或者
ls -R ./backup/
# 示例输出应该类似于:
# ./backup/
# └── hsrg
# ├── users.bson
# ├── users.metadata.json
# ├── products.bson
# └── products.metadata.json
⚠️ 常见错误及解决
错误1:备份文件在错误的位置
bash
# 如果备份文件直接在 backup 目录下,而不是 backup/hsrg 下
# 需要调整目录结构
mkdir -p ./backup/hsrg
mv ./backup/*.bson ./backup/*.metadata.json ./backup/hsrg/ 2>/dev/null || true
mongorestore ./backup/
错误2:权限问题
bash
# 检查文件权限
ls -la ./backup/hsrg/
# 如果有权限问题
chmod -R 755 ./backup/
错误3:版本不兼容
bash
# 检查 MongoDB 版本
mongorestore --version
mongodump --version
# 如果版本不匹配,使用兼容模式
mongorestore --db=hsrg ./backup/hsrg/ --noIndexRestore
🎯 一键修复脚本
bash
#!/bin/bash
# fix_mongorestore.sh
BACKUP_DIR="./backup"
DB_NAME="hsrg"
# 检查备份目录是否存在
if [ ! -d "$BACKUP_DIR" ]; then
echo "错误:备份目录 $BACKUP_DIR 不存在"
exit 1
fi
# 检查数据库目录是否存在
if [ -d "$BACKUP_DIR/$DB_NAME" ]; then
echo "检测到正确的目录结构,开始恢复..."
mongorestore --db="$DB_NAME" "$BACKUP_DIR/$DB_NAME/"
elif [ -f "$BACKUP_DIR/$DB_NAME.bson" ]; then
echo "检测到旧格式备份,调整目录结构..."
mkdir -p "$BACKUP_DIR/$DB_NAME"
mv "$BACKUP_DIR/$DB_NAME".* "$BACKUP_DIR/$DB_NAME/" 2>/dev/null
mongorestore --db="$DB_NAME" "$BACKUP_DIR/$DB_NAME/"
else
echo "错误:无法识别的备份结构"
echo "目录内容:"
ls -la "$BACKUP_DIR"
exit 1
fi
📊 总结
你的问题是因为:
- 备份目录结构不对
mongorestore路径指定错误
正确的命令应该是:
bash
# 先查看备份目录内容
ls -la ./backup/
# 如果看到 hsrg 目录
mongorestore --db=hsrg ./backup/hsrg/
# 或者直接用新语法
mongorestore ./backup/
全文总结
bash
# 导出
mongodump --db=hsrg --out=./backup
#导入
mongorestore --db=hsrg ./backup/hsrg/
## 重点
为什么导入的路径多个hsrg,是因为导出的时候携带有表名称