备份与快照策略:数据不丢的最低成本方案
用 3-2-1 原则、几行脚本加一条 `cron`,就能让你的服务器数据在硬盘损坏、误删或勒索软件面前活下来。
服务器最贵的从来不是配置,而是里面的数据。硬件会坏、命令会打错、机房也可能出事。备份的目标很朴素:出事之后还能把数据找回来。这篇文章给你一套低成本、可照做的方案。
先记住 3-2-1 原则
一句话:至少 3 份数据,存在 2 种不同介质上,其中 1 份放在异地。
- 3 份:线上正在用的算 1 份,再加 2 份备份。
- 2 种介质:比如本机磁盘 + 对象存储,别把所有副本放在同一块盘上。
- 1 份异地:机房失火、账号被封,异地那份就是你最后的救命稻草。
这不是教条,而是把"单点故障"逐个消掉。
文件备份:tar 与 rsync
打包归档用 tar,适合做每天的整包快照:
tar -czf /backup/www-$(date +%F).tar.gz /var/www
增量同步用 rsync,只传变化的部分,速度快、省空间。--delete 让目标端与源端保持一致:
rsync -avz --delete /var/www/ /backup/www/
数据库备份:mysqldump
数据库不能直接拷文件(会拷到不一致的状态),要用逻辑导出。mysqldump 导出的是可重放的 SQL:
mysqldump --single-transaction -u root -p yourdb | gzip > /backup/db-$(date +%F).sql.gz
--single-transaction 保证在不锁表的情况下拿到一致快照。恢复时:gunzip < db.sql.gz | mysql -u root -p yourdb。
用 cron 定时自动跑
手动备份迟早会忘。把命令写进脚本,交给 cron 每天凌晨执行。运行 crontab -e 加一行:
# 每天 3:30 备份数据库,保留 7 天
30 3 * * * mysqldump --single-transaction -u root -pYOURPASS yourdb | gzip > /backup/db-$(date +\%F).sql.gz && find /backup -name 'db-*.sql.gz' -mtime +7 -delete
注意 cron 里的 % 要转义成 \%。用 find -mtime +7 -delete 自动清理旧备份,避免磁盘被撑满。
异地:推到对象存储
本机备份挡不住整机报废。把备份同步到对象存储(S3 兼容),用 rclone 或供应商 CLI:
rclone copy /backup remote:my-bucket/backup
再挂进上面的 cron,你就自动拥有了异地的那"1 份"。给存储桶开启版本控制,连误删和勒索加密都能回滚。
快照 ≠ 备份,但能配合
快照是某一时刻的整卷镜像,由云平台或文件系统(如 LVM、ZFS、Btrfs)生成,秒级完成、恢复快,适合升级或改配置前的"后悔药"。
但快照通常和原卷放在同一套存储里,底层故障会一起丢;而且它是全卷粒度,取不出单个文件。所以:快照用于快速回滚,备份用于长期、异地、可挑选地保命,两者互补,谁也替代不了谁。
定期做恢复演练
没验证过的备份等于没有备份。每月挑一次,把备份拉到一台干净机器上真正还原一遍:解压归档、导入数据库、启动服务、核对数据。记录下恢复用了多久(你的 RTO)。真正出事那天,你要的是肌肉记忆,不是第一次翻文档。
小结
备份不需要昂贵方案:tar/rsync 管文件,mysqldump 管数据库,cron 管定时,对象存储管异地,快照管快速回滚——再加上每月一次恢复演练。守住 3-2-1,你的数据就能在几乎任何意外面前活下来。