必须确认的三个权限和配置项是:RAM子账号需具备oss:PutObject、oss:GetBucketLocation、oss:ListObjects权限;OSS endpoint必须与Bucket所在地域严格匹配;~/.ossutilconfig中accessKeyID和accessKeySecret须对应该RAM子账号且配置正确。

备份前必须确认的三个权限和配置项
直接用 ossutil 上传 MySQL 备份,失败八成卡在权限或配置上。不是命令写错,而是没跑通最基础的链路。
-
ossutil必须已配置好~/.ossutilconfig,且其中accessKeyID、accessKeySecret对应的是**有写入目标 Bucket 权限的子账号(RAM)**,主账号密钥不推荐直连生产环境 - 目标 OSS Bucket 需开启「读写权限」给该 RAM 用户,最小策略至少包含:
oss:PutObject、oss:GetBucketLocation、oss:ListObjects - 执行脚本的机器必须能访问公网(或阿里云内网,取决于 endpoint 设置),且
endpoint要匹配 Bucket 所在地域,例如杭州 Bucket 用https://oss-cn-hangzhou.aliyuncs.com,写成oss-cn-beijing就会报InvalidEndpoint
mysqldump + gzip + ossutil 三步链路怎么串才不丢数据
不能把 mysqldump 直接管道给 ossutil cp - —— 这样一旦网络抖动或 ossutil 退出,备份就截断且无校验。稳妥做法是先落盘再传,加时间戳和校验码。
- 用
mysqldump --single-transaction --routines --triggers导出,避免锁表;加上--set-gtid-purged=OFF(如果不用 GTID)防止恢复时报错 - 压缩必须用
gzip -c流式压缩,不要先生成大文件再 gzip:mysqldump -u root -p'xxx' mydb | gzip -c > /tmp/mydb_$(date +\%Y\%m\%d_\%H\%M\%S).sql.gz
- 上传后立即用
ossutil head检查对象是否存在,并用md5sum对比本地与 OSS 的 MD5(ossutil上传默认不计算 MD5,需手动加--meta md5=xxx或后续校验)
ossutil cp 命令里这几个参数不设就容易覆盖或超时
默认 ossutil cp 行为对备份场景很危险:不校验、不并发控制、不设超时,大文件上传中断后还得重来。
- 强制校验用
--check-md5,它会在上传前自动算本地文件 MD5 并写入 OSS Object Meta,下次可快速验证完整性 - 大库(>1GB)必须加
--parallel-num=5(默认是 3),但别盲目调高,超过 10 可能触发 OSS 单 IP 请求频率限制 - 加
--connect-timeout=60和--request-timeout=3600,否则默认 10 秒超时,导出+压缩耗时长的备份必失败 - 禁止覆盖已有文件:加
--update=false,否则定时任务重复跑一次,就把昨天的备份冲掉了
脚本里最容易被忽略的两个错误处理点
很多脚本只管“上传成功”,不管“上传了但内容损坏”或“磁盘满导致 dump 失败”。这两处不兜底,备份就是假象。
-
mysqldump命令后必须跟|| exit 1,否则即使 dump 报错(如权限不足、表不存在),脚本仍继续执行 gzip 和上传,结果传了个空文件 - 上传完成后,用
ossutil ls oss://my-bucket/path/ | grep -q "$(basename $local_file)"确认文件已列出,再用ossutil head oss://... | grep 'Content-Length'检查大小是否非零——有些失败上传会留个 0 字节空对象 - 临时文件(.sql.gz)务必在上传成功后才
rm,且加trap 'rm -f $tmpfile' EXIT防止脚本异常中断导致磁盘被占满
oss:GetBucketLocation(导致 ossutil 连不上)、以及忘记 --update=false 导致定时任务互相覆盖。这些都不是技术难点,但排查起来特别费时间。


















