服务器自动备份实战:rsync 定时同步加历史快照,再也不怕丢数据

服务器自动备份实战:rsync 定时同步加历史快照,再也不怕丢数据
前年我把一台 VPS 上的数据库搞丢过一次。误删了一张表想着应该有备份吧结果翻遍了发现备份脚本半年前就因为磁盘满悄悄失败了。从那以后我给自己立了规矩任何上生产的数据必须有自动备份而且要定期验证能恢复。折腾过不少方案后现在稳定在用的一套是rsync 做文件级同步restic 做带历史版本的快照备份cron 定时跑加上一个失败告警。整套东西不复杂一台备用服务器或者家里的旧电脑就能当备份目的地。这篇把方案完整写出来系统以 Ubuntu 22.04 为例命令都可以直接抄。一、想清楚备份策略动手之前先明确三件事问题我的答案备什么数据库导出文件、网站目录、配置文件备到哪另一台机器异机备份同机备份等于没备留多久每日快照保留最近 7 天 最近 4 周 最近 6 个月3-2-1 原则值得记住至少 3 份副本、2 种不同介质、1 份异地。对普通玩家来说简化成生产机一份 另一台机器一份就已经能挡住绝大多数事故。二、准备备份机备份目的地要求很低能 SSH 连上、磁盘够大就行。家里的旧电脑、树莓派或者再开一台大硬盘低配云服务器都可以。我备数据库和网站文件那台是雨云rainyun-com的大硬盘款月付二十来块磁盘给得多注册填码2026off可领5折。这种只吃存储不吃性能的场景选机器时盯着磁盘容量和流量看就行CPU 内存无所谓。在生产机上生成一对专用密钥免密登录备份机ssh-keygen-ted25519-f/root/.ssh/backup_key-Nssh-copy-id-i/root/.ssh/backup_key.pub backup备份机IP三、第一步数据库先导出再备份直接拷贝数据库的数据目录是不可靠的文件处于打开状态拷出来可能损坏。正确做法是先导出成 SQL 文件。以 MySQL 为例建一个导出脚本/opt/backup/dump-db.sh#!/bin/bashDUMP_DIR/opt/backup/dbmkdir-p$DUMP_DIRmysqldump-uroot -p你的密码 --all-databases\--single-transaction--quick\|gzip$DUMP_DIR/all-$(date%F).sql.gz# 只留最近 3 天的导出文件防止本地占满find$DUMP_DIR-name*.sql.gz-mtime3-delete给执行权限并手动跑一次验证chmodx /opt/backup/dump-db.sh /opt/backup/dump-db.shls-lh/opt/backup/db/PostgreSQL 用户把 mysqldump 换成pg_dumpall即可思路一样。四、第二步restic 做快照备份restic 是一个开源备份工具去 GitHub 搜 restic 就能找到。它最大的优点是增量备份加去重每天跑一遍快照只存变化的部分还能随时回到任意历史版本。Ubuntu 仓库里直接有sudoaptupdatesudoaptinstall-yrestic在备份机上建好存放目录然后在生产机上初始化仓库通过 SFTP 走 SSHexportRESTIC_PASSWORD一串足够长的仓库密码 restic-rsftp:backup备份机IP:/home/backup/restic-repo init写备份脚本/opt/backup/backup.sh#!/bin/bashexportRESTIC_PASSWORD仓库密码REPOsftp:backup备份机IP:/home/backup/restic-repo# 先跑数据库导出/opt/backup/dump-db.sh# 打快照数据库导出、网站目录、配置restic-r$REPObackup\/opt/backup/db\/var/www\/etc/nginx\--exclude-caches# 清理策略留 7 天、4 周、6 个月restic-r$REPOforget--prune\--keep-daily7\--keep-weekly4\--keep-monthly6# 把结果写到日志方便排查echo$(date)backup done, exit$?/var/log/backup.logchmod x之后手动跑一次第一次是全量之后每天只传增量速度很快。五、第三步cron 定时执行编辑 crontabsudocrontab-e加一行每天凌晨 3 点 40 跑40 3 * * * /opt/backup/backup.sh /var/log/backup-cron.log 21选个网站流量低的时段即可。跑完后第二天记得看一眼日志确认没有报错。六、最关键的一步定期演练恢复没演练过恢复的备份等于没有备份。恢复其实很简单# 列出所有快照restic-rsftp:backup备份机IP:/home/backup/restic-repo snapshots# 把某个快照的 /var/www 还原到临时目录restic-rsftp:backup备份机IP:/home/backup/restic-repo\restore latest--target/tmp/restore--include/var/www我的习惯是每个月挑一个周末随便还原一个快照到临时目录解开 SQL 文件看一眼数据是否完整。十分钟的事换来的是真出事时不慌。常见问题问restic 和 rsync 到底用哪个rsync 适合镜像同步但它不留历史版本误删文件一同步备份也没了。restic 的快照模型更安全我的建议是主备份用 resticrsync 只用来快速同步静态大文件。问备份机带宽小会不会很慢首次全量确实慢可以先把数据用移动硬盘之类的方式弄到备份机上做本地 init之后再走增量。日常增量一天通常只有几十上百 MB小水管也够用。问仓库密码忘了怎么办restic 仓库加密基于这个密码忘了谁都解不开。把密码抄在纸上或者存进密码管理器别只留在服务器上——服务器没了密码也跟着没了那就尴尬了。总结整套方案下来就是mysqldump 导出、restic 快照、cron 定时、定期演练恢复四块拼在一起总配置时间不超过一小时。备份这种事平时感觉完全没用出事那天你会觉得这是自己做过最值的一小时投入。别等丢了数据才想起来搭今晚就动手吧。