磁盘故障排查实战:从IO使用率高到定位问题进程全攻略

前言

在Linux系统运维中,磁盘IO性能问题是最常见的故障之一。当系统响应变慢、应用卡顿时,往往与磁盘IO使用率过高有关。本文将系统性地介绍磁盘IO故障的排查方法,从系统级定位到进程级分析,帮助你快速找到问题根源。

一、快速判断:是否为IO问题引起的系统缓慢

当系统变慢时,首先需要确认是否由磁盘IO问题导致。

使用top命令查看CPU等待IO的占比

top

重点关注 %wa 这一列(CPU等待I/O的时间占比):

%Cpu(s):  2.5 us,  1.2 sy,  0.0 ni, 70.5 id, 25.6 wa,  0.0 hi,  0.2 si,  0.0 st

判断标准:

  • %wa < 10%:IO压力正常
  • %wa 10%-30%:存在IO压力,需要关注
  • %wa > 30%:IO压力较大,系统性能明显受影响
  • %wa > 50%:IO严重瓶颈,系统响应极慢

注意:wa值高只说明CPU在等待IO,但具体是哪个磁盘、哪个进程需要进一步排查。

二、定位磁盘:哪个磁盘IO使用率高

使用 iostat 命令可以查看每个磁盘的IO使用情况。

安装sysstat工具包(包含iostat)

# CentOS/RHEL
yum install -y sysstat

# Ubuntu/Debian
apt-get install -y sysstat

查看磁盘IO统计信息

# 查看所有磁盘IO情况,每2秒刷新一次
iostat -x 2

# 查看指定磁盘,例如sda
iostat -x sda 2

关键指标解读:

指标 含义 参考阈值
%util 磁盘繁忙程度(最重要的指标) >70% 表示磁盘繁忙
r/s 每秒读请求次数 数值越高IO越密集
w/s 每秒写请求次数 数值越高IO越密集
rkB/s 每秒读取的KB数 -
wkB/s 每秒写入的KB数 -
await 平均每次IO请求的等待时间(ms) >10ms 可能存在问题
svctm 平均每次IO请求的服务时间(ms) -

示例输出:

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.00     0.00   45.00 102.00   512.00  2048.00    36.00     5.20   38.50   12.30   45.20   4.50  90.52

从这个示例可以看出:%util = 90.52%,说明sda磁盘已经非常繁忙,是系统性能瓶颈所在。

三、定位进程:哪个进程导致IO高

找到问题磁盘后,需要进一步找出是哪个进程在大量读写磁盘。

方法一:使用iotop命令(推荐)

iotop可以实时显示每个进程的IO读写情况,是最直观的工具。

安装iotop:

# CentOS/RHEL
yum install -y iotop

# Ubuntu/Debian
apt-get install -y iotop

常用命令:

# 实时查看进程IO情况
iotop

# 只显示有IO操作的进程
iotop -o

# 批量模式,输出到文件进行分析
iotop -botqqq --iter=3

# 筛选IO大于0.2MB/s的进程
iotop -botqqq --iter=3 | awk '{ if ($11 > 0.2) print }'

iotop输出解读:

Total DISK READ:       20.15 M/s | Total DISK WRITE:       45.32 M/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
 1234  be/4  mysql      15.20 M/s   30.15 M/s  0.00 %  95.32 % mysqld
 5678  be/4  apache      2.50 M/s    8.20 M/s  0.00 %  45.12 % httpd
  • DISK READ/WRITE:实际磁盘读写速率
  • IO>:进程在IO调度中消耗的时间百分比

方法二:通过/proc文件系统查看

如果无法安装iotop,可以通过 /proc 文件系统查看特定进程的IO统计。

# 先找到IO高的进程PID(通过top或ps)
top -d 2

# 查看指定进程的IO详情
cat /proc/[PID]/io

示例:查看mysqld进程(PID=3203)的IO情况

cat /proc/3203/io

输出示例:

rchar: 1246816249
wchar: 5987241452
syscr: 485723
syscw: 327168
read_bytes: 862653440
write_bytes: 5123723264
cancelled_write_bytes: 0

字段含义:

字段 含义
rchar 读出的总字节数(含pagecache缓存)
wchar 写入的总字节数(含pagecache缓存)
syscr read()/pread()系统调用次数
syscw write()/pwrite()系统调用次数
read_bytes 实际从磁盘读取的字节数(重要指标)
write_bytes 实际写入磁盘的字节数(重要指标)
cancelled_write_bytes 截断pagecache导致的未写入字节数

注意:rchar/wchar 包含pagecache统计,不一定代表实际磁盘IO;read_bytes/write_bytes 才是实际磁盘IO量。

方法三:使用pidstat工具

pidstat可以按进程统计IO使用情况。

# 查看指定进程的IO统计,每2秒输出一次,共5次
pidstat -d -p 12976 2 5

# 查看所有进程的IO统计
pidstat -d 2

输出示例:

Linux 3.10.0-957.el7.x86_64 (localhost)   04/22/2026      _x86_64_        (4 CPU)

10:15:30 AM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
10:15:32 AM   27      3203   1024.00   2048.00      0.00  mysqld
  • kB_rd/s:每秒从磁盘读取的KB数
  • kB_wr/s:每秒写入磁盘的KB数
  • kB_ccwr/s:每秒取消写入的KB数

四、排查特殊进程状态

1. 查看不可中断睡眠进程(D状态)

D状态进程通常是在等待IO(磁盘IO、网络IO等),大量D状态进程说明IO系统存在问题。

# 查看所有D状态进程
ps -eo state,ppid,pid,cmd | grep -e '^[Dd]'

# 更详细的D状态进程信息
ps aux | awk '$8=="D" {print $0}'

输出示例:

D  1234  1234  [kworker/0:0]
D  5678  5678  mysqld

D状态说明:

  • 产生原因:进程等待磁盘IO时无法被中断,进入uninterruptible sleep状态
  • 正常情况:短暂的D状态是正常的
  • 异常情况:大量D状态进程或长时间D状态,说明IO系统可能存在故障

2. 查看僵尸进程(Z状态)

虽然僵尸进程不直接消耗IO资源,但大量僵尸进程会影响系统整体性能。

# 查看所有Z状态进程
ps -eo state,ppid,pid,cmd | grep -e '^[Zz]'

五、完整排查脚本

以下是一个完整的磁盘IO问题排查脚本:

#!/bin/bash
# disk_io_check.sh - 磁盘IO问题一键排查脚本

echo "========== 磁盘IO问题排查报告 =========="
echo "检查时间: $(date)"
echo ""

# 1. 查看系统负载和CPU等待IO情况
echo "【1】系统负载及CPU等待IO情况:"
top -bn1 | head -5
echo ""

# 2. 查看磁盘IO使用率
echo "【2】磁盘IO使用率(%util > 70% 表示繁忙):"
iostat -x 2 1 | grep -E "Device|sd|vd|nvme"
echo ""

# 3. 找出%util最高的磁盘
BUSY_DISK=$(iostat -x 2 1 | grep -E "sd|vd|nvme" | sort -k14 -rn | head -1 | awk '{print $1}')
if [ -n "$BUSY_DISK" ]; then
    echo "【3】最繁忙的磁盘: $BUSY_DISK"
    iostat -x $BUSY_DISK 2 1
fi
echo ""

# 4. 查看IO高的进程(如果有iotop)
if command -v iotop &> /dev/null; then
    echo "【4】IO使用率最高的进程:"
    iotop -botqqq --iter=1 2>/dev/null | head -10
else
    echo "【4】iotop未安装,使用pidstat替代:"
    pidstat -d 1 1 | head -10
fi
echo ""

# 5. 查看D状态进程
echo "【5】不可中断睡眠(D状态)进程:"
D_PROCS=$(ps -eo state,ppid,pid,cmd | grep -e '^[Dd]')
if [ -n "$D_PROCS" ]; then
    echo "$D_PROCS"
else
    echo "无D状态进程"
fi
echo ""

# 6. 查看Z状态进程
echo "【6】僵尸(Z状态)进程:"
Z_PROCS=$(ps -eo state,ppid,pid,cmd | grep -e '^[Zz]')
if [ -n "$Z_PROCS" ]; then
    echo "$Z_PROCS"
else
    echo "无Z状态进程"
fi
echo ""

# 7. 磁盘空间使用情况
echo "【7】磁盘空间使用情况:"
df -h | grep -E "Filesystem|/dev/sd|/dev/vd|/dev/nvme"
echo ""

# 8. 磁盘挂载参数
echo "【8】磁盘挂载参数(查看是否使用noatime等优化选项):"
mount | grep -E "/dev/sd|/dev/vd|/dev/nvme"
echo ""

echo "========== 排查完成 =========="

六、附录:iotop使用详解

iotop常用参数

参数 说明
-o, --only 只显示有IO操作的进程
-b, --batch 批量模式,适合输出到文件
-t, --time 添加时间戳
-q, --quiet 安静模式,减少输出行数
--iter=N 迭代N次后退出
-d SEC, --delay=SEC 设置刷新间隔(秒)
-p PID 只监控指定PID

实用命令组合

# 实时监控,只显示有IO的进程
iotop -o

# 批量模式,输出3次,每次间隔2秒
iotop -botq --iter=3 --delay=2

# 监控特定进程
iotop -p 1234

# 输出到文件分析
iotop -botq --iter=10 > /tmp/iotop.log

# 筛选IO大于1MB/s的进程
iotop -botqqq --iter=3 | awk '{ if ($7 > 1024 || $9 > 1024) print }'

七、常见问题及解决方案

问题1:%util持续100%,但业务没有明显变慢

可能原因:

  • 磁盘在做后台清理(如TRIM操作)
  • 文件系统日志刷盘
  • 使用了RAID卡,%util不能准确反映单盘状态

解决方法:

# 使用iostat查看更详细的指标
iostat -x 1
# 关注await和svctm,如果都正常,可能是正常现象

问题2:大量D状态进程,kill不掉

原因: 进程在等待IO,无法被中断

解决方法:

  1. 检查磁盘硬件是否有故障(dmesg查看内核日志)
  2. 检查文件系统是否损坏
  3. 最后手段:重启服务器
# 查看内核日志中的磁盘错误
dmesg | grep -i error
dmesg | grep -i fail

问题3:IO突然飙高后无法恢复

排查步骤:

# 1. 查看是否有大量D状态进程
ps aux | awk '$8=="D"'

# 2. 查看系统平均负载
uptime

# 3. 查看磁盘队列长度
iostat -x 1
# 关注avgqu-sz,如果持续大于10,说明IO堆积严重

八、总结

磁盘IO问题的排查思路总结为以下流程图:

系统响应慢
    ↓
top查看%wa是否过高  ────No──→ 排查其他原因(CPU/内存/网络)
    ↓ Yes
iostat查看%util确定繁忙磁盘
    ↓
iotop/pidstat定位具体进程
    ↓
分析进程行为(是否正常IO)
    ↓
解决问题(优化SQL、增加缓存、更换磁盘等)

核心命令速查表:

排查阶段 命令 关键指标
初步判断 top %wa
定位磁盘 iostat -x 2 %util, await
定位进程 iotop -o DISK READ/WRITE
进程详情 cat /proc/[PID]/io read_bytes, write_bytes
异常进程 `ps -eo state,pid,cmd grep '^D'`

本文为原创内容,欢迎转载,请注明出处。

posted @ 2026-04-22 15:54  不断精进,终生成长  阅读(170)  评论(0)    收藏  举报