MongoDB 备份恢复与自动化运维完全指南:mongodump、mongorestore 与定时任务实战

引言

MongoDB 作为最流行的 NoSQL 数据库之一,广泛应用于游戏、电商、物联网等场景。与关系型数据库不同,MongoDB 的备份恢复工具 mongodumpmongorestore 提供了灵活的数据导出导入能力。本文将详细介绍 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/
# 输出目录下将生成 .bson.gz 文件

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
# mongo_backup_restore.sh
# MongoDB 自动备份、恢复并重启服务

# 配置参数
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 "========================================"

# 1. 创建备份目录
echo "[1/5] 创建备份目录..."
mkdir -p "${BACKUP_DIR}"

# 2. 备份数据库
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}"

# 3. 删除目标数据库
echo "[3/5] 删除目标数据库 ${TARGET_DB}..."
mongo "${TARGET_DB}" --eval "db.dropDatabase()"

if [ $? -ne 0 ]; then
echo "删除数据库失败,退出脚本"
exit 1
fi

# 4. 恢复数据库
echo "[4/5] 恢复数据库到 ${TARGET_DB}..."
mongorestore --db "${TARGET_DB}" \
--dir "${BACKUP_PATH}/${SOURCE_DB}"

if [ $? -ne 0 ]; then
echo "恢复失败,退出脚本"
exit 1
fi

# 5. 重启应用服务
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

# 添加以下行
# 每天凌晨 2 点执行备份
0 2 * * * /data/scripts/mongo_daily_backup.sh >> /var/log/mongo_backup.log 2>&1

# 每周日凌晨 3 点执行完整备份并清理旧备份
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
# mongo_daily_backup.sh
# 每日备份并自动清理 7 天前的旧备份

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

# 查看 bson 文件信息
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
# 1. 在测试 MongoDB 实例上创建测试数据库
mongo test_restore --eval "db.dropDatabase()"

# 2. 恢复备份到测试数据库
mongorestore --db test_restore /data/backup/mygame_2024-01-01/mygame/

# 3. 验证数据完整性
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');
}
"

# 4. 清理测试数据库
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
# 使用 --noIndexRestore 跳过索引恢复后手动重建
mongorestore --db mygame --noIndexRestore /data/backup/mygame/

# 在 mongo shell 中重建索引
db.players.createIndex({ "playerId": 1 }, { unique: true })
db.players.createIndex({ "lastLogin": -1 })

总结

MongoDB 备份恢复的核心要点:

  1. 工具选择mongodump/mongorestore 适合逻辑备份,mongoexport/mongoimport 适合数据迁移
  2. 认证参数:生产环境务必使用 --authenticationDatabase admin 指定认证库
  3. 自动化:通过 Shell 脚本 + crontab 实现定时备份,配合清理策略控制磁盘占用
  4. 压缩存储:大型数据库使用 --gzip 参数压缩,可节省 70% 以上磁盘空间
  5. 恢复演练:定期进行恢复演练,验证备份可用性,确保灾难恢复能力
  6. 分层备份:结合逻辑备份、物理快照和异地备份,构建多层次的数据保护体系

通过系统化的备份策略和自动化脚本,可以确保 MongoDB 数据的安全性和业务的连续性。