大家好!在运行Linux系统时,您是否也曾遇到过磁盘I/O突然飙升,导致整个系统变慢的情况?🐢 在这种时候,找出是哪个进程导致了问题,以及该进程实际上正在给哪个物理磁盘带来负载,这一点至关重要。
今天,我们将利用iotop这个强大的工具,找出导致大量磁盘I/O的进程,并通过该进程使用的文件系统,最终追溯到它所连接的物理磁盘!🚀

📊 步骤1:查找导致最多磁盘读取(Read)的进程
首先,我们需要确定导致系统负载的原因。iotop命令对于监控磁盘I/O非常有用。如果尚未安装,可以轻松进行安装。
# 如果iotop未安装,则进行安装。
yum install -y iotop
现在,我们将以批处理模式(-b)运行iotop两次(-n 2),只过滤当前有I/O的进程(-o)。然后,我们将根据磁盘读取(DISK READ)对结果进行排序,找出最高进程的PID(进程ID)并将其保存到文件中。
# 以批处理模式运行iotop,重复2次,只显示有I/O的进程。
# 根据磁盘读取(第4列)对结果进行排序,并提取最顶层进程的PID(第1列)。
PID_HIGH_READ=$(iotop -b -n 2 -o | tail -n +3 | sort -k4,4nr | head -n 1 | awk '{print $1}')
# 将找到的PID保存到/opt/highread.pid文件。
echo ${PID_HIGH_READ} > /opt/highread.pid
- iotop -b -n 2 -o: 以批处理模式收集两次信息,用于自动化脚本。
- tail -n +3: 排除iotop的头部信息,只获取实际的进程列表。
- sort -k4,4nr: 根据第4列(DISK READ)进行数字降序(nr)排序。
- head -n 1: 获取排序结果中的第一行。(最高的进程)
- awk ‘{print $1}’: 只提取第一列,即PID。
现在,打开/opt/highread.pid文件,您就可以立即看到哪个进程正在读取最多的磁盘数据了!📈
🔄 步骤2:查找导致最频繁I/O事务的进程
不仅要关注读写容量,查找I/O操作频率(IO%)高的进程也同样重要。因为反复读写小文件有时可能会给系统带来更大的负载。
这次,我们将根据I/O使用率(第10列)进行排序,找出最繁忙的进程。
# 根据I/O使用率(第10列)对iotop结果进行排序,并提取最顶层进程的PID。
PID_HIGH_TPS=$(iotop -b -n 2 -o | tail -n +3 | sort -k10,10nr | head -n 1 | awk '{print $1}')
现在,PID_HIGH_TPS变量中存储了执行最频繁磁盘操作的进程ID。让我们深入探究这个进程!🧐
🗺️ 步骤3:从进程到物理磁盘的路径追踪
这是最有趣的部分。让我们追踪上面找到的PID_HIGH_TPS进程正在访问哪些文件,以及这些文件通过哪个分区最终存储在哪个物理磁盘上。
📝 3-1. 查找进程打开的文件
使用lsof (List Open Files)命令,可以查看特定进程当前打开了哪些文件。
# 使用lsof查找该PID打开的普通文件(REG)的路径。
FILE_PATH=$(lsof -p ${PID_HIGH_TPS} | awk '$4 ~ /REG/ {print $9}' | head -n 1)
通过上述命令,我们找到了进程当前正在使用的文件的完整路径(FILE_PATH)。
🔗 3-2. 查找文件所属的设备(Device Mapper)
既然知道了文件路径,我们就可以使用df命令来查看该文件属于哪个文件系统(挂载点)。如果使用LVM(Logical Volume Manager),通常会显示/dev/mapper/形式的逻辑卷名称。
# 使用df命令查找文件路径所属的设备名称。
DM_DEVICE=$(df ${FILE_PATH} | tail -n 1 | awk '{print $1}')
DM_DEVICE变量将存储一个逻辑设备名称,例如/dev/mapper/centos-root。
💿 3-3. 查找真正的物理磁盘(Physical Device)!
这是最后一步!逻辑设备名称就像指向实际物理磁盘的标签。通过结合lsblk和readlink,我们可以最终确认这个逻辑卷是在哪个物理分区上创建的。
# 使用lsblk查找设备映射器名称(DM_DEVICE)指向的实际物理分区名称。
REAL_DEVICE_PARTITION=$(lsblk -no pkname $(readlink -f ${DM_DEVICE}))
# 将最终找到的物理设备路径保存到文件。
echo "/dev/${REAL_DEVICE_PARTITION}" > /opt/devname.txt
- readlink -f ${DM_DEVICE}: 查找符号链接设备名称的原始路径。
- lsblk -no pkname …: 输出该设备的父内核名称(pkname),即实际的物理分区名称。(例如sda2等)
最后,打开/opt/devname.txt文件,您就可以确认导致问题的进程最终正在使用的物理磁盘设备名称(例如/dev/sda2等)了!🎉
✨ 总结
通过这种方式,我们学习了如何将iotop、lsof、df和lsblk等基本Linux命令通过管道连接起来,从而逐步追踪模糊的磁盘负载原因,从具体的进程ID一直到实际的物理磁盘。
通过这个过程,您可以准确地识别系统瓶颈,并制定更有效的解决方案,例如更换磁盘或重新分配数据。当您的系统出现问题时,不妨利用这个方法,像侦探一样追踪原因吧!😉
发表回复