Appearance
备份与恢复
数据备份是数据库管理中最重要的工作之一。本章将介绍MongoDB的各种备份方法、恢复策略以及数据导入导出操作。
备份概述
备份类型
bash
# MongoDB备份类型:
# 1. 逻辑备份
# 使用工具导出数据(mongodump、mongoexport)
# 优点:可读性强、跨版本兼容
# 缺点:速度慢、大数据量不适用
# 2. 物理备份
# 直接复制数据文件
# 优点:速度快、适合大数据量
# 缺点:需要停止服务或使用快照
# 3. 文件系统快照
# 使用LVM、ZFS等文件系统快照
# 优点:速度快、一致性保证
# 缺点:需要特定文件系统支持
# 备份策略选择:
# - 小数据量:mongodump
# - 大数据量:文件系统快照或复制数据文件
# - 复制集:从节点备份
# - 分片集群:配置服务器和分片备份mongodump备份
基本用法
bash
# mongodump是MongoDB自带的逻辑备份工具
# 备份所有数据库
mongodump --host localhost --port 27017 \
--username admin --password \
--authenticationDatabase admin \
--out /backup/mongodb_$(date +%Y%m%d)
# 备份指定数据库
mongodump --host localhost --port 27017 \
--db mydb \
--out /backup/mongodb_$(date +%Y%m%d)
# 备份指定集合
mongodump --host localhost --port 27017 \
--db mydb --collection users \
--out /backup/mongodb_$(date +%Y%m%d)
# 使用URI连接
mongodump --uri="mongodb://admin:password@localhost:27017/mydb?authSource=admin" \
--out /backup/mongodb_$(date +%Y%m%d)常用选项
bash
# mongodump常用选项
# --host:MongoDB服务器地址
# --port:MongoDB服务器端口
# --username:用户名
# --password:密码
# --authenticationDatabase:认证数据库
# --db:指定数据库
# --collection:指定集合
# --query:备份符合条件的文档
# --out:输出目录
# --gzip:压缩输出
# --oplog:记录备份期间的oplog(用于时间点恢复)
# --archive:输出到单个归档文件
# 使用gzip压缩
mongodump --host localhost --port 27017 \
--db mydb \
--gzip \
--out /backup/mongodb_$(date +%Y%m%d)
# 输出到单个归档文件
mongodump --host localhost --port 27017 \
--db mydb \
--archive=/backup/mydb_$(date +%Y%m%d).archive
# 压缩归档文件
mongodump --host localhost --port 27017 \
--db mydb \
--gzip \
--archive=/backup/mydb_$(date +%Y%m%d).archive.gz
# 备份指定查询条件的数据
mongodump --host localhost --port 27017 \
--db mydb --collection orders \
--query '{"status": "completed"}' \
--out /backup/mongodb_$(date +%Y%m%d)
# 使用oplog备份(用于时间点恢复)
mongodump --host localhost --port 27017 \
--oplog \
--out /backup/mongodb_$(date +%Y%m%d)复制集备份
bash
# 从复制集备份(从从节点备份,减少主节点压力)
# 指定从节点备份
mongodump --host secondary1.example.com --port 27017 \
--db mydb \
--out /backup/mongodb_$(date +%Y%m%d)
# 使用readPreference
mongodump --host rs0/primary.example.com,secondary1.example.com \
--readPreference=secondary \
--db mydb \
--out /backup/mongodb_$(date +%Y%m%d)
# 完整备份(包含oplog)
mongodump --host rs0/primary.example.com,secondary1.example.com \
--oplog \
--gzip \
--archive=/backup/mongodb_full_$(date +%Y%m%d).archive.gzmongorestore恢复
基本用法
bash
# mongorestore是MongoDB的数据恢复工具
# 恢复所有数据库
mongorestore --host localhost --port 27017 \
--username admin --password \
--authenticationDatabase admin \
/backup/mongodb_20240101
# 恢复指定数据库
mongorestore --host localhost --port 27017 \
--db mydb \
/backup/mongodb_20240101/mydb
# 恢复指定集合
mongorestore --host localhost --port 27017 \
--db mydb --collection users \
/backup/mongodb_20240101/mydb/users.bson
# 从归档文件恢复
mongorestore --host localhost --port 27017 \
--archive=/backup/mydb_20240101.archive
# 从压缩归档文件恢复
mongorestore --host localhost --port 27017 \
--gzip \
--archive=/backup/mydb_20240101.archive.gz恢复选项
bash
# mongorestore常用选项
# --drop:恢复前删除现有数据
mongorestore --host localhost --port 27017 \
--drop \
/backup/mongodb_20240101
# --nsInclude:只恢复匹配的命名空间
mongorestore --host localhost --port 27017 \
--nsInclude="mydb.*" \
/backup/mongodb_20240101
# --nsExclude:排除匹配的命名空间
mongorestore --host localhost --port 27017 \
--nsExclude="mydb.logs.*" \
/backup/mongodb_20240101
# --nsFrom 和 --nsTo:重命名命名空间
mongorestore --host localhost --port 27017 \
--nsFrom="mydb.*" \
--nsTo="mydb_restored.*" \
/backup/mongodb_20240101
# 恢复oplog(时间点恢复)
mongorestore --host localhost --port 27017 \
--oplogReplay \
/backup/mongodb_20240101
# 停止应用oplog的时间点
mongorestore --host localhost --port 27017 \
--oplogReplay \
--oplogLimit "2024-01-01 12:00:00" \
/backup/mongodb_20240101数据导入导出
mongoexport导出
bash
# mongoexport:将数据导出为JSON或CSV格式
# 导出为JSON格式
mongoexport --host localhost --port 27017 \
--db mydb --collection users \
--out /backup/users.json
# 导出为CSV格式
mongoexport --host localhost --port 27017 \
--db mydb --collection users \
--type=csv \
--fields name,email,age \
--out /backup/users.csv
# 导出查询结果
mongoexport --host localhost --port 27017 \
--db mydb --collection orders \
--query '{"status": "completed"}' \
--out /backup/completed_orders.json
# 导出排序后的数据
mongoexport --host localhost --port 27017 \
--db mydb --collection users \
--sort='{ "createdAt": -1 }' \
--limit 1000 \
--out /backup/recent_users.json
# 使用URI连接
mongoexport --uri="mongodb://localhost:27017/mydb" \
--collection users \
--out /backup/users.json
# 导出为JSON数组格式
mongoexport --host localhost --port 27017 \
--db mydb --collection users \
--jsonArray \
--out /backup/users_array.json
# 格式化输出(pretty print)
mongoexport --host localhost --port 27017 \
--db mydb --collection users \
--pretty \
--out /backup/users_pretty.jsonmongoimport导入
bash
# mongoimport:从JSON或CSV文件导入数据
# 导入JSON文件
mongoimport --host localhost --port 27017 \
--db mydb --collection users \
--file /backup/users.json
# 导入JSON数组文件
mongoimport --host localhost --port 27017 \
--db mydb --collection users \
--jsonArray \
--file /backup/users_array.json
# 导入CSV文件
mongoimport --host localhost --port 27017 \
--db mydb --collection users \
--type=csv \
--headerline \
--file /backup/users.csv
# 导入CSV并指定字段
mongoimport --host localhost --port 27017 \
--db mydb --collection users \
--type=csv \
--fields name,email,age \
--file /backup/users.csv
# 导入时忽略空字段
mongoimport --host localhost --port 27017 \
--db mydb --collection users \
--ignoreBlanks \
--file /backup/users.json
# 导入时删除现有数据
mongoimport --host localhost --port 27017 \
--db mydb --collection users \
--drop \
--file /backup/users.json
# 导入时更新现有数据(upsert)
mongoimport --host localhost --port 27017 \
--db mydb --collection users \
--upsertFields email \
--file /backup/users.json
# 批量导入(指定批次大小)
mongoimport --host localhost --port 27017 \
--db mydb --collection users \
--batchSize 1000 \
--file /backup/users.json物理备份
复制数据文件
bash
# 物理备份:直接复制数据文件
# 方法一:停止MongoDB后复制(冷备份)
# 1. 停止MongoDB服务
sudo systemctl stop mongod
# 2. 复制数据目录
sudo cp -r /var/lib/mongodb /backup/mongodb_$(date +%Y%m%d)
# 3. 启动MongoDB服务
sudo systemctl start mongod
# 方法二:使用文件系统快照(热备份)
# 使用LVM快照
sudo lvcreate -L 10G -s -n mongodb_snapshot /dev/vg0/mongodb_lv
# 挂载快照
sudo mkdir /mnt/mongodb_snapshot
sudo mount /dev/vg0/mongodb_snapshot /mnt/mongodb_snapshot
# 复制快照数据
sudo cp -r /mnt/mongodb_snapshot /backup/mongodb_$(date +%Y%m%d)
# 卸载并删除快照
sudo umount /mnt/mongodb_snapshot
sudo lvremove /dev/vg0/mongodb_snapshot使用WiredTiger检查点
bash
# 使用WiredTiger检查点进行一致性备份
# 1. 锁定数据库(阻止写入)
db.fsyncLock()
# 2. 复制数据文件
cp -r /var/lib/mongodb /backup/mongodb_$(date +%Y%m%d)
# 3. 解锁数据库
db.fsyncUnlock()
# 注意:锁定期间数据库只能读取不能写入备份脚本
自动备份脚本
bash
#!/bin/bash
# MongoDB自动备份脚本
# 配置变量
MONGO_HOST="localhost"
MONGO_PORT="27017"
MONGO_USER="admin"
MONGO_PASS="password"
AUTH_DB="admin"
BACKUP_DIR="/backup/mongodb"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_PATH="${BACKUP_DIR}/${DATE}"
RETENTION_DAYS=7
# 创建备份目录
mkdir -p ${BACKUP_PATH}
# 执行备份
echo "开始备份: $(date)"
mongodump --host ${MONGO_HOST} \
--port ${MONGO_PORT} \
--username ${MONGO_USER} \
--password ${MONGO_PASS} \
--authenticationDatabase ${AUTH_DB} \
--gzip \
--out ${BACKUP_PATH}
# 检查备份是否成功
if [ $? -eq 0 ]; then
echo "备份成功: ${BACKUP_PATH}"
# 压缩备份目录
tar -czf ${BACKUP_PATH}.tar.gz -C ${BACKUP_DIR} ${DATE}
rm -rf ${BACKUP_PATH}
# 删除旧备份
find ${BACKUP_DIR} -name "*.tar.gz" -mtime +${RETENTION_DAYS} -delete
echo "已清理 ${RETENTION_DAYS} 天前的备份"
else
echo "备份失败"
exit 1
fi
echo "备份完成: $(date)"定时备份
bash
# 使用crontab设置定时备份
# 编辑crontab
crontab -e
# 每天凌晨2点执行备份
0 2 * * * /path/to/backup_script.sh >> /var/log/mongodb_backup.log 2>&1
# 每周日凌晨3点执行完整备份
0 3 * * 0 /path/to/full_backup_script.sh >> /var/log/mongodb_backup.log 2>&1
# 每小时备份oplog
0 * * * * /path/to/oplog_backup_script.sh >> /var/log/mongodb_backup.log 2>&1备份验证
bash
#!/bin/bash
# 备份验证脚本
BACKUP_FILE=$1
# 检查文件是否存在
if [ ! -f "$BACKUP_FILE" ]; then
echo "备份文件不存在: $BACKUP_FILE"
exit 1
fi
# 检查压缩文件完整性
if [[ $BACKUP_FILE == *.gz ]]; then
gzip -t $BACKUP_FILE
if [ $? -ne 0 ]; then
echo "压缩文件损坏: $BACKUP_FILE"
exit 1
fi
fi
# 测试恢复到临时数据库
TEMP_DB="test_restore_$(date +%Y%m%d_%H%M%S)"
mongorestore --host localhost --port 27017 \
--db ${TEMP_DB} \
--drop \
--gzip \
--archive=${BACKUP_FILE}
# 检查恢复的数据
DOCUMENT_COUNT=$(mongosh --quiet --eval "
db.getSiblingDB('${TEMP_DB}').getCollectionNames().forEach(function(c) {
print(db.getSiblingDB('${TEMP_DB}').getCollection(c).count());
})
")
echo "恢复的文档数: ${DOCUMENT_COUNT}"
# 清理临时数据库
mongosh --quiet --eval "db.getSiblingDB('${TEMP_DB}').dropDatabase()"
echo "备份验证完成: $BACKUP_FILE"本章小结
本章介绍了MongoDB备份与恢复的相关知识:
- 备份概述:了解不同备份类型的特点和适用场景
- mongodump备份:掌握逻辑备份工具的使用方法
- mongorestore恢复:学会使用恢复工具还原数据
- 数据导入导出:掌握mongoexport和mongoimport的使用
- 物理备份:了解直接复制数据文件的方法
- 备份脚本:学会编写自动备份和验证脚本
下一章,我们将学习性能优化,了解如何优化MongoDB性能。
