前阵子朋友的一台云服务器系统盘突然出现坏道转为只读,虽然后面工单救回了一部分数据,但当时大家冷汗都冒出来了。我自己手头几个轻量服务器之前虽然也配了宝塔的定时备份,但默认全部扔在本地 /www/backup 目录下,一旦母机故障或者本地云盘损坏,这种备份其实等于裸奔。
趁着周末有空,我把手头几个站点的整站源码和 MySQL 数据库全部调成了定时自动打包并上传到对象存储,顺带配好了保留周期。把这套跑顺了的配置逻辑和几个需要注意的细节记下来,留作备忘。
1. 为什么不建议只放在本地磁盘
很多人刚搭好网站,在宝塔计划任务里设个每天凌晨备份网站和数据库就觉得高枕无忧了。实际上本地备份存在两个明显的隐患:
一是容灾能力差。如果服务器系统盘崩溃、误执行了破坏性命令,或者机器被机房黑洞下线,备份和源文件都在同一个物理/虚拟磁盘上,根本拿不出来。
二是容易不知不觉塞满磁盘。网站运行一段时间后,上传的图片和数据库都会变大,如果本地保留份数稍多,备份文件会越滚越大,一旦磁盘被占满到 100%,MySQL 就会直接挂掉,甚至导致 SSH 无法写入临时文件而登录失败。
对象存储(如阿里云 OSS、腾讯云 COS、七牛云或兼容 S3 协议的存储)存储单价非常便宜,普通博客一年几块钱的存储费用就足够,天然自带多副本冗余,是目前成本最低也最稳妥的异地备份方案。
2. 存储桶配置与子账号权限
在宝塔面板的软件商店里,搜索你所使用的云厂商对象存储插件(例如“腾讯云 COS”、“阿里云 OSS”或通用的“通用 S3 存储”),安装完成后需要填写 Bucket、访问密钥和所属地域。
这里有一个必须遵守的安全习惯:绝对不要直接使用云账号的主密钥(Root AccessKey)。
- 在云厂商后台新建一个专门的 RAM/CAM 子账号。
- 只给这个子账号授予对应存储桶的读写权限(PutObject、GetObject、DeleteObject 等),不要给其他任何云资源的权限。
- 存储桶本身的访问权限务必设为“私有读写”,千万不要设为公共读,否则备份出来的数据库压缩包一旦被扫到,整站数据直接泄露。
3. 备份频率与保留份数参考
不同类型和体量的站点,备份策略应该有所区分。如果是每天都有更新的内容站,数据库的变动频率远高于整站源码;如果是静态居多的站点,完全没必要天天全量打包文件。
| 站点类型 | 备份内容 | 执行频率 | 保留份数 | 执行时间建议 |
|---|---|---|---|---|
| 个人博客 / 小型展示站 | 网站文件 数据库 | 每周 1 次 每天 1 次 | 文件留 3 份 数据库留 14 份 | 凌晨 03:00~04:00 |
| 交互类站点 / 活跃社区 | 网站文件 数据库 | 每 3 天 1 次 每天 2 次 | 文件留 7 份 数据库留 30 份 | 凌晨 02:30 / 中午 14:00 |
| 资源下载 / 包含大量媒体 | 排除媒体目录 数据库 | 每周 1 次 每天 1 次 | 文件留 2 份 数据库留 7 份 | 凌晨 04:30 |
在宝塔的“计划任务”中添加任务,任务类型选择“备份网站”或“备份数据库”,备份提醒选择对应的对象存储插件名称,同时务必设置好“保留最新的 X 份”,插件在上传新备份后会自动向云端发起清理指令,把超出份数的旧文件删掉,防止对象存储费用持续增长。
4. 几个容易踩坑的细节
实际跑这套自动化备份时,有几个地方容易出现静默失败:
- 本地剩余磁盘空间必须大于打包体积:宝塔备份到对象存储的底层逻辑,是先在本地
/www/backup目录下将文件或数据库导出并压缩成 tar.gz/sql.gz,上传成功后再把本地临时文件删掉。因此,如果你的服务器磁盘只剩 2G,而网站打包出来有 3G,备份任务会在打包阶段直接报错退出,根本不会触发上传。 - 数据库过大导致 PHP 超时:如果数据库体积超过 1G,面板执行 mysqldump 和压缩的时间可能超过默认的超时阈值。如果发现计划任务日志里提示超时中断,需要去面板设置中适当调大脚本超时时间。
- 大体积静态目录一定要排除:如果网站的
uploads目录下存放了十几 G 的视频或压缩包,千万不要每次都全量打包。可以在计划任务中设置排除目录规则,把大文件目录剔除,这类大静态文件建议直接上云存储托管,或者用 rsync 另做增量同步。 - 务必定期做一次还原验证:备份只做了一半工作,隔几个月最好挑一个空闲时间,从对象存储下载一个最近的数据库包,在本地或测试机导入一下,确认导出的 SQL 结构完整无乱码。能正常恢复的备份才算有效备份。