iostat -dx 1 能真实反映设备级读写走势,其 r_ios/w_ios 和 rkB/s/wkB/s 是每秒动态原始值;需配合 date 补时间戳、tail 和 awk 提取字段生成 CSV 供绘图,列序须先验证。

怎么用 iostat -dx 1 看真实设备级读写走势
iostat -dx 1 是唯一能反映真实设备级读写速率随时间变化的命令,它每秒输出一行,r_ios/w_ios 和 rkB/s/wkB/s 都是动态刷新的原始值,不是平均值或累计值。其他工具要么带缓存干扰(如 iotop 的 DISK READ),要么单位错乱(如 vmstat 的 bi/bo 是 512 字节块),无法画出可信走势。
常见错误是加 -c 或 -t 参数试图加时间戳——iostat 本身不输出时间列,但每行天然对应一个采样时刻;想对齐时间轴,得靠外部命令补:while true; do echo "$(date +%H:%M:%S) $(iostat -dx 1 1 | tail -n +4 | grep sda)"; sleep 1; done
-
iostat -dx 1中的r_ios是内核提交到 block queue 的读请求次数,w_ios是写请求次数,它们直接反映 IOPS 走势,比rkB/s ÷ 4更准 -
rkB/s和wkB/s是绕过 page cache 的真实吞吐(KB/s),但注意:它仍经过 block layer 重排和队列缓冲,不等于物理介质完成量 - 如果走势剧烈抖动(比如
r_ios在 0 和 8000 之间跳变),大概率是应用用了小块 buffered I/O,触发了内核合并;此时看avgrq-sz(平均请求大小)能验证——若长期
怎么用 pidstat -d 1 看进程级读写实时曲线
pidstat -d 1 输出的是每个活跃进程每秒的 rkB/s 和 wkB/s,单位 KB/s,天然适合绘制成时间序列曲线。它底层读取的是 /proc/[pid]/io 的 read_bytes/write_bytes 差值,所以比 iotop 的 DISK READ(来自 rchar)更贴近物理读写。
容易踩的坑是直接跑 pidstat -d 不带间隔——它只打一次快照就退出;或者用 pidstat -d 0 导致采样频率失控,终端卡死。正确做法是明确指定间隔,且建议配合 -p 锁定目标进程:
- 监控指定进程:
pidstat -d 1 -p "$(pgrep -f 'mysqld')",pgrep -f匹配完整命令行,避免漏掉多实例 - 多个 PID 时,
pidstat -d 1 -p 1234 5678原生支持空格分隔,无需额外处理 - 输出中只有
rkB/s和wkB/s是真实 IO 速率,%MEM、RSS等字段和磁盘 IO 完全无关,别被排版误导
为什么不能靠 iotop -o 实时画走势
iotop -o 显示的是带缓存的速率(即进程调用 read(2)/write(2) 的数据量),底层来自 /proc/[pid]/io 的 rchar/wchar,不是 read_bytes/write_bytes。这意味着:同一段代码,第一次读文件会记入 rchar 和 read_bytes,第二次读同样内容(page cache 命中)只记 rchar,read_bytes 为 0 —— 所以 iotop 的曲线会频繁归零,无法反映真实磁盘负载走势。
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
实际场景中,你看到 iotop 里某进程 DISK READ 突然飙到 50MB/s,但 pidstat -d 显示 rkB/s 只有 2MB/s,基本可以断定:它在反复读缓存内的热数据,没真正刷盘。
-
iotop -a累计值本质也是轮询/proc/[pid]/io,但它累加的是rchar/wchar,不是read_bytes,所以历史总量也不代表真实磁盘读写 - 想确认某个进程是否真在压盘,必须交叉比对:
pidstat -d 1的rkB/s+iostat -dx 1的r_ios;两者趋势一致,才是真实 IO 走势
怎么导出数据给 gnuplot 或 Excel 画图
所有命令本身不带导出功能,但 Linux 管道足够灵活。关键点是:别用 watch(它加 ANSI 控制符,破坏 CSV 格式),而要用循环 + date + awk 提取字段。
例如,采集 sda 的每秒 r_ios 和 rkB/s 并保存为 CSV:
while true; do
ts=$(date +%s)
stats=$(iostat -dx 1 1 | tail -n +4 | grep sda | awk '{print $2","$4}')
echo "$ts,$stats" >> io_trend.csv
sleep 1
done
注意:iostat -dx 1 1 表示“执行一次扩展模式,每秒刷新,总共 1 次”,避免多行干扰;tail -n +4 跳过表头;awk '{print $2","$4}' 提取第 2 列(r_ios)和第 4 列(rkB/s)
- 字段顺序依赖 iostat 版本,RHEL 8 和 Ubuntu 22.04 的列序一致,但老系统可能不同,首次运行先手动执行
iostat -dx 1 1确认列号 - 如果目标是画进程级曲线,把
iostat换成pidstat -d 1 1 -p $PID,再用awk提取rkB/s对应列(通常是第 5 列) - CSV 文件直接拖进 Excel 就能生成折线图;gnuplot 需要先用
set xtics rotate处理时间戳,否则横轴挤成一团

















