第十二章:备份与恢复

最后更新: 2024-01-01 作者: MongoDB Team
页面目录

第十二章:备份与恢复

MongoDB 数据备份与恢复策略

12.1 备份策略概述

┌─────────────────────────────────────────────────────────────────┐
│                      备份方法对比                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  方法            │ 备份时间  │ 恢复时间  │ 数据一致性 │ 资源开销  │
│  ─────────────┼──────────┼──────────┼──────────┼─────────  │
│  mongodump     │ 慢       │ 慢       │ 低       │ 低        │
│  文件系统快照   │ 快       │ 快       │ 高       │ 中        │
│  Ops Manager   │ 中       │ 中       │ 高       │ 高        │
│  Atlas Backup  │ 快       │ 快       │ 高       │ 云服务     │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

12.2 mongodump 和 mongorestore

基本备份

# 基本备份(所有数据库)
mongodump --uri="mongodb://admin:password@localhost:27017" --out=/backup/dump

# 备份单个数据库
mongodump --uri="mongodb://admin:password@localhost:27017" \
  --db=mydb \
  --out=/backup/dump

# 备份单个集合
mongodump --uri="mongodb://admin:password@localhost:27017" \
  --db=mydb \
  --collection=users \
  --out=/backup/dump

# 带认证的备份
mongodump --host localhost --port 27017 \
  --username admin --password password \
  --authenticationDatabase admin \
  --out=/backup/dump

备份选项

# 压缩备份
mongodump --uri="mongodb://localhost:27017" \
  --out=/backup/dump \
  --gzip

# 备份指定时间点之前的数据
mongodump --uri="mongodb://localhost:27017" \
  --out=/backup/dump \
  --query='{"created_at": {"$lt": {"$date": "2024-01-01T00:00:00Z"}}}'

# 备份并包含索引定义
mongodump --uri="mongodb://localhost:27017" \
  --db=mydb \
  --dumpDbUserAndRoles

# 并行备份(多个线程)
mongodump --uri="mongodb://localhost:27017" \
  --numParallelCollections=4

基本恢复

# 基本恢复(所有数据库)
mongorestore --uri="mongodb://admin:password@localhost:27017" \
  /backup/dump

# 恢复单个数据库
mongorestore --uri="mongodb://admin:password@localhost:27017" \
  --db=mydb \
  /backup/dump/mydb

# 恢复单个集合
mongorestore --uri="mongodb://admin:password@localhost:27017" \
  --db=mydb \
  --collection=users \
  /backup/dump/mydb/users.bson

# 解压恢复
mongorestore --uri="mongodb://localhost:27017" \
  --gzip \
  /backup/dump

恢复选项

# 恢复前删除目标集合
mongorestore --uri="mongodb://localhost:27017" \
  --drop \
  /backup/dump

# 仅恢复索引(不恢复数据)
mongorestore --uri="mongodb://localhost:27017" \
  --restoreDbUsersAndRoles \
  --noIndexRestore

# 恢复并重命名目标数据库
mongorestore --uri="mongodb://localhost:27017" \
  --nsFrom="mydb" \
  --nsTo="mydb_restored" \
  /backup/dump/mydb

# dry run(预览恢复操作)
mongorestore --uri="mongodb://localhost:27017" \
  --dryRun \
  /backup/dump

12.3 文件系统快照

LVM 快照备份

# 创建 LVM 快照
sudo lvcreate --size 10G --snapshot --name mongodb_snap /dev/vg00/lv_mongodb

# 挂载快照
sudo mkdir -p /mnt/snapshot
sudo mount /dev/vg00/mongodb_snap /mnt/snapshot

# 从快照恢复数据
sudo mongorestore --dbpath=/mnt/snapshot/data \
  --drop \
  /mnt/snapshot/data

# 删除快照
sudo umount /mnt/snapshot
sudo lvremove /dev/vg00/mongodb_snap

云存储快照

# AWS EBS 快照
aws ec2 create-snapshot \
  --volume-id vol-12345678 \
  --description "MongoDB backup $(date +%Y-%m-%d)"

# Google Cloud 快照
gcloud compute disks snapshot disk-name \
  --snapshot-names=mongodb-backup

# Azure 快照
az snapshot create \
  --name mongodb-backup \
  --disk-name disk-name

12.4 副本集备份

Oplog 备份

// 创建带 Oplog 的备份
// 1. 查看当前 Oplog 位置
use local
db.oplog.rs.find().sort({ ts: -1 }).limit(1)

// 2. 备份
mongodump --uri="mongodb://localhost:27017" \
  --dumpDbUserAndRoles \
  --authenticationDatabase admin \
  --out=/backup/full

// 3. 备份 Oplog
mongodump --uri="mongodb://localhost:27017" \
  --db=local \
  --collection=oplog.rs \
  --out=/backup/oplog

// 4. 恢复到指定时间点
mongorestore --uri="mongodb://localhost:27017" \
  --oplogReplay \
  --oplogFile=/backup/oplog/local/oplog.rs.bson \
  /backup/full

时间点恢复

# 恢复到指定时间点
mongorestore --uri="mongodb://localhost:27017" \
  --oplogReplay \
  --oplogFile=/backup/oplog/local/oplog.rs.bson \
  --pointInTimeRecovery \
  --pointInTimeRecoveryUTCMillis=1704067200000 \
  /backup/full

12.5 分片集群备份

备份策略

# 1. 停止平衡器
mongo mongos:27017/admin --eval 'sh.stopBalancer()'

# 2. 备份 Config Server
mongodump --host config1 --port 27017 \
  --out=/backup/config

# 3. 备份每个 Shard(副本集主节点)
mongodump --host shard1-primary:27017 \
  --out=/backup/shard1

mongodump --host shard2-primary:27017 \
  --out=/backup/shard2

# 4. 重启平衡器
mongo mongos:27017/admin --eval 'sh.startBalancer()'

分片集群恢复

# 1. 恢复 Config Server
mongorestore --host config1 --port 27017 \
  /backup/config

# 2. 恢复 Shard 数据
mongorestore --host shard1-primary:27017 \
  /backup/shard1

mongorestore --host shard2-primary:27017 \
  /backup/shard2

# 3. 验证集群状态
mongo mongos:27017/admin --eval 'sh.status()'

12.6 自动备份脚本

每日备份脚本

#!/bin/bash
# backup.sh

set -e

# 配置
BACKUP_DIR="/backup/mongodb"
DATE=$(date +%Y%m%d_%H%M%S)
MONGODB_URI="mongodb://admin:password@localhost:27017"
RETENTION_DAYS=7

# 创建备份目录
mkdir -p ${BACKUP_DIR}/${DATE}

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}

# 开始备份
log "Starting MongoDB backup..."

# 执行备份
mongodump --uri="${MONGODB_URI}" \
  --gzip \
  --out=${BACKUP_DIR}/${DATE}

# 备份 Oplog
mongodump --uri="${MONGODB_URI}" \
  --db=local \
  --collection=oplog.rs \
  --gzip \
  --out=${BACKUP_DIR}/${DATE}/oplog

# 创建备份元数据
cat > ${BACKUP_DIR}/${DATE}/metadata.json <<EOF
{
  "date": "${DATE}",
  "uri": "${MONGODB_URI}",
  "version": "$(mongod --version | head -1)"
}
EOF

# 计算校验和
cd ${BACKUP_DIR}
tar -czf mongodb_backup_${DATE}.tar.gz ${DATE}
sha256sum mongodb_backup_${DATE}.tar.gz > mongodb_backup_${DATE}.tar.gz.sha256

# 清理临时文件
rm -rf ${BACKUP_DIR}/${DATE}

# 清理过期备份
log "Cleaning up backups older than ${RETENTION_DAYS} days..."
find ${BACKUP_DIR} -name "mongodb_backup_*.tar.gz" \
  -mtime +${RETENTION_DAYS} -delete

log "Backup completed successfully!"

定时任务配置

# 添加到 crontab
crontab -e

# 每天凌晨 2 点执行备份
0 2 * * * /opt/scripts/backup.sh >> /var/log/mongodb_backup.log 2>&1

# 每周日凌晨 3 点执行全量备份
0 3 * * 0 /opt/scripts/full_backup.sh >> /var/log/mongodb_full_backup.log 2>&1

12.7 验证备份

# 验证备份文件完整性
cd /backup
tar -tzf mongodb_backup_20240101.tar.gz | head -10

# 验证校验和
sha256sum -c mongodb_backup_20240101.tar.gz.sha256

# 测试恢复
mongorestore --uri="mongodb://localhost:27017" \
  --dryRun \
  --gzip \
  /backup/mongodb_backup_20240101.tar.gz

# 在测试环境恢复验证
mongorestore --uri="mongodb://localhost:27017/test" \
  --drop \
  --gzip \
  /backup/mongodb_backup_20240101.tar.gz

12.8 备份恢复最佳实践

┌─────────────────────────────────────────────────────────────────┐
│                      备份恢复检查清单                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ✓ 定期执行备份并验证                                            │
│  ✓ 测试恢复流程                                                  │
│  ✓ 监控备份完成状态                                              │
│  ✓ 备份存储与生产数据隔离                                        │
│  ✓ 记录恢复步骤和时间                                            │
│  ✓ 验证恢复后的数据完整性                                         │
│  ✓ 定期更新恢复文档                                              │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

💡 实践提示

  1. 多策略备份:结合 mongodump 和文件系统快照
  2. 定期测试恢复:确保备份可用
  3. Oplog 备份:支持时间点恢复
  4. 分片集群:备份前停止平衡器
  5. 加密备份:敏感数据加密存储

📚 继续学习