Linux磁盘IO慢需按四步排查:先用iostat确认真实负载,再用iotop定位IO大户进程,接着用lsof和strace分析具体文件操作与系统调用,最后检查IO调度器匹配性及硬件健康状态。

Linux磁盘IO慢不能靠猜,得按IO路径一层层查:先确认是不是真忙,再找谁在猛读写,接着看它在操作哪些文件、怎么写的,最后检查调度策略和硬件状态是否匹配。四步下来,80%的IO慢问题都能定位到根上。
看iostat确认磁盘是否真的高负载
别信“感觉慢”,用数据说话。运行iostat -x 1,重点关注三列:
- %util:持续≥95%,说明磁盘基本跑满;长期低于30%但应用仍卡,问题可能不在磁盘本身
- await:平均每次IO等待时间,超过20ms就要盯紧,超50ms大概率有瓶颈
- r/s 和 w/s:结合设备类型判断是否合理——机械盘随机写超100 IOPS就吃力,NVMe盘则轻松过10万
如果%util低但await高,可能是请求堆积在队列里,或当前IO调度器不匹配硬件;如果%util高且r/w频繁,就该往下查是哪个进程驱动的。
用iotop揪出IO大户进程
执行sudo iotop -o,只显示正在做IO的进程,按I/O%排序一眼锁定目标:
- 看进程名是否合理:比如mysqld、postgres、rsync、日志轮转脚本(logrotate)或备份任务
- 看读写速率(B/s)是否异常:一个普通后台脚本持续写200MB/s,明显不合理
- 注意D状态进程:表示卡在不可中断睡眠,大概率堵在底层IO,需结合stack分析
找到PID后,先别kill,立刻记录:ps -fp PID看完整命令行,lsof -p PID留作下一步分析依据。
查lsof和strace定位具体读写行为
拿到PID,用lsof -p PID | grep -E "(REG|DIR)"筛选出打开的普通文件和目录:
- 重点盯大日志文件(/var/log/messages、应用自定义log),是否被反复truncate或高频追加
- 数据库数据文件(如/var/lib/mysql/*.ibd)或WAL日志(pg_wal/、ib_logfile*)是否持续刷写
- /tmp、/var/tmp下是否频繁创建删除小文件,暴露应用设计缺陷
再补一手strace -p PID -e trace=write,open,fsync抓几秒系统调用,能看清是写4KB小块还是1MB大块、是否每写一次就fsync——这对调优很关键,比如调整MySQL的innodb_flush_log_at_trx_commit或挂载选项禁用atime。
检查IO调度器与硬件健康状态
这步分两线并行:
- 调度器是否匹配:执行cat /sys/block/sda/queue/scheduler,括号中标出当前生效算法。SSD/NVMe/RAID推荐noop或kyber(较新内核);机械盘可试cfq或bfq(旧内核)
- 硬件是否可靠:用smartctl -a /dev/sda查SMART信息,关注Reallocated_Sector_Ct、Current_Pending_Sector等关键项;用fio做基础压测验证吞吐与延迟是否符合标称值
如果所有软件层都排查无误,而iostat持续显示高%util+高await+低IOPS,那就要考虑磁盘老化、RAID卡缓存失效或云平台存储资源争抢了。











