用 iostat -x 1 查 %util>80% 且 await>10ms 可定位磁盘 I/O 瓶颈;需结合 svctm、r/s、w/s 及 MySQL 的 Innodb_data_reads 交叉验证,并开启 log_slow_extra=ON 查 InnoDB_IO_r_ops 等 I/O 指标。

如何用 iostat 快速定位 MySQL 的磁盘 I/O 瓶颈
直接看 iostat -x 1,重点关注 %util(设备忙时百分比)和 await(I/O 平均等待毫秒数)。如果 %util 持续 >80% 且 await >10ms,基本可判定是磁盘响应拖慢了 SQL 执行——但注意,这不等于就是 MySQL 导致的,可能是其他进程(如备份、日志轮转)在争抢 I/O。
实操建议:
- 在业务高峰期运行
iostat -xmd 1(-m输出 MB/s,-d仅显示设备),持续观察 2–3 分钟,避免单次抖动误判 - 对比
svctm(服务时间)和await:若await ≫ svctm,说明 I/O 队列积压严重,不是磁盘本身慢,而是请求太多或队列深度不足 - 检查
r/s和w/s是否突增,再结合 MySQL 的SHOW GLOBAL STATUS LIKE 'Innodb_data_reads'等指标交叉验证读写压力来源
慢日志里哪些字段能反映 I/O 开销
MySQL 慢日志(slow_query_log)默认不记录 I/O 细节,必须开启 log_slow_extra=ON(MySQL 8.0.26+)才能看到 Rows_examined、Lock_time、Rows_sent 之外的关键字段:InnoDB_pages_distinct 和 InnoDB_IO_r_ops(实际读页次数)、InnoDB_IO_r_bytes(读字节数)。
实操建议:
- 不要只盯着
Query_time:一个Query_time=0.8s但InnoDB_IO_r_ops=12000的查询,大概率是全表扫描或索引失效;而Query_time=1.2s但InnoDB_IO_r_ops=3的,问题可能在锁等待或网络 - 用
mysqldumpslow -s ar -t 10 /var/lib/mysql/slow.log按平均读页数排序,快速揪出“IO 最狠”的 Top 10 查询 - 注意
InnoDB_pages_distinct:值接近InnoDB_IO_r_ops说明缓存命中率极低;若远小于后者(比如 50 vs 5000),说明大量重复读同一页面,可能是小缓冲池 + 大范围扫描
为什么 iostat 显示高 I/O,但慢日志里没几条慢 SQL
常见于两类场景:一是大量短查询堆积(单条 innodb_io_capacity 调度的脏页刷盘、log_writer 写 redo)占用了磁盘带宽。
实操建议:
- 查
SHOW ENGINE INNODB STATUS\G中的LOG和FILE I/O部分,看pending log writes或pending file reads/writes是否非零 - 运行
pt-ioprofile --profile-pid=$(pgrep -f "mysqld")(需 Percona Toolkit),直接抓取 mysqld 进程的实时 I/O 调用栈,定位是read()还是pwrite64()占主导 - 临时调低
innodb_io_capacity(如从 2000 改为 400),观察iostat是否缓解——若明显下降,说明是 InnoDB 主动刷脏页引发的 I/O 压力,而非用户 SQL 直接导致
排查时最容易被忽略的配置与路径
很多团队卡在“iostat 看到 sda 高负载,但不确定是不是 MySQL 在读”,根本原因是没确认 MySQL 实际使用的物理设备路径。尤其是 LVM、RAID、云盘挂载后设备名易混淆。
实操建议:
- 用
ls -l /proc/$(pgrep mysqld)/fd/ | grep "/var/lib/mysql" | head -5查 MySQL 打开的数据文件路径,再用df -h /var/lib/mysql和lsblk追踪到底层设备(比如/dev/nvme0n1p1而非/dev/sda) - 检查
innodb_flush_method:若设为O_DIRECT,iostat 统计的是真实磁盘 I/O;若为fsync或空值,部分 I/O 可能被 page cache 缓冲,iostat 数值偏低但内核态压力仍在 - 云环境特别注意:EBS gp3 的
iops是按吞吐量(MB/s)和 IOPS(每秒操作数)双指标限速的,iostat的rkB/s接近上限时,即使%util不高也会触发限速,表现为await突增
真正难的不是看懂 iostat 或解析慢日志,而是把设备层、文件系统层、InnoDB 存储引擎层、SQL 执行层这四层的指标串起来——漏掉任意一层,结论都可能南辕北辙。


















