服务器上的 Halo 博客数据全在 MySQL 里。本地备份放在 /opt/1panel/backup,但本地备份不是备份 —— 硬盘挂了、系统被黑、误删目录,本地备份一样没。所以我给它加了一层:每天自动把备份传到腾讯云 COS。

现状

1Panel 本身有备份功能,但我的 MySQL 备份走的是另一条路:

  • 脚本:/opt/1panel/backup/mysql/backup.sh
  • 定时:系统 cron 30 3 *(每天凌晨 3:30)
  • 目标:COS 桶 dsh-server-backup-1253492961,前缀 mysql/YYYY-MM-DD/
  • 保留:脚本内置 COS_RETENTION_DAYS=90,自动清理 90 天前的

为什么绕开 1Panel?因为一开始是手动配的脚本,后来 1Panel 里也有了 COS 账号,两条路并存,互不冲突。

容量测算

这是我最关心的:会不会把 COS 撑爆?

实测每个备份文件约 1.07 MB。按每天一份算:

保留天数稳态占用
30 天约 32 MB
90 天约 99 MB
365 天约 395 MB

90 天保留完全够用。COS 的容量和请求次数对这点量来说几乎无感。

旧备份怎么清

你可能会问:COS 里已经有 6 份 MySQL 备份,能不能删掉 5 份只留最新?

技术上可以,但不建议。

  • 备份的价值在于「时间维度」。只留最新一份,万一数据是被慢慢污染的(比如某次迁移改错了数据,三个月后才发现),你就没有可回退的点。
  • 6 份 × 1.07 MB ≈ 6.4 MB,删掉 5 份省不到 5 MB,省的钱可以忽略,丢的保障很实在。
  • 脚本自带 90 天保留策略,到时间自动清,不需要手动删。

如果真要清理,用 COS 控制台按前缀 mysql/ 批量选,或者写个脚本按时间排序删。但请先想清楚:你是在省空间,还是在降低容灾能力?

在 1Panel 里也配一个 COS 账号

为了让面板备份也能用 COS,我在 /opt/1panel/db/1Panel.db 的 backup_accounts 表里加了一行:

type       = COS
bucket     = dsh-server-backup-1253492961
backup_path = /1panel
vars       = {"region":"ap-beijing","scType":"Standard"}

注意 backup_path 设成 /1panel,刻意避开脚本用的 mysql/ 前缀,这样两条路不会互相覆盖。

配置前先备份了数据库(10 MB 的 1Panel.db),出问题能还原。

教训

  • 备份的第一原则是「异地」。本地备份防误删,异地备份防灾难。
  • 保留策略比备份本身更重要。没有保留策略的备份,要么撑爆存储,要么被手动删光。
  • 算清楚容量再动手。1 MB/天 × 90 天 = 99 MB,这种量根本不用纠结。
  • 改数据库前先备份。1Panel 的 1Panel.db 也是 SQLite,cp 一份就能救命。
  • 两条备份路径并存时,用前缀隔离,别让它们互相踩。

备份这件事,平时没人注意,出事时它就是全部。