pv需接在mysqldump stdout管道中限速,正确格式为:mysqldump ... | pv -l 20m > backup.sql;单位必须带字母(如m),不可写成重定向后接pv,也不支持mysqldump原生命令限速。

mysqldump 备份时 IO 突增,pv 怎么接进管道?
直接用 mysqldump 输出到文件会持续高压读取表数据、写入磁盘,尤其在大库或机械盘上容易拖垮 r_await 和 aqu-sz。用 pv 限速不是加个参数就行,必须重构整个输出链路——它只能作用于管道流,不能对文件写入限速。
正确做法是把 mysqldump 的 stdout 通过管道交给 pv,再重定向到文件或压缩命令:
mysqldump --single-transaction --all-databases | pv -L 20m > backup.sql
注意三点:
-
pv -L 20m中的20m表示 20MB/s,单位必须带字母(k/m/g),否则按字节/秒理解,实际等于限速到 20B/s - 不能写成
mysqldump ... > backup.sql | pv -L 20m—— 重定向优先级高于管道,pv根本收不到数据 - 如果后续要
gzip,pv要放在gzip前:mysqldump ... | pv -L 20m | gzip > backup.sql.gz
为什么不用 --throttle 而选 pv?
--throttle 是 XtraBackup 专用参数,mysqldump 完全不识别。有人误以为加在 mysqldump 后面能生效,结果只是被当成了无意义的额外参数,备份照样全速跑。
而 pv 是通用流控工具,只要命令支持 stdout 输出,就能套进去。它不关心上游是什么,只管住字节流速率。实测中:
- 设
pv -L 10m后,iostat -x 1观察到wMB/s稳定在 9~11MB/s,aqu-sz从 8+ 降到 1.2 左右 - 同一台机器上,
mysqldump直接写文件时w_await常突破 50ms;加pv后回落至 5~8ms - 注意:若备份目标盘本身慢(如 USB 机械盘),
pv限速值设太高会触发缓冲区堆积,反而放大延迟
和 ionice 搭配用效果更好吗?
可以,但作用层面不同:ionice -c2 -n7 是降低进程 IO 调度优先级,让出磁盘时间片;pv -L 是硬性掐断数据流速。两者叠加不是简单相加,而是分层控制。
推荐组合方式:
- 低峰期小库:单用
pv -L 15m足够 - 高峰期大库(>100GB):先
ionice -c2 -n7降权,再套pv -L 8m,避免抢占其他业务 IO - 不要用
ionice -c3(idle class):MySQL 自身日志刷盘可能被饿死,导致innodb_log_waits上升
验证是否生效,盯住 iostat 的 %util(仅机械盘参考)和 aqu-sz:若 aqu-sz > 2 持续超过 10 秒,说明限速值还是偏高或磁盘已达瓶颈。
增量备份里 mysqlbinlog 能用 pv 限速吗?
能,但必须用对位置。常见错误是把 pv 加在 mysqlbinlog 命令末尾,比如:
mysqlbinlog --start-datetime="2026-04-13 02:00:00" mysql-bin.000001 | pv -L 5m > inc.sql
这样是对的。但注意:
-
mysqlbinlog默认输出是 base64 编码的 ROW 事件,pv限的是解码前的原始字节流,所以实际 SQL 写入速度会略低于设定值 - 若加了
-v参数,输出体积膨胀 3~5 倍,pv -L 5m实际 SQL 落盘可能只有 1MB/s 出头 - 更稳的做法是先用
--base64-output=DECODE-ROWS解码,再用pv,避免中间编码干扰流控精度
真正容易被忽略的是时区——mysqlbinlog --start-datetime 用的是 MySQL 服务器时区(SELECT @@system_time_zone),不是本地 shell 时区。错配会导致漏掉或重复拉取 binlog,pv 再准也没用。











