负载高但CPU低,基本可断定进程卡在磁盘I/O:%util≥95%或await>100ms(HDD)/>20ms(SSD)表明磁盘饱和;用iotop -o -P定位高IO进程,lsof -p [PID]查具体文件,dmesg | grep -i "blocked"验证内核级阻塞。

负载高但CPU低,基本可以断定不是CPU在忙,而是进程卡在磁盘I/O上——它们在等硬盘响应,不占CPU,但持续计入系统负载。
怎么看是不是真被磁盘拖住?盯死 iostat -x 1 的两个值
别信宝塔面板里那条跳动的IO曲线,它只画趋势,不给数字。真正判断依据只有两个:
-
%util持续 ≥95%:说明磁盘几乎没空闲时间,已饱和 -
await稳定 >100ms(HDD)或 >20ms(SSD):请求排队严重,不是慢,是堵死了 - 如果
%util才60%但await飙到2000ms,大概率是小文件随机写(比如日志刷屏),不是吞吐量问题 - 注意查对分区:
lsblk确认/www/wwwlogs或/tmp是否挂载在独立磁盘上,别只盯着/dev/vda1
哪个进程在狂刷磁盘?iotop -o -P 是唯一靠谱答案
iotop 不装不行,但装完直接跑 iotop 会刷一堆静默进程干扰判断。必须加参数:
-
-o:只显示当前有IO活动的进程,过滤掉空闲子进程 -
-P:只看物理磁盘读写,排除缓存干扰 - 重点关注
DISK WRITE列(单位是KB/s),>5MB/s 就得查;IO>列 >90% 表示这进程基本卡在等磁盘 - 按
R键实时按IO降序,按P暂停,截图时务必保留COMMAND列里的完整路径(比如/bin/bash /www/server/panel/script/backup.sh)
定位到进程后,怎么知道它在写哪个文件?lsof -p [PID] 必须跟上
光知道是 php-fpm 或 mysqld 还不够,得看它具体操作哪几个文件:
- 执行
lsof -p [PID](把[PID]换成实际进程号) - 重点筛三类路径:
/www/wwwlogs/(站点日志)、/www/server/panel/logs/(面板日志)、/tmp/(临时文件) - 如果看到同一
error.log被上百个进程同时write,基本就是日志轮转失效或权限错误导致反复重试 - 别直接
rm -f正在写的日志,用echo "" > /www/wwwlogs/xxx.log更稳妥 - 若
lsof输出里出现/dev/shm/或/proc/[PID]/fd/下的数字文件,说明用了内存映射IO,得用strace -p [PID]抓系统调用
内核都出手了?dmesg | grep -i "blocked" 是最后证据
当IO堵到极致,Linux内核会主动kill阻塞进程保命,这事不会记在宝塔日志里:
- 运行
dmesg | grep -i "blocked for" - 如果返回
task mysqld blocked for more than 120 seconds,说明IO已恶化到内核级,不是调参能解决的 - 同步查
journalctl -b | grep -i "io",交叉验证时间点是否和你看到的负载高峰吻合 - 这时候别再纠结PHP配置或OPcache,先停备份、关日志、查硬盘健康(
smartctl -a /dev/sda)
最常被忽略的一点:很多“IO高”其实不是硬盘慢,而是进程在反复失败重试——比如Laravel storage/logs 权限不对,每次写都失败,就不断fork新线程再试,await 和 load 一起飙,但CPU纹丝不动。











