在mysql数据库运行过程中,磁盘I/O异常往往会直接导致SQL执行效率下降,甚至引发整个业务系统的响应延迟。要精准定位这类问题,结合iostat工具和mysql慢日志是最常用且高效的排查方案,能够从不同维度还原SQL执行时的磁盘负载情况。

排查前的准备工作
首先需要确保mysql慢日志功能已开启,同时系统层面安装了sysstat工具包(包含iostat命令)。如果是Linux系统,可以通过下面的命令安装sysstat:
# centos系统安装命令 yum install -y sysstat # ubuntu系统安装命令 apt-get install -y sysstat
接着检查mysql的慢日志配置,执行以下SQL查看相关参数:
-- 查看慢日志是否开启 SHOW VARIABLES LIKE 'slow_query_log'; -- 查看慢日志阈值,单位秒,执行时间超过该值的SQL会被记录 SHOW VARIABLES LIKE 'long_query_time'; -- 查看慢日志文件路径 SHOW VARIABLES LIKE 'slow_query_log_file';
如果慢日志未开启,可以通过下面的SQL临时开启,永久生效需要修改my.cnf配置文件:
-- 开启慢日志 SET GLOBAL slow_query_log = 'ON'; -- 设置慢查询阈值为1秒,可根据实际需求调整 SET GLOBAL long_query_time = 1;
使用iostat采集磁盘I/O指标
iostat可以实时展示磁盘的读写负载情况,常用的执行命令如下:
# 每2秒输出一次磁盘I/O统计结果,共输出10次 iostat -x 2 10
输出结果中需要重点关注以下几个指标:
- %util:磁盘利用率,值越接近100%说明磁盘处于满负载状态,I/O压力极大
- rkB/s:每秒读取的数据量,单位KB
- wkB/s:每秒写入的数据量,单位KB
- await:I/O请求的平均等待时间,包含队列等待时间和实际处理时间,单位毫秒,值越高说明I/O响应越慢
- svctm:I/O请求的平均服务时间,单位毫秒,反映磁盘本身的处理能力
当观察到%util持续处于高位、await数值远高于svctm时,就可以确定当前磁盘存在I/O异常,需要进一步定位对应的SQL语句。
分析mysql慢日志定位问题SQL
慢日志文件中会记录所有执行时间超过阈值的SQL,以及对应的执行信息,我们可以通过mysql自带的mysqldumpslow工具分析慢日志:
# 按照查询时间倒序排序,输出前10条最慢的SQL mysqldumpslow -s t -t 10 /var/lib/mysql/slow.log
慢日志的每条记录包含以下核心信息:
| 字段 | 说明 |
|---|---|
| Query_time | SQL总执行时间,单位秒 |
| Lock_time | SQL等待锁的时间,单位秒 |
| Rows_sent | 返回给客户端的行数 |
| Rows_examined | SQL执行过程中扫描的行数,该值越大越容易触发大量磁盘I/O |
| SQL语句 | 实际执行的SQL内容 |
重点关注Rows_examined数值过高的SQL,这类SQL往往因为没有合适的索引,需要全表扫描或者扫描大量行,会触发频繁的磁盘读写操作。
结合两者关联排查的完整流程
实际排查时可以按照下面的步骤完成关联分析:
- 先通过iostat持续监控磁盘I/O指标,记录I/O异常发生的时间段
- 到慢日志中筛选对应时间段内记录的慢SQL
- 分析这些SQL的执行计划,查看是否存在全表扫描、索引失效的情况
- 对问题SQL进行优化,比如添加合适的索引、调整查询条件、拆分大查询等
- 优化后再次通过iostat观察磁盘I/O指标,确认异常是否消失
下面是一个查看SQL执行计划的示例,通过EXPLAIN命令可以判断索引使用情况:
-- 查看问题SQL的执行计划 EXPLAIN SELECT * FROM user_order WHERE create_time > '2024-01-01' AND status = 1;
如果执行计划中type字段为ALL,说明是全表扫描,需要对create_time或者status字段添加索引来减少磁盘扫描范围。
常见优化方案
针对排查到的磁盘I/O异常SQL,常用的优化方向包括:
- 为查询条件、关联条件、排序字段添加合适的索引,避免全表扫描
- 避免查询不需要的字段,不要使用
SELECT *,减少不必要的数据读取 - 大批量数据写入时采用批量提交的方式,减少频繁的磁盘刷写
- 对于历史数据较多的表,可以进行分表或者归档,减少单表的数据量
- 调整mysql的
innodb_buffer_pool_size参数,让更多热点数据缓存在内存中,减少磁盘读取
注意:修改mysql配置参数后需要重启服务才能生效,生产环境操作前需要做好备份和评估,避免影响线上业务。
总结
排查mysql SQL执行过程中的磁盘I/O异常,核心是通过iostat获取磁盘的实时负载指标,再通过慢日志定位到具体的问题SQL,两者结合可以快速找到问题根源。优化后需要持续监控相关指标,确认优化效果,同时日常也需要定期分析慢日志,提前发现潜在的I/O风险,保障数据库的稳定运行。