首页 > Technology > 正文

Linux 磁盘 IO 突然 100%?iostat/iotop 定位慢盘与捣乱进程

fenij 2026-08-17 50 Technology

服务器突然变卡,top 里 CPU 没满、内存也够,可 load average 一路飙高,网站慢到怀疑人生——这种八成是磁盘 IO 打满了。它和「磁盘空间满」不是一回事:空间满是没地方写,IO 满是写得太多或太慢,磁盘忙不过来。下面用 iostat、iotop 两步把「谁在狂写、哪块盘在喘」揪出来。

先确认是不是 IO 瓶颈

别一上来就瞎猜,先用两条命令看证据:

top            # 看 %wa(iowait)那一行,持续高于 10% 就指向磁盘
iostat -x 1    # 看设备级 %util 和 await

iostat -x 1 重点看两列:%util 接近 100% 说明这块盘在满负荷跑;await 是平均每次 IO 等待毫秒数,SATA SSD 正常就几毫秒,飙到几十上百就是严重排队。如果只是偶尔尖刺,多半是备份或日志刷盘,不用慌;持续高位才是真瓶颈。

用 iotop 抓「捣乱」的进程

知道是 IO 问题后,下一步锁定进程:

iotop -oP     # 只看真正在搞 IO 的进程,按 IO 排序

-o 只显示有 IO 的进程,-P 按进程(不是线程)聚合。常见凶手就那几个:MySQL 在刷脏数据、某个服务日志疯狂写、半夜的备份/rsync、或者索引重建。找到 PID 你就知道该调哪里了。

命令 看什么 异常信号
iostat -x 1 设备 %util / await %util≈100%、await 几十 ms
iotop -oP 进程级 IO 占用 某进程长期占 80%+ IO
df -h 盘挂在哪个目录 定位到具体挂载点

用 iostat 定位是哪块盘

iostat -x 1 按设备分行,先找出 %util 高的盘(比如 sdb),再 df -h 看这块盘挂到哪个目录。这样你才能判断是数据库盘、日志盘还是网站目录在遭罪。多盘机器尤其要分清,别一通优化搞错盘。

踩坑实录

有台 8G 内存的机器,白天网站偶尔卡几秒,top 看 CPU 才 30%、内存也够,一直以为是网络问题。后来 iostat -x 1 一看,sda 的 await 长期 180ms、%util 100%,iotopmysqld 占了 90% IO。根因是 innodb_buffer_pool_size 只给了 512M,数据量一大,查询全变成磁盘随机读。把 buffer pool 调到 4G、顺手把机械盘换成 SSD 后,await 直接掉到 2ms,卡顿消失。教训:iowait 高别光盯 CPU,先问磁盘。

常见根因与对策

根因 表现 对策
MySQL 刷脏页 mysqld IO 高 调大 innodb_buffer_pool / innodb_io_capacity
日志无轮转 某日志文件狂写 配 logrotate + truncate 应急
备份/rsync 抢资源 夜间定时任务期卡 ionice/nice 限速,错峰执行
机械盘随机写 await 长期偏高 换 SSD / 加缓存层

临时止血与长期治理

临时止血:ionice -c 3 -p <pid> 把失控进程 IO 优先级降到最低,必要时直接 kill。这属于救火,根因还在。

长期治理:上 SSD、按上面的表调数据库参数、给备份任务限速并错峰、再加监控。推荐 node_exporter + Grafana 看磁盘 IO 利用率历史曲线,设个 80% 告警,别等卡了才查。顺带一提,如果连带出现「磁盘空间满」,可以看这篇 Linux 磁盘空间满了怎么办 一起对照排查。

常见问题

iowait 高但 iotop 里没看见进程?
可能是文件系统元数据操作(如大量小文件删除),或进程刚结束但脏页还在刷。直接看 iostat -x 1 的设备列更准。

云服务器 IO 是不是被限速了?
有可能。云盘有 IOPS/吞吐上限,突发额度用尽就限流。去云监控看磁盘 IO 是否触顶,必要时升配或换高性能云盘。

await 多少算异常?
SATA SSD 一般 <10ms,机械盘 <20ms;持续几十 ms 就是明显拥挤,该优化了。

怎么提前预防?
监控磁盘 IO 利用率并设置告警,比等网站卡了再排查省心得多。

如果你也遇到过磁盘 IO 飙红的离谱场景,欢迎到 fenij.com 评论区聊聊当时是怎么定位的。

相关完整手册

系统化的排查与配置思路,建议顺手收藏这几篇完整手册: