一文让你应对 Linux 进程 “D” 状态
环境
红帽企业 linux 4、5、6、7、8、9
问题
- 什么是 “D” 状态(或 dstate 或 d-state)?
- 什么是进程的 “D” 状态
解决
- Linux 遵循传统 UNIX 的标准,将其平均负荷计算为指定时间间隔内可运行或正在运行的进程(R 状态)的平均数量,以及处于不可中断睡眠(D 状态)中的进程数量。
- "D" 状态(TASK_UNINTERRUPTIBLE)是发生在内核代码路径中的一种状态,在这种状态下,在处理任务时执行不能被中断。我们希望这应该是一个短暂的过程,且在正常操作中,内核线程应该快速地从 TASK_UNINTERRUPTIBLE 状态中出来。
- "D" 状态进程通常被阻塞等待资源,磁盘 IO 和锁是进程可能阻塞的几种常见资源。
- 一个例子可能是与硬件通信的 low level 驱动程序,可能从 NIC 固件检索网络数据包数据或访问硬盘驱动器上的数据块--读写 IO。
- 通常,这种情况发生得非常快,并且线程保持这种状态的时间非常短(因此通常不会观察到,尤其是在用户空间中)。
- "D" 状态名称有历史原因,因为最初认为这种状态是进程处于“磁盘等待”状态。但现在,与“磁盘 IO”分离的网络、锁和其他资源可能导致进程处于不可中断的等待状态。有关进程状态的更多背景信息,请参阅 "了解 Linux 进程状态"。具体来说,我们总结了 "D" 状态过程如下:“不可中断睡眠状态是不会立即处理信号的状态。它只有在等待资源变得可用或者在等待期间发生超时(如果在进程进入睡眠时指定了超时)时才会被唤醒。”
- 当线程进入 "D" 状态并且未能在合理的时间内退出该状态时,就会出现问题。这个进程现在被“卡住”,任何等待它的进程(可能在它后面的队列中访问相同的硬件)或依赖它的进程也同样被卡住。
- 虽然“合理的时间”是主观的,但如果一个任务在 D 状态下停滞太久,那么 "INFO: task
: " 的消息就会输出,通知系统管理员需要调查或可能需要系统调优的潜在情况。blocked for more than ... seconds
- 虽然“合理的时间”是主观的,但如果一个任务在 D 状态下停滞太久,那么 "INFO: task
- 要查看哪个进程/线程保持在 "D" 状态:
- 获取处于 "D" 状态的线程列表:
ps auxH | awk '$8 ~ /^D/{print}'
- 显示每个线程
sudo cat /proc/<PID>/stack
的堆栈:
for D_PID in $(ps auxH | awk '$8 ~ /^D/{print $2}');do ps -Llp $D_PID;sudo cat /proc/$D_PID/stack;echo;done
- 获取处于 "D" 状态的线程列表:
根本原因
- 发现处于 D 状态的进程是相当普遍和正常的
- 在大多数情况下,这是由于对 I/O 资源(通常是本地或远程存储、网络文件系统等)的访问中断造成的
- 如果一个进程在 D 状态停滞太久,那么内核中的“停滞任务”逻辑将被启用
诊断步骤
- 检查 ps 输出中是否有处于 D 状态的线程,可以使用类似于以下内容的内容:
ps auxH | awk '$8 ~ /^D/{print}'
- 负载可能很高而且还在增加(可能有成百甚至到数千,1 分钟负载始终高于 5 分钟,5 分钟始终高于 15 分钟,暗示报告的负载不断增加);机器的响应能力与这个高数字不匹配(机器还能响应命令,但是如果所有核心都被占据之后,可能系统就不再响应)
- 解决问题的第一步(假设前两个步骤得到了验证)是隔离导致这种情况的资源(最有可能的存储/文件系统),例如查看处于 d 状态(当前工作)的进程的共同使用的文件或者目录等
- 一旦确定了所涉及的资源,就应采取措施恢复对它的访问;根据具体情况,可能会重新获得对在线文件系统/存储的访问,或者可能需要重新启动机器才能完全恢复(最有可能的情况)
参考链接