在IDC运维日常中,磁盘IO问题往往比CPU和内存问题更难排查——因为IO瓶颈的现象千奇百怪:网站偶尔卡顿、数据库查询时快时慢、备份任务莫名超时。本文分享一套从现象到根因的磁盘IO排查方法论,全部基于真实生产环境经验。
第一步:确认是不是IO问题
不要上来就查磁盘,先确认瓶颈真的在IO。用top按x键高亮排序列,再按P看CPU、按M看内存、按D看磁盘。如果发现wa(iowait)长期高于20%,或者多个进程处于D(不可中断睡眠)状态,基本可以锁定IO瓶颈。
更直观的方式是vmstat 1,关注bi(块设备读)、bo(块设备写)和wa三列:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 1 0 48256 123456 789012 0 0 890 1200 1234 2345 8 6 68 18 0b列表示等待IO的进程数,如果持续大于1,说明有进程在排队等IO;bi/bo数值持续高位则说明IO吞吐已经吃紧。
第二步:定位到具体磁盘
服务器有多块盘时,用iostat -x 1看每块盘的详细指标。重点看四个值:
%util:磁盘利用率。注意这个不是百分比意义上的"容量",而是磁盘忙的时间占比,接近100%说明磁盘已饱和await:平均IO响应时间(毫秒)。机械盘正常应在10ms以下,SSD应在1ms以下svctm:单次IO服务时间,接近await说明IO都在排队avgqu-sz:平均请求队列长度,持续大于2说明排队严重
如果%util高但await不高,说明磁盘吞吐够用只是请求密集;如果%util不高但await很高,那问题可能出在磁盘本身(坏道、降级)或者控制器。
第三步:揪出罪魁祸首进程
磁盘层面的问题定位后,还要找到是谁在产生IO。iotop是最直观的工具:
iotop -oP # 只显示实际在IO的进程-o只显示有IO活动的进程,避免刷屏;-P显示进程而非线程。重点看IO>%列,找出读写占比最高的进程。
对于MySQL这类多线程应用,用pidstat -d -p <pid> 1可以按线程维度看IO。注意很多数据库的连接池会让IO分散到多个线程,看起来每个都不高,但总和很大,这时要回到iostat的总量维度判断。
第四步:深入IO子系统
如果进程层面找不到异常,可能是更底层的IO子系统问题:
文件系统层面:df -i看inode是否耗尽(inode耗尽时即使有空间也写不进文件);dumpe2fs或xfs_info查看文件系统碎片情况。ext4可以用e2fsck -fn做只读检查,但生产环境谨慎执行。
RAID层面:用megacli -pdlist -a0或storcli查看RAID状态,重点检查是否有磁盘处于Rebuild(重建)或Degraded(降级)状态。RAID降级时性能会骤降50%以上,这是生产环境最常见的隐性IO杀手。
内核IO调度器:cat /sys/block/sda/queue/scheduler查看当前调度器。机械盘推荐mq-deadline或noop,SSD推荐none(即noop)。错误配置调度器会导致IO延迟明显升高。
第五步:常见场景实战
场景一:数据库写入慢
先看iostat -x确认是sda还是其他盘在忙,再iotop -oP找进程。大概率是sync参数配置问题(如MySQL的innodb_flush_log_at_trx_commit=1在机械盘上性能极差),或者日志盘和数据盘共用了一块盘。
场景二:备份导致业务卡顿
备份任务(mysqldump、tar、rsync)往往是IO大户。解决方案是限速:ionice -c2 -n7给备份任务设置低优先级,或者用rsync --bwlimit限制带宽。更彻底的做法是把备份时间错峰,或者备份走独立磁盘/独立存储。
场景三:磁盘明明很空却报错写不进去
优先检查inode:df -i。inode耗尽常见于大量小文件的目录(如邮件队列、session文件、docker容器层)。清理方案:删除过期文件、合并小文件、或者重新格式化时增大-i的bytes-per-inode值。
排查流程图
现象(卡顿/慢查询/超时)
↓
vmstat 确认 wa / b 高?
↓ 是
iostat -x 定位到具体磁盘
↓
%util高? → 是 → 吞吐饱和,看iotop找进程
↓否 ↓
await高? → 是 → 磁盘/RAID/控制器问题
↓否
检查文件系统/inode/调度器总结
磁盘IO排查的核心思路:先确认(vmstat)→ 再定位(iostat)→ 后揪凶(iotop)→ 查底层(RAID/文件系统)。每一步都基于数据说话,不靠猜。建议日常巡检就把iostat -x 1和vmstat 1纳入监控,配合告警阈值(wa>20%、await>20ms持续5分钟),这样IO问题刚冒头就能发现,而不是等到业务挂了才手忙脚乱。
评论