很多站长把 VPS 用起来之后,注意力几乎全放在"网站能不能跑、跑得快不快"上,很少有人认真想过另一个问题:这台机器上的数据,到底靠什么兜底?代码、数据库、上传的图片、Nginx 配置、SSL 证书,全部堆在同一台机器上。磁盘坏了、系统被入侵、甚至商家跑路,任何一种情况都可能让几年的积累在几分钟内归零。备份这件事,平时看不出任何价值,真到需要恢复的那一天,才知道它是最后的救命稻草。本文按真实操作顺序,把 VPS 备份的方案设计、定时任务配置、异地副本同步,以及整机迁移到新服务器的完整流程一次讲清。
一、先想清楚:你的数据到底有几类
动手备份之前,先别急着写脚本,而是把服务器上的数据分一下类。分类的目的是让恢复时"各归其位",不然一锅端地打包,出了问题时反而不知道怎么还原。对绝大多数站长来说,VPS 上的数据无非三类:
- 网站代码与静态文件:一般放在 /var/www 下,包括程序源码、主题、上传的图片附件。
- 数据库:MySQL、MariaDB 或者 SQLite,网站的内容、评论、配置参数都在这。
- 配置文件:Nginx 虚拟主机配置、PHP 配置、Cron 定时任务、SSL 证书目录,这些往往最少,但丢了最麻烦。
三类数据分开备份、分开保留,恢复的时候才知道每个文件该放到哪里。下面就从最关键的数据库开始。
二、数据库定时备份:mysqldump + Crontab
数据库是网站的灵魂,也是恢复成本最高的部分,所以优先备份、每天备份。最稳妥的做法是写一个脚本,用 mysqldump 把全部数据库导出并压缩,然后交给 Crontab 定时执行。先创建备份目录和脚本:
mkdir -p /root/backup/mysql nano /root/backup/mysql_backup.sh
脚本内容如下,导出全部数据库并 gzip 压缩,同时自动清理,只保留最近 14 份,避免磁盘被备份文件占满:
#!/bin/bash # MySQL 每日备份脚本 BACKUP_DIR=/root/backup/mysql DB_USER=root DB_PASS='换成你的数据库密码' DATE=$(date +%Y%m%d_%H%M%S) mkdir -p $BACKUP_DIR mysqldump -u$DB_USER -p$DB_PASS --all-databases --single-transaction | gzip > $BACKUP_DIR/all_$DATE.sql.gz # 只保留最近 14 份,自动清理过期备份 ls -t $BACKUP_DIR/*.sql.gz | tail -n +15 | xargs rm -f
给脚本加执行权限,然后写入定时任务,每天凌晨 3 点运行一次(这个时段访问量低、数据库压力小):
chmod +x /root/backup/mysql_backup.sh crontab -e
在 crontab 里追加一行,并把输出写入日志,方便日后排查:
0 3 * * * bash /root/backup/mysql_backup.sh >> /var/log/backup.log 2>&1
第一次执行之前,先手动跑一遍脚本,确认生成的 .sql.gz 文件非空、能正常解压,再交给定时任务,避免"任务一直在跑、备份一直是坏的"。如果是宝塔面板,也可以在计划任务里添加 Shell 脚本,效果一样,还多了个可视化日志。
三、网站文件与配置打包备份
数据库之外,网站文件和配置文件同样要备份。用 tar 打包,注意排除缓存和临时目录——这些目录内容可以随时重建,备份它们只会浪费空间和时间。示例命令:
tar -czf /root/backup/www_$(date +%Y%m%d).tar.gz \ --exclude='/var/www/*/runtime' \ --exclude='/var/www/*/cache' \ --exclude='/var/www/*/tmp' \ /var/www /etc/nginx /etc/php /etc/cron*
把这条命令也写进同一个定时脚本,或者单独加一行 crontab。备份文件建议按"类型_日期"命名,恢复时一眼就能看出这是哪一天的哪类数据。
四、异地备份:把副本送出这台机器
这里要强调一个很多新手会踩的坑:备份放在同一台机器上,等于没有备份。磁盘损坏、系统被入侵,本地备份会跟原始数据一起完蛋。所以备份一定要"异地"。
最常见的做法是同步到对象存储,比如阿里云 OSS、腾讯云 COS、Cloudflare R2,或者各类网盘。用 rclone 一条命令就能完成:
rclone sync /root/backup remote:backup/vps1 --transfers 4
rclone 配置一次之后,可以把它追加到每日的备份任务末尾,实现"本地备份 + 自动异地同步"的完整链路。如果预算紧张,备选方案是用 rsync 把备份推送到另一台 VPS 或者家里的 NAS:
rsync -avz --delete /root/backup/ root@另一台机器IP:/backup/vps1/
备份中包含数据库和站点源码,属于敏感数据,同步到第三方存储前建议先加密(例如用 gpg 对称加密),并妥善保管密钥,防止备份文件本身泄露。
五、恢复演练:备份是否可用,试过才知道
备份最大的谎言是"我以为备份是好的"。定期做一次恢复演练,才能确认备份文件完整、命令可用、流程顺畅。演练流程很简单,可以选一台闲置的测试机,或者直接在本地环境操作:
- 从备份中解压最新的数据库文件,用 zcat 还原:
zcat all_20261031_030001.sql.gz | mysql -u root -p - 解包网站文件到对应目录,恢复 Nginx 配置并 reload。
- 打开网站验证首页、文章、图片、后台登录是否全部正常。
- 确认无误后记录本次演练的时间与结论。
强烈建议每季度至少演练一次,并把恢复步骤写成文档。真出事那天,照着文档一步步操作,远比临场回忆命令可靠。
六、整机迁移实战:从旧 VPS 无缝搬到新 VPS
备份练好了,迁移就只是备份的延伸。换机器、升级配置、商家到期续费不划算,都可能需要把整站搬到新 VPS。这里给出一个可复现的操作顺序:
第一步:环境对齐。先确认新旧两台机器的系统版本、PHP 版本、数据库版本一致或兼容,差异太大会导致迁移后出现莫名其妙的报错。
第二步:同步网站文件。用 rsync 全量同步并保留权限属性:
rsync -avz --progress /var/www/ root@新VPS_IP:/var/www/
第三步:迁移数据库。导出后直接通过 SSH 管道导入,一步完成:
mysqldump -u root -p --all-databases --single-transaction | ssh root@新VPS_IP "mysql -u root -p"
第四步:迁移配置与证书。把 Nginx 配置、PHP 配置、SSL 证书目录(如 /etc/letsencrypt)整体复制过去,并逐一核对伪静态规则是否生效。
第五步:切换解析。在新机器上确认网站访问正常后,把域名解析切换到新 VPS 的 IP。因为解析生效有延迟,建议旧机器保留观察 24~48 小时再下线,期间可以用 hosts 文件强制解析到新 IP 先行测试。
结语
备份和迁移都不是一次性的动作,而是一种习惯:脚本写清楚、定时任务配上、异地副本留好、每季度做一次恢复演练。做完这些,你的网站才算真正"踏实"了。下一次遇到突发情况,你会感谢今天动手做过这一切的自己。