1. 背景与需求
- 环境:CentOS 7.9, MongoDB 6.0.16 (Replica Set)。
- 架构:
- 主节点 (Master):
192.168.1.20 - 副节点 (Slave):
192.168.1.21
- 主节点 (Master):
- 认证方式:无账号密码,采用内网 IP 白名单限制。
- 核心需求:
- 每天自动备份指定的业务数据库(如
testdata)。 - 跳过 无价值且巨大的日志库(节省空间与时间)。
- 实现 双机热备:备份文件既保存在本地 (
1.20),也同步传输一份到副机 (1.21) 的/data/backup目录。
- 每天自动备份指定的业务数据库(如
2. 环境准备工作
2.1 安装 MongoDB Database Tools (主节点)
MongoDB 6.0+ 将 mongodump 等工具剥离了 Server 包,需单独安装。在 192.168.1.20 上执行:
# 检查是否已安装,若未安装执行以下命令
sudo yum install -y mongodb-database-tools
注:如果没有配置 yum 源,需先配置 /etc/yum.repos.d/mongodb-org-6.0.repo。
2.2 创建备份目录 (两台机器)
确保两台机器都有存放备份的文件夹。
# 在 192.168.1.20 执行
mkdir -p /data/backup
# 在 192.168.1.21 执行
mkdir -p /data/backup
2.3 配置 SSH 免密登录 (关键)
为了让脚本自动将文件从 20 传到 21,必须配置 SSH 互信。
步骤 1:在 1.20 上生成密钥
ssh-keygen -t rsa
# 提示 "Enter file..." -> 直接回车
# 提示 "Enter passphrase" -> 直接回车(必须留空!)
# 提示 "Enter same passphrase again" -> 直接回车
步骤 2:将公钥发给 1.21
ssh-copy-id root@192.168.1.21
# 这里需要输入一次 1.21 的 root 密码
常见问题处理:
如果报错Permission denied,请登录 1.21 修改/etc/ssh/sshd_config,确保PasswordAuthentication yes,然后重启 sshd 服务,再重试上面的命令。如果1.21是密钥验证,在1.20上查看密钥内容
cat /root/.ssh/id_rsa.pub,在1.21上编辑并复制密钥到这里,vi /root/.ssh/authorized_keys
步骤 3:验证连接
在 1.20 上执行以下命令,若不需要密码直接输出时间,则配置成功:
ssh root@192.168.1.21 "date"
3. 编写备份脚本
此脚本专为“指定数据库”设计,会自动循环备份你需要的库,忽略日志库。
- 脚本路径:
/opt/mongo_custom_backup.sh - 操作节点:
192.168.1.20
使用 vi /opt/mongo_custom_backup.sh 创建文件并写入:
#!/bin/bash
# ================= 配置区域 =================
# MongoDB 连接信息 (本地白名单模式)
DB_HOST="127.0.0.1"
DB_PORT="27017"
# 【关键配置】在这里列出所有需要备份的数据库名,用空格隔开
# 例如: "testdata admin config"
# 坚决不写那个巨大的日志库名
TARGET_DBS="testdata admin"
# 本地备份存储路径
LOCAL_BACKUP_DIR="/data/backup"
# 时间戳
DATE_STR=$(date +%Y%m%d_%H%M%S)
# 远程备份配置 (副机信息)
REMOTE_IP="192.168.1.21"
REMOTE_USER="root"
REMOTE_DIR="/data/backup"
# 保留最近多少天的备份
RETENTION_DAYS=7
# ===========================================
# 1. 检查本地目录
if [ ! -d "$LOCAL_BACKUP_DIR" ]; then
mkdir -p "$LOCAL_BACKUP_DIR"
fi
echo "[$(date)] ====== 开始执行多库备份任务 ======"
# 2. 循环备份指定的数据库
for DB_NAME in $TARGET_DBS
do
echo "[$(date)] 正在备份数据库: $DB_NAME ..."
# 定义文件名: 库名_时间.gzip
BACKUP_NAME="${DB_NAME}_${DATE_STR}.gzip"
# 执行备份
# 注意: 指定 --db 时无法使用 --oplog,这在跳过日志库的场景下是必须的妥协
/usr/bin/mongodump \
--host "$DB_HOST" \
--port "$DB_PORT" \
--db "$DB_NAME" \
--gzip \
--archive="${LOCAL_BACKUP_DIR}/${BACKUP_NAME}"
if [ $? -eq 0 ]; then
echo "[$(date)] 数据库 $DB_NAME 备份成功。"
else
echo "[$(date)] !!! 警告: 数据库 $DB_NAME 备份失败。"
fi
done
# 3. 传输文件到远程主机 (192.168.1.21)
echo "[$(date)] 开始传输本次备份文件到远程主机 $REMOTE_IP ..."
# 传输所有包含本次时间戳的文件
scp ${LOCAL_BACKUP_DIR}/*_${DATE_STR}.gzip ${REMOTE_USER}@${REMOTE_IP}:${REMOTE_DIR}
if [ $? -eq 0 ]; then
echo "[$(date)] 远程传输成功。"
else
echo "[$(date)] 远程传输失败!请检查 SSH 连接。"
fi
# 4. 清理旧备份 (本地)
echo "[$(date)] 清理本地超过 $RETENTION_DAYS 天的旧文件..."
find "$LOCAL_BACKUP_DIR" -name "*.gzip" -type f -mtime +$RETENTION_DAYS -delete
# 5. 清理旧备份 (远程)
# 通过 SSH 命令清理副机上的过期文件,防止副机磁盘满
echo "[$(date)] 清理远程超过 $RETENTION_DAYS 天的旧文件..."
ssh ${REMOTE_USER}@${REMOTE_IP} "find ${REMOTE_DIR} -name '*.gzip' -type f -mtime +$RETENTION_DAYS -delete"
echo "[$(date)] ====== 任务全部完成 ======"
赋予执行权限
chmod +x /opt/mongo_custom_backup.sh
4. 设置定时任务 (Crontab)
建议在业务低峰期(如凌晨 2 点)执行。
在 1.20 上输入 crontab -e,添加以下内容:
# 每天凌晨 02:00 执行 MongoDB 备份,日志记录到 /tmp
0 2 * * * /opt/mongo_custom_backup.sh > /tmp/mongo_backup.log 2>&1
5. 数据恢复指南
当发生意外需要恢复数据时,使用 mongorestore。
场景:恢复 testdata 库到最新备份
假设你要恢复 20250101 的备份文件。
# 1. 解压并恢复 testdata 库
mongorestore \
--host 127.0.0.1 \
--port 27017 \
--gzip \
--archive=/data/backup/testdata_20250101_020000.gzip \
--nsInclude="testdata.*"
--gzip --archive: 指定读取压缩归档文件。--nsInclude="testdata.*": 明确指定恢复该库下的所有集合(通常不需要,但在单库恢复时加上更保险)。
6. 重要提示与风险告知
关于一致性 (Consistency):
由于我们为了跳过日志库使用了--db参数,导致无法开启--oplog。这意味着备份不是“严格的时间点快照”。- 缓解建议:只要你在凌晨业务写入量极低的时候备份,这个风险是可以忽略的。
关于安全性 (Security):
当前使用了“无账号密码 + 白名单”模式。请务必确保服务器防火墙(firewalld/iptables)已配置好,只允许可信 IP 访问 27017 端口。如果内网有其他不可信机器,该配置存在安全隐患。监控:
建议定期(如每周)手动检查一次/data/backup目录,确认文件是否正常生成,文件大小是否合理(如果不为 0,说明有数据)。