返回首页

磁盘 IO 排查实战 — %util 陷阱与 await 真相

📅 创建于 2026-07-30 🔄 更新于 2026-07-30 📝 598 字

来源:赵楠 | 发布日期:2026-07-30

磁盘 IO 排查实战

服务器变慢,CPU 正常、内存正常——凶手其实是磁盘 IO。很多人"查了磁盘没问题",是因为只查了空间没查性能。

磁盘问题的三种类型

问题类型 症状 排查工具
磁盘空间不够 写文件报错、日志停止写入 df -h
磁盘速度太慢 服务响应慢、iowait 高 iostat
某个进程在疯狂读写 磁盘灯狂闪、I/O 负载高 iotop

绝大多数人只会第一种——df -h 看空间。但服务器变慢通常是第二、三种,df 对这两种完全看不出来。


iostat:磁盘版"心电图"

iostat -x 2

输出示例:

Device   r/s    w/s   rkB/s   wkB/s  await  r_await  w_await  %util
sda      0.5   180.3    8.0   2880.0  126.4     8.2    127.1   94.2

六个关键指标

指标 含义 核心判断
%util 磁盘忙碌占比 见下方陷阱
await IO 请求平均等待时间 (ms) 真正的瓶颈指标
r_await / w_await 读/写请求平均等待时间 区分读/写瓶颈
r/s, w/s 每秒读写次数 (IOPS) 结合设备上限判断
rkB/s, wkB/s 读写吞吐量 结合带宽上限判断
avgqu-sz 平均队列长度 > 2 有积压,> 8 严重阻塞

%util 的陷阱

%util = 94.2 表示每 100ms 中磁盘有 94.2ms 在处理 IO。

%util 100% ≠ 磁盘坏了,也不等于性能见底。

  • 机械硬盘:%util 接近 100% 确实饱和
  • SSD/NVMe:可同时处理上千个 IO 请求,%util 100% 只说明"每秒都有请求在跑",不代表跑不动

判断磁盘是否真瓶颈,必须结合 await。

await:真正的瓶颈指标

await 是 IO 请求从发出到完成的平均等待时间(毫秒)。

存储类型 正常范围 异常阈值
机械硬盘 (HDD) 5–20ms > 50ms
SATA SSD 0.1–1ms > 10ms
NVMe SSD 0.05–0.5ms > 5ms

类比:%util 是收银台有没有在工作,await 是顾客排队要等多长时间。收银台一直在转(%util 高)但队伍很长(await 高),才是真正的瓶颈。

IOPS vs 带宽:两个不同维度

典型误解: "磁盘带宽还没用满,应该不慢?"

不一定。 带宽和 IOPS 是两个维度:

  • 高带宽、低 IOPS:大卡车运大批货
  • 高 IOPS、低带宽:大量快递员送小包裹

机械硬盘 IOPS 通常只有 100–200 次/秒(受限于磁头物理移动)。数据库随机读写是大量小 IO——每次只读几 KB,一秒请求 200 次就把 HDD 打满,但带宽可能只用了几 MB/s。

SSD 对数据库提升巨大的原因:NVMe SSD IOPS 能到几十万次,彻底解决随机 IO 瓶颈。


iotop:找出"磁盘杀手"进程

iostat 告诉你磁盘在被打,iotop 告诉你是谁在打。

iotop -o

输出示例:

Total DISK READ: 0.00 B/s | Total DISK WRITE: 2.81 M/s
  PID  PRIO  USER     DISK READ  DISK WRITE  COMMAND
 3421  be/4  mysql       0.00 B   2.81 M/s   mysqld

找到 mysqld 疯狂写磁盘后,下一步进 MySQL 查慢查询日志,或检查是否配置触发大量 fsync。


完整排查流程

发现服务器慢
  ↓
top 看 CPU
  ├─ id 低、us/sy 高  → CPU 瓶颈 → 找高 CPU 进程
  └─ id 高、wa 高      → IO 瓶颈 → 继续往下查
      ↓
  iostat -x 2
    ├─ %util 高、await 高  → 磁盘饱和
    └─ %util 低、await 高  → 磁盘请求堆积,单次延迟高
      ↓
  iotop -o
    → 找出哪个进程在大量读写
      ↓
  针对具体进程深查(慢查询、日志积压、大文件写入……)

wa 字段:iowait 信号

top 输出中的 wa 是 iowait:

%Cpu(s): 28.3 us,  3.1 sy,  0.0 ni, 51.2 id, 16.8 wa

wa = 16.8% → 磁盘问题,不是 CPU 问题。


磁盘空间排查:IO 排查的前置步骤

磁盘空间不够时 IO 性能也会急剧下降(机械硬盘碎片化尤其严重)。空间排查永远是 IO 排查的前置。

# 1. 看各挂载点空间使用率
df -h

# 2. 找出空间大户
du -sh /* 2>/dev/null | sort -rh | head -10

du -sh /* 统计根目录下每个子目录大小,sort -rh 降序,head -10 取最大十个。


安装命令

# Debian/Ubuntu
apt install sysstat iotop

# RHEL/CentOS
dnf install sysstat iotop

关联页面

页面关联点
linux-disk-inspection-tools-guide磁盘排查工具实战指南(iostat/smartctl/lsscsi 详解)
linux-disk-io-tuning生产级 Linux 磁盘 IO 调优(调度器/内核参数/fio 基准测试)
server-performance-four-dimensions服务器性能五维排查(CPU/内存/磁盘/网络/文件系统)
linux-load-average-guideLinux Load Average 详解(含 wa 字段深度解析)
linux-disk-space-troubleshootingLinux 磁盘空间排查(8 命令/四种场景)
server-suddenly-slow-troubleshooting-sop服务器突然卡顿完整排查 SOP
linux-disk-io-monitoring-reference磁盘 IO 监控参考 — iostat/vmstat 字段详解与五指标框架。磁盘使用率/饱和度/IO
linux-perf-troubleshooting-handbookLinux 服务器性能排查实战手册

实用诊断脚本

#!/bin/bash
# disk-io-diag.sh — 磁盘 IO 一站式诊断脚本
# 用法:sudo bash disk-io-diag.sh [秒数,默认5]

DURATION=${1:-5}

echo "=== 磁盘空间 ==="
df -h | grep -v "tmpfs\|devtmpfs"

echo ""
echo "=== IO 状态(${DURATION}秒采样)==="
iostat -xz 1 $DURATION

echo ""
echo "=== 最活跃的 IO 进程(Top 10)==="
pidstat -d 1 3 2>/dev/null | tail -n +4 | head -10

echo ""
echo "=== iowait 检查 ==="
top -bn1 | head -4 | grep -i "cpu\|wa"

echo ""
echo "=== 磁盘健康(S.M.A.R.T. 状态)==="
for disk in /dev/sd[a-z] /dev/nvme[0-9]n1; do
  if [ -b "$disk" ]; then
    smartctl -H "$disk" 2>/dev/null | grep -E "PASSED|FAILED|overall"
  fi
done

运行方式:

sudo bash disk-io-diag.sh 10