13 10 月 2026

服务器数据丢失的原因远比想象的常见:误删文件、程序写坏数据库、被勒索加密、磁盘损坏、升级失败、被入侵后恶意删除。

这篇讲清楚快照、镜像、文件备份、数据库备份四种手段的区别和组合用法,给出可以直接照抄的方案。

财富云计算 的云服务器支持快照功能,建议创建实例后立即开启自动快照策略。做内网服务与游戏服务端可选 NAT 型(无独立公网 IP,价格比独立 IP 机型省一半以上),同样支持快照与备份。

一、四种手段,别搞混

手段备份什么粒度恢复速度适合
快照整块磁盘的某个时间点状态磁盘级几分钟,回滚整个盘系统级回滚、误删文件、升级前保险
镜像整机的系统模板机器级几分钟,开新机器批量部署、环境复制
文件备份指定目录打包文件级拷回来即可网站文件、配置、存档
数据库备份SQL 逻辑导出表/库级导入即可数据库(最不能丢的)

核心原则:快照不是备份的全部,数据库必须有独立的逻辑备份。

原因:快照恢复是"整盘回滚",意味着恢复后所有数据都回到那个时间点——如果你只想找回一张表,快照帮不了你,反而会覆盖掉之后新增的正确数据。


二、3-2-1 备份原则

业界公认的备份法则:

  • 3 份数据副本(1 份生产 + 2 份备份)
  • 2 种不同介质(本地磁盘 + 对象存储/异地)
  • 1 份异地/离线(防机房故障、防勒索加密)

对个人和小团队来说,落地成:

生产数据(服务器本地)
   ├── 本地备份(服务器另一块盘,快速恢复)
   └── 异地备份(对象存储 / 另一台机器 / 网盘,防灾)

千万别只做本地备份——勒索软件会连备份一起加密,磁盘坏了备份也没了。


三、快照怎么用

什么时候打快照

场景是否打快照
系统升级前(apt upgrade、换内核)✅ 必打
大版本程序升级前(数据库、面板)✅ 必打
修改重要配置前✅ 建议
日常依赖自动快照策略
定期(比如每周)✅ 建议

快照的注意事项

  1. 快照不等于数据一致性保证:正在写数据库时打快照,恢复后可能遇到数据库损坏(概率低但存在)。重要数据库建议先停服务或执行 FLUSH TABLES WITH READ LOCK 再打。
  2. 快照会占用存储费用:保留策略要设好,别无限累积。
  3. 快照恢复是覆盖式的:恢复后当前数据会被替换,操作前确认清楚。
  4. 快照不能替代测试:定期做一次恢复演练,验证快照真的能用。

自动快照策略建议

业务类型频率保留
个人博客/测试环境每天 1 次保留 3~7 天
游戏服务端每天 1 次(在低峰期)保留 3~7 天
企业官网每天 1 次保留 7 天
电商/交易系统每 12 小时或更密保留 15~30 天,另加数据库日志备份

四、文件备份:rsync + tar

方案一:tar 打包(简单直接)

#!/bin/bash
# /usr/local/bin/backup_files.sh
DATE=$(date +%F)
BACKUP_DIR=/backup/files
SRC="/var/www/html /etc/nginx /etc/letsencrypt"
KEEP_DAYS=14

mkdir -p $BACKUP_DIR
tar -czf $BACKUP_DIR/files-$DATE.tar.gz $SRC 2>/dev/null

# 清理过期备份
find $BACKUP_DIR -name "files-*.tar.gz" -mtime +$KEEP_DAYS -delete

echo "备份完成: $BACKUP_DIR/files-$DATE.tar.gz"
chmod +x /usr/local/bin/backup_files.sh

方案二:rsync 增量(推荐,省空间省时间)

#!/bin/bash
# /usr/local/bin/backup_rsync.sh
SRC=/data/
DST=/backup/data/
LOG=/var/log/backup.log

rsync -a --delete \
  --exclude='cache/' \
  --exclude='*.tmp' \
  $SRC $DST >> $LOG 2>&1

echo "$(date) rsync 完成" >> $LOG

带时间戳的快照式备份(能回滚到任意一天,且增量只占差异空间):

#!/bin/bash
DATE=$(date +%F)
SRC=/data/
BASE=/backup/snapshots
LATEST=$BASE/latest

mkdir -p $BASE
rsync -a --delete \
  --link-dest=$LATEST \
  $SRC $BASE/$DATE/

rm -f $LATEST
ln -s $BASE/$DATE $LATEST

# 保留 30 天
find $BASE -maxdepth 1 -type d -name "20*" -mtime +30 -exec rm -rf {} \;

--link-dest 是精髓:相同的文件用硬链接指向上次备份,看起来每天都是完整备份,实际只占增量空间。

异地同步(rsync over ssh)

rsync -avzP --delete -e "ssh -p 2222" /backup/ root@备份机IP:/backup/

建议配 SSH 密钥,放进 crontab 自动跑。


五、数据库备份(最重要)

MySQL / MariaDB

# 单库
mysqldump -u root -p --single-transaction --routines --triggers --default-character-set=utf8mb4 dbname > db-$(date +%F).sql

# 全库
mysqldump -u root -p --single-transaction --all-databases --routines --triggers > all-$(date +%F).sql

# 只备份结构
mysqldump -u root -p --no-data dbname > schema.sql

# 只备份数据
mysqldump -u root -p --no-create-info dbname > data.sql

关键参数:

  • --single-transaction:InnoDB 表热备份,不锁表(必须加)
  • --routines --triggers:连存储过程和触发器一起备份
  • --master-data=2:主从场景记录 binlog 位置

压缩 + 自动脚本:

#!/bin/bash
# /usr/local/bin/backup_mysql.sh
DATE=$(date +%F)
DIR=/backup/mysql
USER=root
PASS='你的密码'
KEEP=30

mkdir -p $DIR
mysqldump -u$USER -p$PASS --single-transaction --routines --triggers \
  --all-databases | gzip > $DIR/all-$DATE.sql.gz

find $DIR -name "all-*.sql.gz" -mtime +$KEEP -delete
echo "$(date) MySQL 备份完成 $DIR/all-$DATE.sql.gz" >> /var/log/backup.log

⚠️ 密码写在脚本里有泄露风险。更安全的做法是建 ~/.my.cnf:

[mysqldump]
user=root
password=你的密码
chmod 600 ~/.my.cnf

之后脚本里直接 mysqldump --all-databases 即可。

恢复:

gunzip < all-2026-10-01.sql.gz | mysql -u root -p
# 或
mysql -u root -p dbname < db.sql

PostgreSQL

pg_dump -U postgres dbname > db.sql
pg_dumpall -U postgres > all.sql
# 恢复
psql -U postgres dbname < db.sql

Redis

# RDB 快照(自动触发,也可手动)
redis-cli BGSAVE
# 文件位置
redis-cli CONFIG GET dir
# 手动复制
cp /var/lib/redis/dump.rdb /backup/redis/dump-$(date +%F).rdb

大数据库用物理备份

数据量超过几十 GB 时,mysqldump 太慢,考虑:

  • Percona XtraBackup:InnoDB 物理热备,速度快很多
  • 主从复制:从库本身就是一份实时备份

六、备份自动化:cron 或 systemd timer

crontab -e
# 每天凌晨 2 点备份数据库
0 2 * * * /usr/local/bin/backup_mysql.sh

# 每天凌晨 3 点备份文件
0 3 * * * /usr/local/bin/backup_rsync.sh

# 每天凌晨 4 点同步到异地
0 4 * * * rsync -azP --delete -e "ssh -p 2222" /backup/ root@备份机:/backup/

# 每周日凌晨 5 点全量打包
0 5 * * 0 /usr/local/bin/backup_files.sh

更现代的方式是用 systemd timer(能记录日志、错过可补跑),见《systemd 服务编写与开机自启实战》。


七、异地/离线备份方案

方案成本做法
另一台云服务器中rsync 定时同步,最简单可靠
对象存储(S3/OSS/COS)低(按量)用 rclone/s3cmd 同步
本地 NAS / 移动硬盘低手动或定时拉取
网盘低rclone 挂载后同步

rclone 同步到对象存储

# 安装
curl https://rclone.org/install.sh | bash

# 配置(交互式)
rclone config

# 同步
rclone sync /backup remote:mybucket/backup --progress

# 只同步变化,带重试
rclone sync /backup remote:mybucket/backup \
  --transfers 8 --retries 3 --log-file /var/log/rclone.log

重要:开启版本控制/不可变备份。如果备份目标可被写入(或删除),勒索软件可能顺着同步把备份也删了。对象存储一般支持"版本控制"和"保留策略",开启后即使被覆盖也能找回历史版本。


八、备份一定要验证

没验证过的备份等于没备份。每月做一次恢复演练:

# 1. 找一台临时机器/目录
mkdir -p /tmp/restore-test

# 2. 解压
tar -xzf /backup/files-2026-10-01.tar.gz -C /tmp/restore-test

# 3. 导入数据库到测试实例
gunzip < /backup/mysql/all-2026-10-01.sql.gz | mysql -u root -p testdb

# 4. 检查数据条数、关键表内容
mysql -u root -p -e "SELECT COUNT(*) FROM testdb.users;"

检查清单:

  • [ ] 备份文件确实生成了(大小合理,不是 0 字节)
  • [ ] 备份文件能解压/导入
  • [ ] 恢复后数据条数对得上
  • [ ] 恢复的完整流程有文档,换个人也能操作
  • [ ] 恢复耗时可接受(关系到 RTO)

九、不同场景的备份方案

场景一:个人博客(Typecho/WordPress)

0 3 * * * mysqldump -uroot -p'xxx' typecho | gzip > /backup/typecho-$(date +\%F).sql.gz
10 3 * * * tar -czf /backup/www-$(date +\%F).tar.gz /var/www/html
20 3 * * * rclone sync /backup remote:blog-backup

加上每周一次云快照。

场景二:游戏服务端

存档是命根子,建议:

#!/bin/bash
# 停服 → 备份 → 启动(保证存档一致性)
systemctl stop cs2
tar -czf /backup/save-$(date +%F-%H).tar.gz /opt/steam/cs2/saves
systemctl start cs2

配合 systemd timer 每天低峰期执行。

场景三:企业业务

  • 数据库:每日全备 + binlog 实时(可恢复到任意秒)
  • 文件:rsync 增量到备份机
  • 异地:对象存储,开启版本控制
  • 快照:每日,保留 7 天
  • 每季度一次完整恢复演练

十、灾难恢复:真出事了怎么做

优先级:先恢复业务,再追查原因。

  1. 确认损失范围:是误删、是硬件故障、还是被入侵?
  2. 不要急着写入新数据:被误删的分区继续写会降低恢复成功率
  3. 选择恢复源:

    • 误删单文件 → 从文件备份里拿
    • 误删数据库表 → 从 SQL 备份里拿(不要整盘回滚)
    • 系统崩溃 / 升级失败 → 回滚快照
    • 被勒索加密 → 回滚快照 + 从异地备份恢复,并先排查入侵途径
  4. 恢复后验证:数据完整性、服务可用性
  5. 复盘:为什么会发生?如何避免?

被入侵的情况特别注意:恢复前必须先堵住入侵入口(改密钥、打补丁、封端口),否则恢复完又被打一遍。详见《服务器被入侵应急排查》。


十一、常见误区

误区正确做法
"有快照就够了"快照是整盘回滚,数据库仍需独立逻辑备份
"备份放在本机就行"磁盘坏了/被加密就没了,必须异地
"备份脚本写好就完事"要监控是否真的执行了,定期检查文件大小和日志
"从没验证过"至少每季度做一次恢复演练
"备份从不清理"会撑爆磁盘,设好保留策略
"数据库备份直接 mysqldump 不加参数"缺 --single-transaction 会锁表、数据不一致
"备份计划任务失败没人知道"加告警:备份失败发通知

给备份加失败告警:

#!/bin/bash
# 备份后检查
BACKUP=/backup/mysql/all-$(date +%F).sql.gz
if [ ! -s "$BACKUP" ]; then
  echo "备份失败!" | mail -s "备份告警" you@example.com
  # 或调用钉钉/企业微信 webhook
fi

数据无价,备份先行。财富云计算 的云服务器支持快照与镜像能力,建议开通后立即设置自动快照策略。做内网服务、游戏服务端、开发测试环境可选 NAT 型云服务器(无独立公网 IP,价格比带独立 IP 机型省一半以上),省下的预算正好用来做一份异地备份。

相关阅读:

  • 《systemd 服务编写与开机自启实战》
  • 《服务器资源排查:CPU / 内存 / 磁盘 / 带宽》
  • 《服务器被入侵应急排查与处置》
延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:服务器资源排查实战:CPU 爆了、内存满了、磁盘红了怎么办
  2. 下一篇:Nginx 安装与配置入门:从零搭建一个能访问的网站
发表评论 9

取消回复