问题出现得很突然,日志倒是留得挺全。腾讯云 2 核 4G 的 CentOS 7.9,每天凌晨把 MySQL 备份 gzip 后传到对象存储,一次真实恢复时 gunzip 报 unexpected end of file,往前翻七天的文件全是坏的,备份日志里只有上传成功。

刚开始盯着「上传用了分片但没做 MD5 校验」,折腾了半个多小时,排掉了。

原因不止一个,得分开看。备份脚本没检查 mysqldump 的退出码,管道中间失败也被当成成功。少数情况下是gzip 压缩时磁盘写满,文件被截断。

少数情况下是备份任务和清理任务并发,文件还没写完就被打包。

第一件事是验证现有备份能不能解开

for f in /data/bak/*.gz; do gzip -t $f || echo BAD $f; done

然后备份时开启 pipefail 并检查退出码

set -o pipefail; mysqldump -uroot -p app | gzip > app.sql.gz || exit 1

生成校验值随文件一起保存

sha256sum app.sql.gz > app.sql.gz.sha256

恢复前先校验再解压

sha256sum -c app.sql.gz.sha256 && gzip -dc app.sql.gz | head

怎么算真的好了,看的是同一批现象。所有备份文件 gzip -t 通过,sha256 校验一致,随机抽一份能完整导入测试库。

补一句。备份没做过恢复演练就等于没有备份,校验只能证明文件完整,能不能导入还得实际跑一遍。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189