Rsync 备份脚本:每天凌晨 3 点的安心
前阵子有个朋友 VPS 到期没续费,上面跑了两年的博客数据全没了,找服务商要快照,人家说过期一周就清掉了。血的教训:数据只存一份,等于没存。这篇分享我的备份方案,简单到不好意思,但确实救过我一次。
方案设计
需求很朴素:每天凌晨,把本机的 /data(网站、数据库 dump、配置文件)同步到另一台备用机器。要求:增量(别每次全量传)、失败要告警、保留最近 7 天。
工具选 rsync,理由:增量传输只传变化块,断点续传友好,几乎所有 Linux 自带。
脚本
#!/bin/bash
# backup.sh - 每天凌晨 3 点执行
set -e
SRC="/data/"
DST="backup@192.168.1.200:/backup/$(hostname)/"
LOG="/var/log/backup.log"
DATE=$(date +%Y%m%d)
echo "[$DATE] 备份开始" >> "$LOG"
# 先 dump 数据库(如果有)
mysqldump -u root mydb > /data/db_mydb.sql 2>/dev/null || true
rsync -avz --delete \
--exclude='*.tmp' \
--exclude='cache/' \
-e "ssh -i /root/.ssh/backup_key -o StrictHostKeyChecking=no" \
"$SRC" "$DST" >> "$LOG" 2>&1
if [ $? -eq 0 ]; then
echo "[$DATE] 备份成功" >> "$LOG"
else
echo "[$DATE] 备份失败!!" >> "$LOG"
# 发告警邮件(需配好 mail)
echo "备份失败,请检查" | mail -s "备份告警 $(hostname)" admin@example.com
fi
# 只保留 7 天日志
find /var/log -name "backup.log*" -mtime +7 -delete
几个关键点
--delete:目标端同步删除,保持镜像一致。危险但必要——否则删掉的文件永远占着备份空间。怕误删的话,先不加--delete跑一周观察- 专用密钥:给备份单独生成一对 key,只做 rsync 用,和日常登录的 key 分开,丢了影响面小
- 先 dump 再同步:数据库文件直接 rsync 可能拷到一半的状态,先
mysqldump成 sql 文件再同步才靠谱 - 3 点执行:
0 3 * * * /root/backup.sh,业务低峰,传完天亮
恢复演练
备份了没演练过恢复,等于没备份。每季度我会随机挑一天,在备用机上把数据恢复出来看一眼能不能用。演练过两次,一次发现 dump 出来的 sql 有乱码(字符集问题),一次发现新加的数据目录没进备份列表——都是平时发现不了的坑。
备份的三个境界:有备份 → 备份能自动跑 → 备份能恢复出来。很多人停在第一层。
这套方案跑了一年多,传的都是增量,每天几分钟搞定,备用机上躺着 7 天的完整镜像。睡觉踏实多了。