D 状态与高负载
系统负载(load average)很高但 CPU 大量空闲,最常见的原因是进程阻塞在不可中断的 IO 上,也就是 ps 状态列为 D 的那些进程。它们在内核里等待磁盘、块设备或 NFS 返回,不消耗 CPU 却持续计入负载。所以只盯 CPU 使用率排查,会完全找不到原因。
基本信息
| 适用平台 | Linux |
|---|---|
| 典型信号 | load average 高、CPU idle 高、进程状态为 D |
| 定位方式 | ps -eo state,pid,user,cmd 过滤 D |
| 常见原因 | 磁盘或块设备 IO 阻塞、NFS 挂载点无响应、云盘限流 |
| 关联场景 | 备份任务并发、挖矿或批量加密造成的大量读写 |
| 关键限制 | D 状态进程 kill -9 也杀不掉,需先解除 IO 阻塞 |
典型使用场景
- 负载报警但 CPU 曲线平稳,需要定位真正的阻塞源
- 数据库或文件服务响应变慢,判断是 IO 瓶颈还是应用问题
- NFS、云盘挂载点无响应导致命令卡死时找出等待中的进程
- 排查疑似挖矿、批量加密行为造成的异常磁盘压力
- 评估扩容方向:究竟缺 CPU 还是缺 IO 能力
定位 D 状态进程与等待点
定位 D 状态进程与等待点
uptime # 先看三个负载数值
ps -eo state,pid,user,lstart,cmd | awk '$1 ~ /^D/' | head -n 20 # 揪出 D 状态进程
cat /proc/1234/stack 2>/dev/null | head -n 10 # 内核栈:卡在哪一层
cat /proc/1234/wchan; echo # 内核等待通道
cat /proc/1234/status | grep -E 'State|VmRSS' # 状态与内存占用
iostat -x 1 3 2>/dev/null | tail -n 20 # 设备利用率与 await
mount | grep -E 'nfs|cifs|gluster' # 是否存在网络文件系统关键字段读法
| 字段 | 含义 | 正常与异常 |
|---|---|---|
| State (D) | 不可中断睡眠 | D 表示阻塞在内核 IO,S 是可中断睡眠 |
| wchan | 内核等待通道 | 指向具体驱动或文件系统调用 |
| stack | 内核调用栈 | 需 root 与内核支持,直接给出卡点 |
| %util | 设备繁忙度 | 持续接近 100% 说明设备已成瓶颈 |
| await | 平均 IO 等待毫秒 | 显著升高提示后端存储变慢 |
/proc/<PID>/stack 需要 root 且内核开启支持;拿不到栈时,用 wchan 配合 iostat、mount 输出综合判断阻塞位置。
对 D 状态进程反复 kill -9 无效:信号要等进程从不可中断睡眠返回才会被处理,先解决后端 IO 问题才是正路。
负载数值的分母是 CPU 核数,所以要先看核数再看数值:4 核机器负载 8 就是 2 倍超载,而 32 核机器负载 8 只算轻度。判断前用 nproc 确认核数,避免把小问题当事故。