MongoDB 备份与恢复:mongodump 和 mongorestore 实战

发布于:2025-09-02 ⋅ 阅读:(18) ⋅ 点赞:(0)

第一章:MongoDB 备份恢复概述

1.1 数据备份的重要性

在当今数据驱动的时代,数据是企业最宝贵的资产之一。MongoDB 作为最流行的 NoSQL 数据库,承载着大量关键业务数据。数据备份的重要性体现在:
业务连续性保障:

  • 防止数据丢失导致业务中断
  • 满足合规性和监管要求
  • 支持灾难恢复计划
    数据管理需求:
  • 环境迁移和数据同步
  • 版本控制和变更回滚
  • 测试数据准备和开发支持

1.2 MongoDB 备份策略类型

备份类型 优点 缺点 适用场景
逻辑备份 (mongodump) 跨版本兼容、可选择性备份、体积小 备份恢复慢、需要停机时间 开发测试、小规模数据
物理备份 (文件系统快照) 备份恢复快、几乎无需停机 存储需求大、版本依赖强 生产环境、大规模数据
持续备份 (oplog) 实时保护、秒级RPO 配置复杂、资源消耗大 关键业务、零数据丢失要求

1.3 备份架构示意图

[应用程序] → [MongoDB 主节点] → [备份服务器]
    │              │              │
    │              ↓              ↓
    └──────→ [监控系统]    [云存储/磁带库]

第二章:mongodump 工具详解

2.1 mongodump 基本语法

mongodump --uri="mongodb://用户名:密码@主机:端口/数据库" \
          --collection=集合名 \
          --out=备份目录 \
          --gzip \
          --query='{"字段": {"$gt": 100}}'

2.2 常用参数详解

连接参数:

  • –uri:连接字符串(MongoDB 4.4+)
  • –host:主机地址
  • –port:端口号
  • –username:用户名
  • –password:密码
  • –authenticationDatabase:认证数据库
    备份参数:
  • –db:指定数据库
  • –collection:指定集合
  • –out:输出目录
  • –gzip:压缩备份
  • –query:过滤条件
  • –excludeCollection:排除集合

2.3 实战示例:完整备份

#!/bin/bash
# 完整数据库备份脚本

BACKUP_DIR="/data/backup/mongodb"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/mongodb/backup_${TIMESTAMP}.log"

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

# 执行备份
mongodump \
  --host="localhost:27017" \
  --username="admin" \
  --password="securepassword" \
  --authenticationDatabase="admin" \
  --out="${BACKUP_DIR}/${TIMESTAMP}" \
  --gzip \
  --verbose 2>&1 | tee ${LOG_FILE}

# 验证备份完整性
if [ $? -eq 0 ]; then
    echo "备份成功完成: ${TIMESTAMP}"
    # 清理旧备份(保留最近7天)
    find ${BACKUP_DIR} -type d -mtime +7 -exec rm -rf {} \;
else
    echo "备份失败,请检查日志: ${LOG_FILE}"
    exit 1
fi

2.4 实战示例:增量备份

#!/bin/bash
# 基于查询的增量备份

LAST_BACKUP_TIME="20240101_000000"
CURRENT_TIME=$(date +%Y%m%d_%H%M%S)

mongodump \
  --uri="mongodb://admin:password@localhost:27017/mydb" \
  --query="{\"timestamp\": {\"\$gt\": {\"\$date\": \"${LAST_BACKUP_TIME}\"}}}" \
  --out="/backups/incremental_${CURRENT_TIME}" \
  --gzip

2.5 备份文件结构解析

backup_20240101/
├── admin/
│   ├── system.users.bson.gz
│   └── system.users.metadata.json.gz
├── mydb/
│   ├── collection1.bson.gz
│   ├── collection1.metadata.json.gz
│   ├── collection2.bson.gz
│   └── collection2.metadata.json.gz
└── backup.log

第三章:mongorestore 工具详解

3.1 mongorestore 基本语法

mongorestore --uri="mongodb://用户名:密码@主机:端口/数据库" \
             --dir=备份目录 \
             --gzip \
             --drop \
             --nsInclude="数据库.集合"

3.2 常用参数详解

恢复参数:

  • –dir:备份文件目录
  • –gzip:解压缩恢复
  • –drop:恢复前删除集合
  • –nsInclude:包含的命名空间
  • –nsExclude:排除的命名空间
  • –noIndexRestore:不恢复索引

3.3 实战示例:完整恢复

#!/bin/bash
# 完整数据库恢复脚本

BACKUP_DIR="/data/backup/mongodb/20240101_120000"
TARGET_URI="mongodb://admin:password@localhost:27017"

mongorestore \
  --uri="${TARGET_URI}" \
  --dir="${BACKUP_DIR}" \
  --gzip \
  --drop \
  --verbose

if [ $? -eq 0 ]; then
    echo "恢复成功完成"
else
    echo "恢复失败"
    exit 1
fi

3.4 实战示例:部分恢复

# 恢复特定集合
mongorestore \
  --uri="mongodb://localhost:27017" \
  --nsInclude="mydb.important_collection" \
  --dir="/backups/full_backup" \
  --gzip

# 恢复时重命名集合
mongorestore \
  --uri="mongodb://localhost:27017" \
  --nsFrom="mydb.old_collection" \
  --nsTo="mydb.new_collection" \
  --dir="/backups/full_backup" \
  --gzip

第四章:高级备份策略

4.1 分片集群备份

#!/bin/bash
# 分片集群备份脚本

CONFIG_SERVER="cfg1.example.com:27019"
SHARDS=("shard1.example.com:27018" "shard2.example.com:27018")

# 备份配置服务器
mongodump --host=${CONFIG_SERVER} --out=/backups/config_server --gzip

# 备份每个分片
for shard in "${SHARDS[@]}"; do
    shard_name=$(echo ${shard} | cut -d':' -f1)
    mongodump --host=${shard} --out="/backups/shards/${shard_name}" --gzip
done

4.2 副本集备份

#!/bin/bash
# 从副本集次要节点备份

SECONDARY_NODE="secondary.example.com:27017"

# 检查节点状态
Node_state=$(mongo --host ${SECONDARY_NODE} --eval "rs.status().members.find(m => m.name == '${SECONDARY_NODE}').stateStr" --quiet)

if [ "${Node_state}" == "SECONDARY" ]; then
    mongodump --host=${SECONDARY_NODE} --out=/backups/secondary_backup --gzip
else
    echo "节点不是次要节点,无法备份"
    exit 1
fi

4.3 加密备份

# 使用OpenSSL加密备份文件
mongodump --uri="mongodb://localhost:27017/mydb" --out=- --gzip | \
openssl enc -aes-256-cbc -salt -out /backups/encrypted_backup.enc -pass pass:mysecret

# 解密并恢复
openssl enc -d -aes-256-cbc -in /backups/encrypted_backup.enc -pass pass:mysecret | \
mongorestore --uri="mongodb://localhost:27017/mydb" --gzip -

第五章:备份恢复实战场景

5.1 生产环境备份方案

多级备份策略:

#!/bin/bash
# 多级备份策略:每日+每周+每月

BACKUP_ROOT="/data/backup/mongodb"
DATE=$(date +%Y%m%d)
DAY=$(date +%d)
WEEKDAY=$(date +%w)

# 每日备份
mongodump --uri="mongodb://localhost:27017" --out="${BACKUP_ROOT}/daily/${DATE}" --gzip

# 周日执行每周备份
if [ ${WEEKDAY} -eq 0 ]; then
    cp -r "${BACKUP_ROOT}/daily/${DATE}" "${BACKUP_ROOT}/weekly/${DATE}"
fi

# 每月1号执行月度备份
if [ ${DAY} -eq 1 ]; then
    cp -r "${BACKUP_ROOT}/daily/${DATE}" "${BACKUP_ROOT}/monthly/${DATE}"
fi

# 清理策略
find "${BACKUP_ROOT}/daily" -type d -mtime +7 -exec rm -rf {} \;
find "${BACKUP_ROOT}/weekly" -type d -mtime +30 -exec rm -rf {} \;
find "${BACKUP_ROOT}/monthly" -type d -mtime +365 -exec rm -rf {} \;

5.2 跨版本迁移实战

# 从MongoDB 4.4备份
mongodump --host=old_server:27017 --out=/backups/mongo44_backup

# 恢复到MongoDB 6.0
mongorestore --host=new_server:27017 --dir=/backups/mongo44_backup

# 验证数据一致性
mongo --host=new_server:27017 --eval "
db.adminCommand({listDatabases:1});
db.stats();
"

5.3 大数据量备份优化

# 并行备份多个集合
COLLECTIONS=("collection1" "collection2" "collection3")

for collection in "${COLLECTIONS[@]}"; do
    mongodump \
        --uri="mongodb://localhost:27017/mydb" \
        --collection="${collection}" \
        --out="/backups/parallel_${collection}" \
        --gzip &
done

wait
echo "所有集合备份完成"

第六章:监控与验证

6.1 备份监控脚本

#!/bin/bash
# 备份监控和告警脚本

BACKUP_DIR="/data/backup/mongodb"
MIN_SIZE=1000000  # 最小备份大小1GB
ALERT_EMAIL="admin@example.com"

# 检查最新备份
LATEST_BACKUP=$(ls -t ${BACKUP_DIR} | head -1)
BACKUP_SIZE=$(du -s "${BACKUP_DIR}/${LATEST_BACKUP}" | cut -f1)

# 检查备份完整性
if [ ${BACKUP_SIZE} -lt ${MIN_SIZE} ]; then
    echo "警告: 备份大小异常 ${BACKUP_SIZE}" | mail -s "MongoDB备份异常" ${ALERT_EMAIL}
fi

# 检查备份时间(不超过24小时)
BACKUP_AGE=$(find "${BACKUP_DIR}/${LATEST_BACKUP}" -type f -name "*.bson.gz" -exec stat -c %Y {} \; | sort -n | tail -1)
CURRENT_TIME=$(date +%s)
AGE_HOURS=$(( (CURRENT_TIME - BACKUP_AGE) / 3600 ))

if [ ${AGE_HOURS} -gt 24 ]; then
    echo "警告: 备份已过期 ${AGE_HOURS}小时" | mail -s "MongoDB备份过期" ${ALERT_EMAIL}
fi

6.2 数据一致性验证

// 数据一致性验证脚本
db = db.getSiblingDB('mydb');

// 检查文档数量
var originalCount = db.original_collection.countDocuments();
var restoredCount = db.restored_collection.countDocuments();

print("原始集合文档数: " + originalCount);
print("恢复集合文档数: " + restoredCount);

// 抽样验证数据完整性
var sampleDocs = db.original_collection.aggregate([{ $sample: { size: 100 } }]).toArray();

sampleDocs.forEach(function(doc) {
    var restoredDoc = db.restored_collection.findOne({ _id: doc._id });
    if (!restoredDoc) {
        print("警告: 文档丢失: " + doc._id);
    } else if (JSON.stringify(doc) !== JSON.stringify(restoredDoc)) {
        print("警告: 文档不匹配: " + doc._id);
    }
});

print("数据验证完成");

第七章:故障排除与优化

7.1 常见问题解决

内存不足错误:

# 调整mongodump内存使用
mongodump --uri="mongodb://localhost:27017" \
          --out="/backups" \
          --batchSize=100 \
          --numParallelCollections=2

网络超时问题:

# 增加超时时间
mongodump --host=remote_server:27017 \
          --username=admin \
          --password=password \
          --out="/backups" \
          --gzip \
          --networkTimeout=300000  # 5分钟超时

7.2 性能优化技巧

并行处理优化:

# 使用并行处理加速备份
mongodump --uri="mongodb://localhost:27017" \
          --out="/backups" \
          --numParallelCollections=4 \
          --writeConcern="{w:0}"  # 不等待确认

IO优化:

# 使用更快的存储设备
mongodump --uri="mongodb://localhost:27017" \
          --out="/ssd_backups"  # SSD存储

第八章:自动化与集成

8.1 完整自动化方案

#!/bin/bash
# 完整的自动化备份解决方案

set -e  # 遇到错误立即退出

# 配置参数
MONGODB_URI="mongodb://admin:password@localhost:27017"
BACKUP_DIR="/data/backup/mongodb"
RETENTION_DAYS=7
LOG_DIR="/var/log/mongodb"

# 创建目录
mkdir -p ${BACKUP_DIR}
mkdir -p ${LOG_DIR}

# 生成时间戳
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="${LOG_DIR}/backup_${TIMESTAMP}.log"

# 执行备份
echo "开始MongoDB备份: ${TIMESTAMP}" | tee -a ${LOG_FILE}

mongodump --uri="${MONGODB_URI}" \
          --out="${BACKUP_DIR}/${TIMESTAMP}" \
          --gzip \
          --verbose 2>&1 | tee -a ${LOG_FILE}

# 检查备份结果
if [ $? -eq 0 ]; then
    BACKUP_SIZE=$(du -sh "${BACKUP_DIR}/${TIMESTAMP}" | cut -f1)
    echo "备份成功: ${BACKUP_SIZE}" | tee -a ${LOG_FILE}
    
    # 清理旧备份
    find ${BACKUP_DIR} -type d -mtime +${RETENTION_DAYS} -exec rm -rf {} \; 2>/dev/null || true
else
    echo "备份失败" | tee -a ${LOG_FILE}
    exit 1
fi

echo "备份流程完成: $(date)" | tee -a ${LOG_FILE}

8.2 与监控系统集成

#!/bin/bash
# 与Prometheus监控系统集成

BACKUP_DIR="/data/backup/mongodb"
METRICS_FILE="/tmp/mongodb_backup_metrics.prom"

# 生成监控指标
echo "# HELP mongodb_backup_size_bytes MongoDB备份大小字节数" > ${METRICS_FILE}
echo "# TYPE mongodb_backup_size_bytes gauge" >> ${METRICS_FILE}
echo "mongodb_backup_size_bytes $(du -s ${BACKUP_DIR} | cut -f1)" >> ${METRICS_FILE}

echo "# HELP mongodb_backup_age_seconds MongoDB备份年龄秒数" >> ${METRICS_FILE}
echo "# TYPE mongodb_backup_age_seconds gauge" >> ${METRICS_FILE}
LATEST_BACKUP=$(ls -t ${BACKUP_DIR} | head -1)
if [ -n "${LATEST_BACKUP}" ]; then
    BACKUP_AGE=$(stat -c %Y "${BACKUP_DIR}/${LATEST_BACKUP}")
    CURRENT_TIME=$(date +%s)
    echo "mongodb_backup_age_seconds $((CURRENT_TIME - BACKUP_AGE))" >> ${METRICS_FILE}
fi

# 推送到Prometheus Pushgateway
curl -X POST -H "Content-Type: text/plain" --data-binary @${METRICS_FILE} \
     "http://prometheus:9091/metrics/job/mongodb_backup"

附录:实用命令参考

快速参考手册

常用mongodump命令:

# 基本备份
mongodump --host=localhost --out=/backups

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

# 特定集合备份
mongodump --db=mydb --collection=users --out=/backups

# 带查询条件的备份
mongodump --query='{"created_at": {"$gt": {"$date": "2024-01-01T00:00:00Z"}}}' --out=/backups

常用mongorestore命令:

# 基本恢复
mongorestore --host=localhost --dir=/backups

# 压缩恢复
mongorestore --gzip --dir=/backups

# 恢复特定数据库
mongorestore --db=mydb --dir=/backups/mydb

# 恢复时删除现有数据
mongorestore --drop --dir=/backups

故障排除命令

连接测试:

# 测试数据库连接
mongo --host=localhost --username=admin --password=password --eval "db.adminCommand({ping:1})"

# 检查数据库大小
mongo --eval "db.stats()" mydb

备份验证:

# 检查备份文件完整性
bsondump --objcheck /backups/mydb/users.bson

# 查看备份元数据
zcat /backups/mydb/users.metadata.json.gz | jq .

通过本指南,您应该能够全面掌握MongoDB的备份与恢复技术,构建可靠的数据保护策略。记住,定期测试恢复流程和验证备份完整性同样重要!


网站公告

今日签到

点亮在社区的每一天
去签到