应综合Innodb_buffer_pool_reads与iostat -x 1的r_await/w_await判断I/O瓶颈,因%util和Innodb_os_log_pending_writes无时间维度,无法反映真实等待时长;r_await>10ms(SSD)或w_await>20ms(NVMe)、aqu-sz>4(NVMe)即表明I/O调度已成瓶颈。

直接看 Innodb_buffer_pool_reads 和 iostat -x 1 的 w_await/r_await,别信 %util 或 Innodb_os_log_pending_writes 单一数值——它们不带时间维度,无法换算真实等待时长。
为什么不能只看 SHOW GLOBAL STATUS 里的 IO 计数器
Innodb_buffer_pool_reads 是每秒从磁盘读取页的次数,Innodb_data_writes 是写操作次数,但它们本身不含耗时信息。比如 Innodb_buffer_pool_reads = 80,可能是 80 次 0.1ms 的 SSD 随机读,也可能是 80 次 15ms 的 HDD 寻道读——你完全无从区分。
- 真正反映“等待时长”的是 OS 层指标:
r_await(读平均等待毫秒)、w_await(写平均等待毫秒),必须用iostat -x 1实时抓取 -
Innodb_os_log_pending_writes只是 pending page 数量,值为 12 不代表延迟 12ms,它没时间戳、不累计、不区分刷盘策略 - 如果
Innodb_buffer_pool_read_requests很高但Innodb_buffer_pool_reads很低,说明基本没走磁盘,此时看任何“IO 等待”都无意义
怎么用 iostat -x 1 判断真实 I/O 等待压力
对 NVMe/SSD,%util 已失效,盯死 r_await、w_await 和 aqu-sz 这三项:
-
w_await > 20ms(NVMe)或> 10ms(SATA SSD):说明写请求在队列中排队太久,不是盘慢,是并发压过了调度能力 -
aqu-sz > 4(NVMe)或> 1(SATA SSD):平均队列深度超标,I/O 调度已成瓶颈 - 运行
iostat -x 1时,同时执行iotop -oP -p $(pgrep mysqld),确认高w_await是否真来自mysqld进程,而非备份或日志轮转等其他进程
如何关联 MySQL 内部状态与 OS 层等待
单看某一边容易误判。必须交叉验证:
- 当
iostat显示w_await持续偏高,且SHOW ENGINE INNODB STATUS\G中PENDING NORMAL AIO WRITES非零并缓慢下降 → 真实 IO 阻塞,不是瞬时抖动 - 若
LOG段中Log flushed up to和Log sequence number差值持续扩大(比如超 50MB),同时w_await高 → 日志写成为瓶颈,需检查innodb_flush_log_at_trx_commit和innodb_log_buffer_size - 用
lsof -p $(pgrep mysqld) | grep -E "(ib_logfile|ibdata|\.ibd)"确认高 await 对应的是ib_logfile0(日志)还是test/t1.ibd(数据文件),二者优化路径完全不同
Performance Schema 里能抓到“隐形”IO 等待源头吗
可以,但得绕过慢日志——很多高频小查询不慢却吃 I/O。关键表是 events_statements_summary_by_digest:
- 查磁盘读最多的语句:
SELECT DIGEST_TEXT, SUM_DISK_READS, AVG_TIMER_WAIT FROM performance_schema.events_statements_summary_by_digest WHERE SUM_DISK_READS > 0 ORDER BY SUM_DISK_READS DESC LIMIT 5 -
SUM_DISK_READS是该语句历史累计物理读页数,AVG_TIMER_WAIT是平均执行耗时(含等待),两者结合能看出是否“IO 等待主导了延迟” - 注意:MySQL 8.0.22+ 的
EXPLAIN FORMAT=JSON输出里有disk_reads字段,对单条语句预估更准,比等它进 digest 表更快
最易被忽略的一点:w_await 高不一定代表磁盘快挂了,可能只是 innodb_write_io_threads 设少了,或者 innodb_io_capacity 远高于磁盘实际随机写能力——调参前务必先用 iostat -x 1 看 aqu-sz 和 await 的联动关系,而不是盲目加线程或提 capacity。











