我一开始的备份方式很原始:想起来就 cp -r 一下。结果就是——永远想不起来。
一套能睡安稳觉的备份,需要三个部分:可靠的工具 + 定时触发 + 失败通知。
为什么选 rsync
| 特性 | 说明 |
|---|---|
| 增量传输 | 只传变化的文件,第二次备份飞快 |
| 保留属性 | 权限、属主、时间戳一起同步(-a) |
| 可断点续传 | 网络断了重来只补差的部分 |
| 可删除同步 | --delete 让目标端和源端完全一致 |
核心命令
rsync -avz --delete \
/var/www/ \
/backup/www/
-a归档模式:递归 + 保留权限/属主/时间-v显示过程,-z压缩传输(走网络时有用)--delete源端删了的,目标端也删——注意方向别搞反
最容易出事的细节:源路径结尾的斜杠。
/var/www/ 表示"同步这个目录里的内容";/var/www 表示"同步这个目录本身"。差一个斜杠,备份结构就完全不同。写成脚本
#!/bin/bash
set -euo pipefail
SRC=/var/www/
DST=/backup/www/
LOG=/var/log/backup.log
STAMP=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$STAMP] 备份开始" >> $LOG
if rsync -az --delete "$SRC" "$DST" >> $LOG 2>&1; then
echo "[$STAMP] 备份成功" >> $LOG
else
echo "[$STAMP] 备份失败!" >> $LOG
# 这里可以接告警:发邮件、钉钉、企业微信机器人
exit 1
fi
几个关键点:
set -euo pipefail:出错就停,别让脚本带病继续跑if rsync ...:判断退出码,这是能加告警的前提- 日志带时间戳,出问题能回溯
挂到 cron 上
sudo chmod +x /opt/backup.sh
sudo crontab -e
# 每天凌晨 3:30 备份
30 3 * * * /opt/backup.sh >/dev/null 2>&1
五个字段分别是:分 时 日 月 周。
30 3 * * *= 每天 3 点 30 分
0 */6 * * *= 每 6 小时
0 2 * * 0= 每周日凌晨 2 点
最重要的一步:测试
没验证过的备份,等于没有备份。
# 1. 手动跑一次,看日志
sudo /opt/backup.sh && tail -5 /var/log/backup.log
# 2. 确认目标端真有数据
du -sh /backup/www/ && ls /backup/www/ | head
# 3. 真正恢复一次(关键!)
cp -r /backup/www/index.html /tmp/restore-test.html
运维铁律:备份的价值不在"备了",而在"能恢复"。
定期做一次恢复演练,比多备几份更有意义。
定期做一次恢复演练,比多备几份更有意义。
总结
- 用
rsync -az --delete做增量同步,注意结尾斜杠 - 脚本要判断退出码,才能加告警
- 用
crontab -e定时,注意 cron 的 PATH 环境和登录 shell 不一样 - 一定要做恢复演练