阿里云 ECS 上 ESSD PL1 单盘标称三千 IOPS,MySQL 和 xtrabackup 都放在 /data,每天两点备份一开始接口 P99 就从 5ms 抖到 200ms,iostat 里 await 由 0.8ms 跳到 40ms,备份结束立刻恢复。

一开始怀疑是「InnoDB 的脏页被 checkpoint 推着回写,两股流量恰好撞在同一时段」,查了一圈,方向不对。

真正麻烦的地方在于,几个原因的现象几乎一样。备份是顺序大读,把云盘的 IOPS 和吞吐额度吃满,MySQL 的写请求只能排队。另一种情况是云盘的突发额度平时攒着,被备份一次用光后掉回基线,后续读也跟着慢。

另外,没有做 cgroup io.max 或者 ionice 隔离,两个进程在同一队列里同级抢。

第一件事是确认抖动时段是不是备份在跑

iostat -x 1 10 | awk 'NR>3 {print $1, $10, $11}'

给备份进程降 IO 优先级

ionice -c2 -n7 -p $(pgrep -f xtrabackup | head -1)

再往下把备份限速后再观察一轮

xtrabackup --backup --throttle=100 --target-dir=/data/bak/full

末了用 cgroup 给备份单独限读带宽

systemd-run --scope -p IOReadBandwidthMax='/dev/vdb 100M' /usr/bin/xtrabackup --backup

恢复的判定其实很直接。备份窗口内 iostat 的 await 稳定在 5ms 以下,接口 P99 不再超过 30ms,云盘的突发余额在备份结束后还有剩余,第二天同一时段不再复现。

容易忽略的是,限速要按业务低谷的真实余量给,压得太低备份跑不完会拖进早高峰;数据库和备份放同一块盘本身就不合适,加一块盘做本地备份目录收益比调参数大。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189