想查看磁盘分区级别的实时读写吞吐,必须加上 -p ALL。因为默认执行 iostat -x 时,只会显示主设备(如 sda),不会展开到分区层级;而 -p 用于开启分区统计,ALL 则表示同时纳入 LVM、RAID、NVMe 等所有子设备。只有 -p 与 -x 组合使用时,才会输出 rMB/s 和 wMB/s 这些关键吞吐字段。

最直接、最实用的命令就是 iostat -xh 1 -p ALL。这是目前少数能够同时清晰观察每个磁盘分区(包括 LVM、md、nvme-part)实时读写吞吐变化的方法;其他常见命令不是无法细化到分区级别,就是统计口径不够准确,难以反映真实走势。
为什么必须加 -p ALL 才能看到分区级吞吐
默认状态下,iostat -x 只关注主块设备(例如 sda 或 nvme0n1),并不会自动列出其下属分区(如 sda1、nvme0n1p1)或逻辑卷。如果你想查看具体磁盘分区的读写吞吐量,就必须配合 -p 参数。这里的 ALL 表示将统计范围扩展到全部块设备及子设备——无论是 LVM 的 dm-0、RAID 的 md0,还是 NVMe 分区设备,都会一起显示出来。
-p和-x必须同时使用:例如iostat -x -p才是有效组合;单独使用-p不会输出rMB/s/wMB/s这类吞吐字段- 如果不加
ALL,-p往往只显示主设备和直接子分区,容易漏掉 LVM、RAID 等中间层块设备 - 虽然
/proc/diskstats也包含分区数据,但它的单位是扇区(512B),没有缓存过滤,还需要手动换算,更适合底层排查,不适合直接看实时吞吐走势
iostat -xh 1 -p ALL 输出里哪些字段代表真实分区吞吐
查看 Linux 磁盘分区吞吐量时,重点应关注 rMB/s 和 wMB/s 两列。这两个字段的数据直接来自块设备驱动层,能够尽量避开 page cache 的干扰,并且单位支持自动缩放(K/M/G),更适合直接判断分区实时带宽表现。不要轻易把 rkB/s/wkB/s 或 r/s/w/s 当成真实吞吐依据——前者更容易受到缓存影响,后者又会受到请求合并影响,无法准确反映磁盘分区的实际读写走势。
rMB/s和wMB/s才是最值得参考的吞吐指标,并且按设备名逐项展示,可以快速区分sda1、sda2等分区各自的实时负载- 如果某个分区的
rMB/s长时间为 0,但主设备sda仍有读流量,通常说明 IO 集中在其他分区,或者压根没有命中当前分区(例如 swap 位于sda2) - 需要注意的是,即使使用了
-xk,字段名称依旧显示为rMB/s:这是历史兼容机制导致的,实际数值已经按 KB 换算,只是列名没有变化
常见误判场景和替代方案的坑
如果你想绘制磁盘分区读写吞吐图表或导出实时趋势,尽量不要直接用 dstat -D sda1 或 vmstat。原因是它们都不具备可靠的分区粒度统计能力,而且 dstat 中的 disk read 列来自 VFS 层,缓存命中时数值可能被明显放大;vmstat 的 bi/bo 则是整个系统级汇总,单位还是 512B 块,根本无法区分具体设备或分区。
iotop -o -d 1更适合排查是哪个进程在产生 IO,但它的DISK READ/WRITE实际来自/proc/[pid]/io中的rchar/wchar,包含缓存层数据,因此和iostat的分区吞吐结果并不一致- 脚本采集时,不要直接用
awk '/sda1/ {print $3,$4}'去切默认输出——首屏通常是平均值,容易带来冷启动噪音;更稳妥的做法是使用iostat -xh 1 -p ALL 3 2控制采样次数并跳过初始值 - 如果在
-p ALL输出中看不到目标分区(例如dm-2),建议检查是否被 udev 规则隐藏,同时使用lsblk核对设备路径和命名是否一致
还有一个很容易被忽略的点:分区吞吐并不是简单相加的。比如 sda1 与 sda2 的 rMB/s 总和,通常会小于整个 sda 的 rMB/s,因为有一部分 IO(如元数据或 superblock 访问)发生在设备层,却不属于任何具体分区。如果想验证物理磁盘介质的真实完成量,需要进一步查看 /sys/block/sda/stat 的第 1/5 列,但那属于累计计数,并不能直接当作实时吞吐走势来使用。
