引言
MongoDB 作为最流行的 NoSQL 数据库之一,广泛应用于游戏、电商、物联网等场景。与关系型数据库不同,MongoDB 的备份恢复工具 mongodump 和 mongorestore 提供了灵活的数据导出导入能力。本文将详细介绍 MongoDB 的备份策略、恢复流程,以及如何编写自动化脚本实现定时备份、自动恢复和服务重启的完整运维方案。
MongoDB 备份恢复工具对比
| 工具 |
用途 |
输出格式 |
适用场景 |
mongodump |
逻辑备份 |
BSON 文件 |
全库/单库/单集合备份 |
mongorestore |
逻辑恢复 |
BSON 文件 |
从 mongodump 备份恢复 |
mongoexport |
导出数据 |
JSON/CSV |
数据迁移、分析 |
mongoimport |
导入数据 |
JSON/CSV |
初始化数据导入 |
| 文件系统快照 |
物理备份 |
原始文件 |
大型部署,需停机 |
mongodump 备份详解
基础用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| mongodump --host localhost --port 27017 --out /data/backup/
mongodump --db mygame --out /data/backup/
mongodump --db mygame --collection players --out /data/backup/
mongodump --host 192.168.1.100 \ --username admin \ --password mypassword \ --authenticationDatabase admin \ --db mygame \ --out /data/backup/
|
常用参数说明
| 参数 |
说明 |
示例 |
--host |
MongoDB 服务器地址 |
--host 192.168.1.100 |
--port |
端口号 |
--port 27017 |
--username |
用户名 |
--username admin |
--password |
密码 |
--password pass |
--authenticationDatabase |
认证数据库 |
--authenticationDatabase admin |
--db |
指定数据库 |
--db mygame |
--collection |
指定集合 |
--collection users |
--out |
输出目录 |
--out /data/backup/ |
--gzip |
压缩备份 |
--gzip |
压缩备份
对于大型数据库,建议启用压缩以节省磁盘空间:
1 2
| mongodump --db mygame --gzip --out /data/backup/
|
mongorestore 恢复详解
基础用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| mongorestore /data/backup/
mongorestore --db mygame /data/backup/mygame/
mongorestore --db mygame --drop /data/backup/mygame/
mongorestore --host 192.168.1.100 \ --username admin \ --password mypassword \ --authenticationDatabase admin \ --db mygame \ /data/backup/mygame/
|
常用参数说明
| 参数 |
说明 |
--db |
指定目标数据库 |
--collection |
指定目标集合 |
--drop |
恢复前删除目标集合 |
--gzip |
读取压缩的备份文件 |
--noIndexRestore |
不恢复索引 |
--noOptionsRestore |
不恢复集合选项 |
自动化备份脚本
完整备份恢复脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| #!/bin/bash
DB_HOST="192.168.1.100" DB_USER="admin" DB_PASS="your_password" AUTH_DB="admin" SOURCE_DB="SuperMan_8" TARGET_DB="SuperMan_78" BACKUP_DIR="/data/db/dumps/mongodb" SERVER_DIR="/data/nodejs/mygame" SERVER_SCRIPT="game-api.sh"
YMDAY=$(date +%Y-%m-%d-%H-%M-%S) BACKUP_PATH="${BACKUP_DIR}/${SOURCE_DB}_${YMDAY}"
echo "========================================" echo "MongoDB 备份恢复自动化脚本" echo "开始时间: $(date)" echo "========================================"
echo "[1/5] 创建备份目录..." mkdir -p "${BACKUP_DIR}"
echo "[2/5] 备份数据库 ${SOURCE_DB}..." mongodump --host "${DB_HOST}" \ --username "${DB_USER}" \ --password "${DB_PASS}" \ --authenticationDatabase "${AUTH_DB}" \ --db "${SOURCE_DB}" \ --out "${BACKUP_PATH}"
if [ $? -ne 0 ]; then echo "备份失败,退出脚本" exit 1 fi
echo "备份完成: ${BACKUP_PATH}"
echo "[3/5] 删除目标数据库 ${TARGET_DB}..." mongo "${TARGET_DB}" --eval "db.dropDatabase()"
if [ $? -ne 0 ]; then echo "删除数据库失败,退出脚本" exit 1 fi
echo "[4/5] 恢复数据库到 ${TARGET_DB}..." mongorestore --db "${TARGET_DB}" \ --dir "${BACKUP_PATH}/${SOURCE_DB}"
if [ $? -ne 0 ]; then echo "恢复失败,退出脚本" exit 1 fi
echo "[5/5] 重启应用服务..." cd "${SERVER_DIR}" || exit sh "${SERVER_SCRIPT}"
echo "========================================" echo "操作完成时间: $(date)" echo "备份路径: ${BACKUP_PATH}" echo "========================================"
|
定时自动备份
使用 crontab 定时备份
1 2 3 4 5 6 7 8 9
| crontab -e
0 2 * * * /data/scripts/mongo_daily_backup.sh >> /var/log/mongo_backup.log 2>&1
0 3 * * 0 /data/scripts/mongo_weekly_cleanup.sh >> /var/log/mongo_cleanup.log 2>&1
|
| 定时规则 |
说明 |
0 2 * * * |
每天凌晨 2:00 |
0 */6 * * * |
每 6 小时一次 |
0 3 * * 0 |
每周日凌晨 3:00 |
带清理策略的备份脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #!/bin/bash
DB_HOST="localhost" DB_USER="admin" DB_PASS="your_password" AUTH_DB="admin" DB_NAME="mygame" BACKUP_BASE="/data/db/dumps/mongodb" RETENTION_DAYS=7
YMDAY=$(date +%Y-%m-%d) BACKUP_DIR="${BACKUP_BASE}/${DB_NAME}_${YMDAY}"
mkdir -p "${BACKUP_BASE}" mongodump --host "${DB_HOST}" \ --username "${DB_USER}" \ --password "${DB_PASS}" \ --authenticationDatabase "${AUTH_DB}" \ --db "${DB_NAME}" \ --gzip \ --out "${BACKUP_DIR}"
if [ $? -eq 0 ]; then echo "[$(date)] 备份成功: ${BACKUP_DIR}"
find "${BACKUP_BASE}" -maxdepth 1 -type d \ -name "${DB_NAME}_*" \ -mtime +${RETENTION_DAYS} \ -exec rm -rf {} +
echo "[$(date)] 已清理 ${RETENTION_DAYS} 天前的备份" else echo "[$(date)] 备份失败" exit 1 fi
|
备份验证与恢复演练
验证备份完整性
1 2 3 4 5 6 7 8
| du -sh /data/backup/mygame_2024-01-01/
find /data/backup/mygame_2024-01-01/ -name "*.bson" | wc -l
bsondump --objcheck /data/backup/mygame_2024-01-01/mygame/players.bson
|
恢复到测试环境验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| mongo test_restore --eval "db.dropDatabase()"
mongorestore --db test_restore /data/backup/mygame_2024-01-01/mygame/
mongo test_restore --eval " var collections = db.getCollectionNames(); for (var i = 0; i < collections.length; i++) { var count = db[collections[i]].count(); print(collections[i] + ': ' + count + ' documents'); } "
mongo test_restore --eval "db.dropDatabase()"
|
生产环境备份策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| ┌─────────────────────────────────────────────────────────────────────┐ │ MongoDB 生产环境备份策略 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 备份层级: │ │ │ │ Level 1:每日增量逻辑备份(mongodump --oplog) │ │ ───────────────────────────────────── │ │ • 每天凌晨 2:00 执行 │ │ • 保留 7 天 │ │ • 使用 --gzip 压缩 │ │ │ │ Level 2:每周全量物理备份(文件系统快照) │ │ ───────────────────────────────────── │ │ • 每周日凌晨 3:00 执行 │ │ • 保留 4 周 │ │ • 使用 LVM 快照或云盘快照 │ │ │ │ Level 3:跨区域远程备份 │ │ ───────────────────────────────────── │ │ • 每日同步到异地存储(OSS/S3) │ │ • 保留 30 天 │ │ │ │ 恢复演练: │ │ • 每月在测试环境执行一次恢复演练 │ │ • 验证备份可用性和恢复时间(RTO) │ │ │ └─────────────────────────────────────────────────────────────────────┘
|
| 备份类型 |
工具 |
频率 |
保留期 |
RTO |
| 逻辑全量 |
mongodump |
每日 |
7 天 |
分钟级 |
| 物理快照 |
文件系统 |
每周 |
4 周 |
秒级 |
| 异地备份 |
rsync/OSS |
每日 |
30 天 |
小时级 |
常见问题排查
问题一:认证失败
1 2 3 4 5
| Failed: error connecting to db server: server returned error on SASL authentication step
mongodump --username admin --password pass --authenticationDatabase admin --db mygame
|
问题二:磁盘空间不足
1 2 3 4 5 6 7 8
| df -h
mongodump --db mygame --gzip --out /data/backup/
find /data/backup/ -mtime +7 -delete
|
问题三:恢复后索引丢失
1 2 3 4 5 6
| mongorestore --db mygame --noIndexRestore /data/backup/mygame/
db.players.createIndex({ "playerId": 1 }, { unique: true }) db.players.createIndex({ "lastLogin": -1 })
|
总结
MongoDB 备份恢复的核心要点:
- 工具选择:
mongodump/mongorestore 适合逻辑备份,mongoexport/mongoimport 适合数据迁移
- 认证参数:生产环境务必使用
--authenticationDatabase admin 指定认证库
- 自动化:通过 Shell 脚本 + crontab 实现定时备份,配合清理策略控制磁盘占用
- 压缩存储:大型数据库使用
--gzip 参数压缩,可节省 70% 以上磁盘空间
- 恢复演练:定期进行恢复演练,验证备份可用性,确保灾难恢复能力
- 分层备份:结合逻辑备份、物理快照和异地备份,构建多层次的数据保护体系
通过系统化的备份策略和自动化脚本,可以确保 MongoDB 数据的安全性和业务的连续性。