linux如何排查磁盘I/O使用高的进程
本文介绍了排查Linux系统磁盘I/O使用率高的详细方法:首先通过iostat确认I/O瓶颈和问题磁盘;然后使用iotop或pidstat定位高I/O进程;最后通过lsof、strace或/proc文件系统深入分析进程的I/O操作。文章提供了具体命令、参数解读和实用技巧,并总结了常见的高I/O场景如数据库、日志服务等。这套系统化的排查流程能有效解决Linux服务器的磁盘性能问题。
排查 Linux 下导致磁盘 I/O 使用率高的进程是一个常见的性能诊断任务。
核心思路
- 确认问题:首先确认确实是磁盘 I/O 瓶颈,而不是 CPU 或内存问题。
- 全局视角:找到哪个磁盘或分区压力大。
- 进程视角:定位是哪个(哪些)进程正在大量读写该磁盘。
- 深入分析:分析该进程的具体操作(读写哪些文件、系统调用等)。
第 1 步:确认全局磁盘 I/O 状况
使用 iostat
工具(来自 sysstat
包)来确认是否是磁盘 I/O 问题,并找出有压力的磁盘。
# 安装 sysstat(如果尚未安装)
# Ubuntu/Debian
sudo apt update && sudo apt install sysstat
# CentOS/RHEL/Fedora
sudo yum install sysstat # 或 sudo dnf install sysstat
# 使用 iostat,每 2 秒刷新一次,显示扩展信息
iostat -dx 2
关键指标解读:
Device
: 磁盘设备名(如sda
,vda
,nvme0n1
)。r/s
,w/s
: 每秒的读、写请求数量(IOPS)。rkB/s
,wkB/s
: 每秒读、写的数据量(吞吐量)。await
: 每个 I/O 请求的平均等待时间(毫秒)。这是衡量磁盘延迟的关键指标,值越大说明排队越严重。%util
: 磁盘设备的利用率百分比。如果持续接近 100%,说明该磁盘设备已饱和,确实是 I/O 瓶颈。
示例输出:
Device r/s w/s rkB/s wkB/s await %util
sda 0.00 485.00 0.00 59420.00 120.33 98.20
这里清楚显示 sda
磁盘的写入压力极大(%util
为 98.2%,await
高达 120ms)。
第 2 步:定位高 I/O 的进程
一旦确认了问题磁盘(例如 sda
),下一步就是找出罪魁祸首。
方法一:使用 iotop
(最直接、最常用)
iotop
类似于 top
,但专门用于监视磁盘 I/O。它按进程或线程显示实时 I/O 使用情况。
# 安装 iotop
# Ubuntu/Debian
sudo apt install iotop
# CentOS/RHEL/Fedora
sudo yum install iotop # 或 sudo dnf install iotop
# 运行 iotop(需要 root 权限)
sudo iotop
使用技巧:
- 排序:默认按 I/O 使用率排序。按左右箭头键可以按不同列排序(如读、写)。
- 只显示有 I/O 的进程:按下
o
键或--only
参数。 - 刷新间隔:
-d
参数指定刷新秒数,例如sudo iotop -d 2
。 - 查看累计 I/O:加上
-a
参数显示累计数据而不是实时速率。
输出解读:
Total DISK READ: 0.00 B/s | Total DISK WRITE: 59.42 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
4560 be/4 mysql 0.00 B/s 59.42 M/s 0.00 % 99.99 % mysqld
这里一目了然地看到 mysqld
进程(线程 ID 4560)正在以约 60MB/s 的速度写入磁盘,并且 I/O 占用时间高达 99.99%。
方法二:使用 pidstat
(sysstat 套件的一部分)
pidstat
非常强大,可以按进程报告 I/O 统计信息,并且可以记录历史数据。
# 监控所有进程的 I/O,每 2 秒刷新一次
sudo pidstat -d 2
# 只监控某个特定进程(找到PID后)
sudo pidstat -d -p <PID> 2
输出解读:
Linux 5.4.0-... 06/10/2023 _x86_64_ (4 CPU)
03:15:20 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s Command
03:15:22 PM 112 4560 0.00 59420.00 0.00 mysqld
kB_rd/s
: 每秒从磁盘读取的数据量 (KB)。kB_wr/s
: 每秒向磁盘写入的数据量 (KB)。这里明确显示mysqld
在大量写入。
第 3 步:深入分析特定进程
找到可疑进程后(例如 mysqld
),需要进一步分析它在做什么。
方法一:使用 lsof
查看进程打开的文件
查看该进程当前打开了哪些文件,特别是正在频繁读写的文件。
# 列出指定进程(PID)打开的所有文件
sudo lsof -p <PID>
# 结合 grep 过滤,例如只查看正在写入的文件(deleted状态可能是日志文件被rotate)
sudo lsof -p <PID> | grep -E "REG.*W|DEL"
# 或者,直接查看某个磁盘设备上被哪些文件占用
sudo lsof /dev/sda
方法二:使用 strace
跟踪系统调用(高级)
strace
可以跟踪进程发起的所有系统调用,包括 read
, write
, open
, sync
等,这能告诉你进程在具体读写什么。
# 跟踪一个正在运行的进程的系统调用,重点关注文件操作
sudo strace -ff -p <PID> -e trace=file,write,read -s 1024 -o /tmp/strace_output.txt
# 参数解释:
# -ff: 跟踪所有子线程
# -p <PID>: 指定进程ID
# -e trace=file,write,read: 只跟踪文件、读、写相关的调用
# -s 1024: 显示字符串的前1024个字符(避免截断文件名)
# -o: 输出到文件
注意:strace
开销较大,不建议在生产环境长时间运行。
方法三:使用 /proc
文件系统
/proc/<PID>/io
文件包含了该进程的累计 I/O 统计信息。
# 查看进程的累计I/O
sudo cat /proc/<PID>/io
输出示例:
rchar: 12345678
wchar: 987654321
syscr: 120
syscw: 450
read_bytes: 4096000 # 该进程从存储层读取的物理字节数
write_bytes: 20480000 # 该进程向存储层写入的物理字节数
你可以间隔一段时间(如 10 秒)读取一次 read_bytes
和 write_bytes
,然后计算差值来估算实时速率。
总结与排查流程图
-
全局检查:
iostat -dx 2
- 目标:确认
%util
和await
是否过高,找到压力大的磁盘(如sda
)。
- 目标:确认
-
定位进程:
- 首选:
sudo iotop
(直观,实时) - 替代:
sudo pidstat -d 2
(更详细,可记录)
- 首选:
-
深入分析:
- 看文件:
sudo lsof -p <PID>
- 看操作:
sudo strace -p <PID> ...
(高级调试) - 看统计:
sudo cat /proc/<PID>/io
- 看文件:
常见高 I/O 进程场景:
- 数据库(MySQL, PostgreSQL):写日志、刷脏页、大查询。
- 日志服务(rsyslog, journald, 应用日志):大量写日志文件。
- 备份工具(rsync, tar, cp):大量文件读写。
- 包管理器(apt, yum):更新软件时的大量下载和解压。
- 虚拟机/容器:磁盘镜像的读写操作。
通过以上步骤,你就能系统地定位并解决 Linux 服务器上的磁盘 I/O 瓶颈问题。

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)