linux查磁盘io不能只看%util,需结合await、r/s、w/s判断真实瓶颈:ssd await>20ms或hdd await>50ms且%util≈100%才表明io成瓶颈;%util高但await

Linux怎么查看磁盘IO利用率:别只盯%util,先看是不是真瓶颈
%util 高不等于磁盘真的扛不住——它只是表示设备在采样周期内有 IO 请求的时间占比。SSD 上跑出 100% 可能完全正常,而机械盘上长期 >80% 就得警惕。真正要看的是 await(平均每次 IO 等待毫秒数)和 r/s/w/s(每秒读写次数)是否超出设备能力。
-
%util ≈ 100%+await > 20ms(SSD)或 >50ms(HDD)→ 实际延迟已升高,IO 成瓶颈 -
%util高但await始终 grep 大目录) -
%util低但业务卡顿 → 问题可能在文件系统层(如 ext4 journal 阻塞)、内存页缓存不足,或 IO 被其他进程抢占(用iotop -oP确认)
直接执行:iostat -x 1 3,重点关注输出中的 Device、%util、await、r/s、w/s 这几列。
sar -d 查磁盘IO:参数组合决定你看到的是“快照”还是“趋势”
sar -d 的核心价值是历史回溯——它依赖 sysstat 的后台收集服务(sysstat 默认每10分钟记录一次)。没开这个服务,sar -d 就只能查当天的实时数据(需加 -F 强制读取当前 /var/log/sa/saXX),或者啥也查不到。
- 必须先确认服务运行:
systemctl is-active sysstat,若为inactive,需启用:systemctl enable --now sysstat - 查今天每10分钟的汇总:
sar -d -f /var/log/sa/sa$(date +%d) - 查指定时间段(比如昨天下午2点到4点):
sar -d -s 14:00:00 -e 16:00:00 -f /var/log/sa/sa$(date -d "yesterday" +%d) -
-d默认不显示设备名全称,加-p才能看清是sda还是nvme0n1 - 注意字段含义:
rd_sec/s和wr_sec/s是扇区/秒(512字节/扇区),不是字节/秒;换算带宽要 ×512 ÷ 1024 ÷ 1024 得到 MB/s
为什么sar -d 有时显示DEV为空或全是0?
这通常不是命令写错,而是底层数据源缺失或格式不匹配:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
-
/var/log/sa/saXX文件被清空或权限不对(应为 root:root,644) -
sysstat版本太老(sar -d 无法解析其设备名,直接跳过整行 - 使用了 LVM 或加密卷(如
dm-0),默认sar -d不采集这些逻辑设备,需额外配置/etc/sysconfig/sysstat中的DISKSTATS项 - 时间范围跨了日切(比如查 23:59 到 00:05),
sar不自动拼接两个 sa 文件,必须分两次查再人工合并
快速验证数据是否存在:sa1 -A(手动触发一次采集),然后立刻跑 sar -d -s $(date -d '1 minute ago' +%H:%M:%S) -e $(date +%H:%M:%S)。如果这次有输出,说明是历史数据缺失,不是命令问题。
替代方案:当 sar -d 不可用时,直接读 /proc/diskstats
/proc/diskstats 是内核实时暴露的原始计数器,没有采集延迟,适合写监控脚本或做秒级诊断:
- 每行格式:
major minor name r ios r merges r sectors r ticks w ios w merges w sectors w ticks in_flight io_ticks time_in_queue - 关键字段:第 6 列(
r sectors)是读取扇区总数,第 10 列(w sectors)是写入扇区总数,第 14 列(io_ticks)是设备忙的毫秒数(对应%util计算基础) - 两秒间隔采样示例:
read1=$(awk '$3=="vdb"{print $6}' /proc/diskstats) write1=$(awk '$3=="vdb"{print $10}') time1=$(awk '$3=="vdb"{print $14}' /proc/diskstats) sleep 2 read2=$(awk '$3=="vdb"{print $6}' /proc/diskstats) write2=$(awk '$3=="vdb"{print $10}') time2=$(awk '$3=="vdb"{print $14}' /proc/diskstats) echo "read MB/s: $(( (read2-read1)*512/1024/1024/2 ))" echo "util%: $(( (time2-time1)/2 ))"
注意:该方法要自己处理设备名匹配(vdb、nvme0n1、dm-0 写法不同),且无法获得 await 这类衍生指标——那些必须靠 iostat 或 iotop。
真正的难点不在命令语法,而在区分「设备饱和」和「应用滥用」。同一个 grep 进程,在 SSD 上可能只是占满队列,在 HDD 上却会拖垮整个系统的响应。看数字之前,先想清楚你是在调优存储硬件,还是在揪出那个偷偷扫遍 /var/log 的定时任务。










