Linux服务器自动化备份方案:rsync+cron实现异地备份全流程
备份不是可选项,是服务器最后一道防线
磁盘损坏、误操作删文件、勒索软件加密数据——这些情况发生时,能否快速恢复业务的唯一保障就是备份。本文提供一套完整的自动化备份方案:rsync 增量备份文件 + mysqldump 备份数据库 + cron 定时执行 + 异地传输,覆盖中小型服务器的主要备份需求。
一、备份策略设计
| 备份类型 | 频率 | 保留周期 | 工具 |
|---|---|---|---|
| 数据库完整备份 | 每天 1 次 | 保留 7 天 | mysqldump |
| 网站文件增量备份 | 每天 1 次 | 保留 7 天 | rsync |
| 异地传输 | 每天备份后 | 与本地一致 | rsync over SSH |
| 备份完整性验证 | 每天 | — | checksum 校验 |
二、配置 SSH 免密登录(异地备份必需)
在源服务器上生成密钥对,并将公钥上传到备份服务器:
# 在源服务器生成专用备份密钥
ssh-keygen -t ed25519 -f ~/.ssh/backup_key -N "" -C "backup"
# 将公钥复制到备份服务器
ssh-copy-id -i ~/.ssh/backup_key.pub backupuser@backup_server_ip
# 测试免密登录
ssh -i ~/.ssh/backup_key backupuser@backup_server_ip "echo ok"三、编写备份脚本
sudo nano /usr/local/bin/backup.sh#!/bin/bash
# ===== 配置区域 =====
SOURCE_DIR="/www/wwwroot" # 网站文件目录
DB_NAME="myapp_db" # 数据库名
DB_USER="root" # 数据库用户
DB_PASS="your_db_password" # 数据库密码
LOCAL_BACKUP_DIR="/backup" # 本地备份目录
REMOTE_USER="backupuser" # 备份服务器用户名
REMOTE_HOST="backup_server_ip" # 备份服务器 IP
REMOTE_DIR="/backup/$(hostname)" # 备份服务器目标目录
SSH_KEY="/root/.ssh/backup_key" # SSH 密钥路径
KEEP_DAYS=7 # 本地保留天数
LOG_FILE="/var/log/backup.log" # 日志文件
# ===== 函数定义 =====
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# ===== 开始备份 =====
DATE=$(date +%Y%m%d_%H%M%S)
log "===== 备份开始 ====="
# 创建本地备份目录
mkdir -p "${LOCAL_BACKUP_DIR}/db"
mkdir -p "${LOCAL_BACKUP_DIR}/files"
# 1. 备份数据库
log "开始备份数据库: ${DB_NAME}"
DB_FILE="${LOCAL_BACKUP_DIR}/db/${DB_NAME}_${DATE}.sql.gz"
mysqldump -u"${DB_USER}" -p"${DB_PASS}" \
--single-transaction \
--quick \
--routines \
--triggers \
"${DB_NAME}" | gzip > "${DB_FILE}"
if [ $? -eq 0 ]; then
log "数据库备份成功: ${DB_FILE} ($(du -sh ${DB_FILE} | cut -f1))"
else
log "ERROR: 数据库备份失败!"
exit 1
fi
# 2. 备份网站文件(rsync 增量备份)
log "开始备份网站文件: ${SOURCE_DIR}"
FILE_BACKUP_DIR="${LOCAL_BACKUP_DIR}/files/${DATE}"
rsync -avz --delete \
--exclude="*.log" \
--exclude="cache/" \
--exclude=".git/" \
"${SOURCE_DIR}/" "${FILE_BACKUP_DIR}/"
if [ $? -eq 0 ]; then
log "文件备份成功: ${FILE_BACKUP_DIR} ($(du -sh ${FILE_BACKUP_DIR} | cut -f1))"
else
log "ERROR: 文件备份失败!"
fi
# 3. 传输到异地备份服务器
log "开始传输到备份服务器: ${REMOTE_HOST}"
ssh -i "${SSH_KEY}" "${REMOTE_USER}@${REMOTE_HOST}" "mkdir -p ${REMOTE_DIR}"
rsync -avz --delete \
-e "ssh -i ${SSH_KEY}" \
"${LOCAL_BACKUP_DIR}/" \
"${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/"
if [ $? -eq 0 ]; then
log "异地传输成功"
else
log "ERROR: 异地传输失败!"
fi
# 4. 清理本地过期备份
log "清理超过 ${KEEP_DAYS} 天的本地备份"
find "${LOCAL_BACKUP_DIR}/db" -name "*.sql.gz" -mtime +${KEEP_DAYS} -delete
find "${LOCAL_BACKUP_DIR}/files" -maxdepth 1 -type d -mtime +${KEEP_DAYS} -exec rm -rf {} +
log "===== 备份完成 =====\n"# 赋予执行权限
sudo chmod +x /usr/local/bin/backup.sh
# 手动测试一次
sudo /usr/local/bin/backup.sh
# 查看日志
cat /var/log/backup.log四、配置 cron 定时任务
sudo crontab -e# 每天凌晨 3:00 执行备份(避开业务高峰)
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1五、验证备份可用性
备份文件存在不等于备份可用,定期验证是必要的:
# 验证数据库备份文件完整性
gunzip -t /backup/db/myapp_db_20260101_030000.sql.gz && echo "备份文件完整" || echo "备份文件损坏"
# 在测试环境恢复数据库验证内容
gunzip -c /backup/db/myapp_db_20260101_030000.sql.gz | mysql -u root -p test_db
# 验证文件备份是否与源目录一致
rsync -avn --delete /www/wwwroot/ /backup/files/latest/ | grep "^>" | wc -l总结
完整的自动化备份方案包含五个要素:数据库备份(mysqldump)+ 文件增量备份(rsync)+ 异地传输(rsync over SSH)+ 定时执行(cron)+ 定期验证(完整性校验)。单靠本地备份不够,必须有异地备份,防止服务器物理损坏时数据全部丢失。
需要可靠的异地备份目标服务器,IDC.Net 美国服务器月付 199 元起,与香港服务器不同数据中心,适合作为香港业务服务器的异地备份节点,支付宝付款即可开通。