用 sudo iotop -o -P 可快速定位狂读狂写进程,-o 显示活跃I/O进程,-P 屏蔽线程,重点关注 IO> 和 DISK WRITE 列,结合版本差异与后续分析判断业务合理性。

直接上结论:用 sudo iotop -o -P,重点关注 IO> 和 DISK WRITE 两列,90% 的“狂读狂写”问题一眼就能揪出来。
为什么普通用户跑 iotop 什么也看不到
不是命令错了,是权限和内核机制卡住了:
- 必须用
sudo或 root 运行,普通用户即使加sudo也可能因缺失CAP_SYS_ADMINcapability 而失败 - 内核需启用
CONFIG_TASKSTATS和CONFIG_TASK_DELAY_ACCT,最小化安装的 CentOS/RHEL/AlmaLinux 常默认关闭,可运行zcat /proc/config.gz 2>/dev/null | grep -i taskstats验证 -
iotop默认显示所有进程(含大量静默线程),真正干活的进程被淹没;不加-o就像在机场广播里听自己名字——全是噪音
sudo iotop -o -P 是最稳的起点
这个组合过滤掉干扰项,直奔主题:
-
-o(--only):只显示此刻正在做 I/O 的进程,刚写完日志但已休眠的不会出现——这不是漏报,是刻意降噪 -
-P(--processes):屏蔽线程(TID),避免同一服务多个线程分散注意力(比如 Java 应用动辄上百线程) - 界面中优先盯
IO>列:值接近 100% 表示进程大部分时间在等磁盘,哪怕DISK WRITE只有几 KB/s,也可能是高频小文件刷盘(如日志轮转、数据库 WAL 写入) - 按
Shift+P切换按IO>排序,比默认按带宽更敏感
批量抓取快照时字段偏移容易翻车
脚本化分析必须防版本差异:
- 用
iotop --version确认版本,iotop -h查当前列顺序——新旧版本IO>可能在第 10 或第 11 列 - 推荐写法:
sudo iotop -b -n 1 -o -P | awk '$11 ~ /^[0-9.]+$/ && $11 > 5 {print $1, $11, $12}'(假设IO>在第 11 列) -
-b(batch mode)强制非交互,-n 1防止卡住;没有-b的iotop在 SSH 断连或脚本里会挂死 - 注意
Actual DISK WRITE远大于Total DISK WRITE(比如 25MB/s vs 0.85MB/s):说明脏页堆积严重,内核kworker即将爆发刷盘,磁盘延迟马上飙升
看到数据后别急着 kill,先看它在写什么
定位到高 I/O 进程只是第一步,关键要判断是否合理:
- 对
mysqld、postgres,检查是否在执行大事务或未加索引的查询(SHOW PROCESSLIST) - 对
rsyslogd、fluentd,用lsof -p PID看它正往哪个文件写,是不是日志路径落在慢盘上 - 对
java进程,结合pidstat -d -p PID 1看累计读写量,确认是持续行为还是偶发峰值 - 如果
IO>高但DISK READ/WRITE极低,大概率是同步写(O_SYNC)或元数据操作(如fsync、目录遍历),此时strace -p PID -e trace=fsync,write,openat更有效
真正难的不是找到那个进程,而是判断它“该不该这么干”——磁盘 I/O 的异常往往藏在业务逻辑和配置里,iotop 只负责把门推开,门后是什么,得你自己进去看。


















