需交叉验证云监控与MySQL内部指标:当iostat的w_await超阈值(SSD>10ms/NVMe>20ms)且Innodb_data_writes每秒持续>800,或云监控avgqu-sz>4同时InnoDB STATUS显示Pending aio不为0,或await飙升但Innodb_buffer_pool_reads很低,则可确认IO真实瓶颈。

怎么用云监控+MySQL内部指标交叉验证IO是否真瓶颈
公有云上自建 MySQL 的磁盘 IO 问题,不能只信云平台的“磁盘读写 MB/s”图表——它统计的是块设备层吞吐,但 MySQL 实际压力可能来自小 IO、高延迟或锁队列。必须把云监控指标和 MySQL 内部状态对齐。
关键交叉点有三个:
-
iostat -x 1的w_await> 20ms(NVMe)或 > 10ms(SATA SSD),同时Innodb_data_writes每秒持续 > 800,基本可确认写 IO 压力真实存在 - 云监控里“磁盘队列长度”持续 > 4,而
SHOW ENGINE INNODB STATUS\G中FILE I/O段显示Pending normal aio reads/writes不为 0,说明 InnoDB 刷脏或预读跟不上 - 云监控“平均IO等待时间”飙升,但
Innodb_buffer_pool_reads很低,那瓶颈大概率在日志(ib_logfile*或mysql-bin.*),不是数据文件
为什么云厂商的“磁盘使用率”告警对MySQL IO没用
云控制台里“磁盘使用率 > 90%”告警,只管空间满不满,完全不反映 IO 能力耗尽。一块 1TB 云盘,使用率才 40%,但 IOPS 已打满,await 拉到 50ms,查询全卡住——这时你收不到任何告警。
真正该设告警的,是这些云监控中实际暴露底层 IO 能力的指标:
- “平均每次IO等待时间”(即 await),阈值按介质设:SSD 设 10ms,NVMe 设 20ms
- “每秒IO请求数”(IOPS),对比你购买的云盘规格上限(比如某云 NVMe 盘标称 50K IOPS,告警阈值设 45K)
- “IO队列平均长度”,超过 4 就要预警,尤其当
avgqu-sz和await同步上涨时 - 别设“磁盘读写带宽”绝对值告警——MySQL 小 IO 多,带宽可能很低但延迟爆炸
怎样从Performance Schema里揪出“不慢却吃IO”的SQL
慢查询日志漏掉的,往往是那些执行快(performance_schema.events_statements_summary_by_digest 里才显形。
直接查磁盘读最狠的前 5 条:
SELECT DIGEST_TEXT, SUM_DISK_READS, COUNT_STAR, 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是累计值,需对比两次采样差值看每秒增量;别只看总量 - 如果
DIGEST_TEXT是SELECT COUNT(*) FROM t这种,且COUNT_STAR极高,基本就是全表扫描在后台默默拖垮 IO - MySQL 8.4 默认开启
performance_schema,但events_statements_history_long默认关闭,如需回溯,得提前开:UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME = 'events_statements_history_long';
云环境里 lsof + iostat 定位具体文件为啥经常失效
在公有云上跑 lsof -p $(pgrep mysqld),常看到一堆 /var/lib/mysql/xxx.ibd,但 iostat -x 1 却对不上哪个文件在扛压——因为云盘是虚拟块设备,底层做了多层抽象(如 Ceph RBD、EBS 卷网关),lsof 显示的是文件路径,iostat 统计的是后端裸设备,二者不在同一层级。
更靠谱的做法是绕过文件路径,盯住三类高危文件的 OS 层行为:
- redo log:
ls -la /var/lib/mysql/ib_logfile*,用iotop -oP -p $(pgrep mysqld)看进程 IO > 列是否稳定在高位(> 30MB/s),这比看文件名准 - binlog:
ls -la /var/lib/mysql/mysql-bin.*,若sync_binlog=1且写入频繁,它会成为 IO 热点,此时Innodb_log_writes和Binlog_cache_disk_use要一起看 - 临时文件:
ls -la /tmp/ib* /var/tmp/ib*,Created_tmp_disk_tables上涨快,说明排序或 group by 溢出,不是数据文件问题,而是内存配置不足
真正难缠的,是那些没名字的 IO——比如 buffer pool 刷脏产生的异步写,它不对应单个文件,只体现为 Innodb_buffer_pool_pages_dirty 持续不降,配合 iostat 的 w/s 高企,就得调 innodb_io_capacity。


















