iostat和vmstat是定位MySQL硬件层性能瓶颈的首选工具:iostat聚焦磁盘IO,通过%util、await、r/s、w/s判断磁盘是否过载;vmstat监控内存交换(si/so)和CPU上下文切换(cs)、运行队列(r),揭示内存不足或任务调度问题;二者联动可区分IO瓶颈源于磁盘本身、swap抖动还是MySQL内部机制。

MySQL性能卡在硬件层时,iostat 和 vmstat 是最快能告诉你“到底卡在哪”的两个命令——不是猜,是看。
为什么先用 iostat 而不是 top
因为 MySQL 的慢,80% 以上最终落在磁盘 IO 上,而 top 只显示 CPU 占用,容易误判。比如 mysqld 进程 CPU 占用才 15%,但实际它正卡在等磁盘返回数据,iostat 才能暴露这个等待。
-
iostat -x 1每秒刷新一次扩展指标,重点关注三列:%util(设备忙时百分比)、await(单次 I/O 平均等待毫秒数)、r/s和w/s(每秒读写次数) - 若
%util持续 ≥ 95%,且await> 20ms(SSD)或 > 50ms(HDD),基本可断定磁盘是瓶颈 - 注意区分:高
r/s+ 高await常见于索引缺失导致全表扫描;高w/s+ 高await则可能来自大量脏页刷盘或临时表写磁盘(Created_tmp_disk_tables高)
vmstat 1 看内存和上下文切换是否拖垮 MySQL
vmstat 不是看“用了多少内存”,而是看“系统是否在为内存付出代价”。MySQL 吃内存,但吃错方式就会反噬性能。
- 关键列:
si(swap in,单位 KB/s)、so(swap out)、cs(context switch 每秒次数)、bi/bo(块设备读/写) - 只要
si或so持续 > 0,说明物理内存已不够,MySQL 正被迫交换页——这是严重信号,innodb_buffer_pool_size很可能设大了或系统其他进程抢内存 -
cs值异常高(如 > 50000)+r(运行队列)长期 > CPU 核数,说明 CPU 在频繁切换任务,常见于连接数暴增(Threads_connected远超max_connections设定值)或锁争抢激烈
两个工具联动判断的典型场景
单独看一个工具容易漏掉因果链。比如 iostat 显示 await 高,但不知道是 MySQL 主动读,还是被 swap 被迫读。这时要交叉验证:
- 如果
vmstat中si> 0 且iostat中bi也高 → 大概率是 swap 引发的磁盘读风暴,优先查内存配置和innodb_buffer_pool_size - 如果
iostat中w/s高、await高,但vmstat的so= 0、cs正常 → 更可能是 InnoDB 日志刷盘(innodb_log_file_size过小)或大量排序写临时表(sort_merge_passes高) - 如果
vmstat的r长期 ≥ CPU 核数,且iostat的%util却不高 → 问题不在磁盘,而在 CPU 或锁,该切到SHOW PROCESSLIST和SHOW ENGINE INNODB STATUS查
真正难的不是跑出这两条命令,而是看到 await 高时,不急着加磁盘,先确认是不是 si 在偷偷作祟;看到 cs 高时,不只盯着连接数,还要看有没有长事务把 MDL 锁住。硬件指标从不撒谎,但得连起来读才有意义。


















