rsync + cron 做每日增量备份:便宜、够用、能恢复

米阳 2023-9-9 4 9/9

备份这件事,最重要的不是技术方案多先进,而是“真的能恢复”。这套方案我用了两年,一次真故障中救回过数据。

要备份什么

  • 网站代码(其实不重要,能重新拉)
  • 上传的图片和附件(重要,不可再生)
  • 数据库(最重要,文章和配置都在里面)
  • 配置文件和证书(重要,重配很烦)

我的策略是:数据库每天导一次,文件用增量同步,保留 14 天。

数据库导出

#!/bin/bash
set -e
DATE=$(date +%F)
BACKUP_DIR=/root/backup/db
mkdir -p $BACKUP_DIR
mysqldump --single-transaction --quick --routines \
  -u kb_ro -p"$DB_PASS" wordpress \
  | gzip > $BACKUP_DIR/wordpress-$DATE.sql.gz
find $BACKUP_DIR -name "*.sql.gz" -mtime +14 -delete

--single-transaction 对 InnoDB 做一致性快照,不锁表,业务无感。--quick 逐行取数据,避免一次性把大表读进内存。

密码不要写在脚本里明文,从环境变量或权限 600 的配置文件读。

文件增量

rsync -az --delete \
  --exclude 'cache/' \
  --exclude '*.log' \
  /www/wwwroot/mi-blog.cn/wp-content/uploads/ \
  /root/backup/files/uploads/

-a 保留权限时间,-z 压缩传输,--delete 让目标与源一致(慎用,源目录被误删时目标也会删,所以最好本地保留快照而不是纯镜像)。

更稳的做法是配合硬链接快照,但脚本会复杂不少。对个人站点,14 天滚动已经够了。

定时

0 3 * * * /root/backup/db.sh >> /root/backup/backup.log 2>&1
30 3 * * * /root/backup/files.sh >> /root/backup/backup.log 2>&1

关键:异地

备份和数据在同一台机器上,等于没备份——磁盘坏了、机器被删了,数据一起没。至少要传到另一个地方:

rsync -az -e ssh /root/backup/ backup@另一台机器:/data/backup/

或者用对象存储:

ossutil cp -r /root/backup/db/ oss://bucket/backup/db/ --update

验证

备份脚本最容易出的问题是“每天在跑,但从来没成功过”。三条检查:

  1. 看日志里有没有 ERROR
  2. 检查文件大小是否合理(突然从 50M 变成 2K,说明导了个空库)
  3. 每月真恢复一次到临时库
gunzip -c wordpress-2023-09-08.sql.gz | mysql -u root -p test_restore

真恢复过一次,才会知道备份是否可用。我第一次演练就发现数据库账号权限不够,导出来少了三张表——脚本一直是“成功”状态。

结论

备份方案的价值 = 能恢复的概率 × 恢复的速度。花里胡哨不如简单可靠,把验证做成习惯,比升级工具更重要。

- THE END -

米阳

9月09日21:30

最后修改:2023年9月9日
0

非特殊说明,本博所有文章均为博主原创。

共有 0 条评论