第一次把备份传到华为云 OBS,obsutil 折腾了我一下午
上个月有天早上,我那台华为云 ECS 弹了磁盘告警。登上去一看,MySQL 的每日备份攒了小半年,全在 /data/backup 里,单个文件不大,加起来快 40G。本地留着占地方,删了又不放心,琢磨来琢磨去,决定挪到对象存储上。ECS 和 OBS 都在华为云,内网传应该不花流量钱,这事听着挺顺。
先装 obsutil,别用错版本
OBS 官方有个命令行工具叫 obsutil,Linux 上直接下个二进制就能跑。我一开始图省事,在网上搜了个第三方教程,照着装了个老版本,结果 obsutil config 的时候报错说配置文件格式不对。后来去官方文档翻了一下,发现新版改了配置方式,老教程全对不上了。
正确做法是去 OBS 的工具下载页拿最新版,解压出来就是一个可执行文件:
cd /opt
wget https://obs-community.obs.cn-north-1.myhuaweicloud.com/obsutil/current/obsutil_linux_amd64.tar.gz
tar -zxf obsutil_linux_amd64.tar.gz
cd obsutil_linux_amd64_*/
cp obsutil /usr/local/bin/
obsutil version
装完第一件事是配 AK/SK。注意这一步有个细节:obsutil config 默认把配置写到 ~/.obsutilconfig,权限是 600,这个没问题。但我当时是在 root 下配的,后来备份脚本放在普通用户的 crontab 里跑,死活报认证失败。查了半天才发现是配置文件归属的问题——普通用户读不到 root 家目录下的配置。最后的办法是脚本里显式指定配置文件路径:
obsutil config -i=你的AK -k=你的SK -e=https://obs.cn-north-4.myhuaweicloud.com -c=/etc/obsutil/config
-c 参数可以指定配置文件位置,放到 /etc/obsutil/ 下,权限收紧到只有备份用户能读。这一步我折腾了快一个小时,就因为没往权限上想。
endpoint 写错一个字,报错能把人绕晕
配完信心满满跑了个上传测试:
obsutil cp /data/backup/mysql-20261110.sql.gz obs://my-backup-bucket/db/
结果报错,大意是桶不存在。我明明在控制台上刚建好桶,名字也复制粘贴的,不可能错。反复核对了三遍桶名,又去控制台确认桶确实存在,还是报这个错。
后来才反应过来:endpoint 的区域写错了。我的桶建在华北四(cn-north-4),但我抄教程的时候顺手写了 obs.cn-north-1.myhuaweicloud.com。obsutil 不会告诉你"区域不对",它只会说桶不存在——因为在华北一那个区域里,这个桶确实不存在。这报错一点都不直白。
改对 endpoint 之后上传一次就通了。教训就一条:建桶的时候看清楚区域,endpoint 里的区域必须和桶的区域一字不差。控制台建桶页面右上角会显示区域,复制的时候别凭印象写。
大文件上传,默认配置慢得离谱
小文件传上去之后,我试了个 2G 多的备份文件。上传速度慢得让我怀疑人生,跑了十几分钟进度条才挪了一点。查了一下,obsutil 默认是单线程上传,大文件得开分片。
加上分片参数之后速度一下就上来了:
obsutil cp /data/backup/mysql-20261110.sql.gz obs://my-backup-bucket/db/ \
-u -f -bigfile-threshold=50 -parallel=5
-bigfile-threshold=50 的意思是超过 50MB 就走分片上传,-parallel=5 是 5 个并发。还有个 -u 是增量上传,已经传过且没变过的文件会跳过,-f 是强制覆盖。这两个参数配在一起,日常备份就只要传新增的部分。
不过并发数别贪多。我一开始设了 10,ECS 是 2 核 4G 的小机器,CPU 直接被打满,还影响了上面跑的业务。5 个并发对这台机器来说刚好,备份窗口也够。
生命周期规则配了三天没生效
备份传上去了,新的问题又来了:桶里的文件只会越攒越多,得有个自动清理的规则。我在控制台配了个生命周期规则——30 天后转低频存储,90 天后删除。当时觉得这事就完了。
结果三天后去看,文件一个没少,存储类型也没变。我以为规则配错了,把规则删了重配一遍,又等了一天,还是没动静。最后去翻文档才发现,生命周期规则每天只在固定时间跑一次,而且规则只对"规则生效之后"满足条件的文件起作用。更关键的一点:我配规则的时候,对象名前缀写的是 db/,但实际上传路径是 db/mysql-...,前缀是对的。真正的问题出在别处——我当时选的是"对整个桶生效",控制台上看着没问题,实际上规则保存后要等到第二天凌晨才开始执行,第一天去看的时候它根本还没跑过。
等到第四天早上再看,30 天前的文件已经转了低频存储。这事没别的办法,就是得等,别急着删了重配,越改越乱。
最后定下来的备份流程
现在每天凌晨 2 点,crontab 跑这么个脚本:
#!/bin/bash
set -e
DATE=$(date +%Y%m%d)
BACKUP_DIR=/data/backup
mysqldump -u backup -p'密码放这里不合适,实际用的配置文件' --all-databases | gzip > $BACKUP_DIR/mysql-$DATE.sql.gz
obsutil cp $BACKUP_DIR/mysql-$DATE.sql.gz obs://my-backup-bucket/db/ -u -f -bigfile-threshold=50 -parallel=5
find $BACKUP_DIR -name "mysql-*.sql.gz" -mtime +7 -delete
流程就三步:本地先备份打包,传到 OBS,本地只留最近 7 天的。这样本地磁盘压力没了,云上还有 90 天的留存,真要恢复的时候从 OBS 拉回来就行。
费用这块我也算过:这台 ECS 和桶都在华北四,走内网 endpoint 传数据不收流量费。存储费按量算,40G 的标准存储一个月也就几块钱,转低频之后更便宜。比起再买一块云硬盘挂上去,划算不少。
这一下午我记住的几件事
- obsutil 装最新版,别照着网上老教程配,老版本的配置方式已经变了。
- AK/SK 配置文件的归属和权限要和跑脚本的用户对上,认证失败先查这个。
- endpoint 里的区域必须和桶的区域一致,对不上就报"桶不存在",别被这个报错带偏。
- 大文件开分片上传,并发数按机器配置来,小机器别贪多。
- 生命周期规则生效要等第二天,别急着删了重配。
- 点赞
- 收藏
- 关注作者
评论(0)