一、先快速判断:是不是 I/O 高?
bash
top
看这一行:
%Cpu(s): 5.2 us, 2.3 sy, 0.0 ni, 82.5 id, **10.0 wa**
只要满足:
- wa(iowait) ≥ 10% → 已经是 I/O 高
- wa ≥ 20% → 严重 I/O 瓶颈,系统会很卡
- wa ≥ 30% → 基本卡死
只要 wa 高,CPU 再闲也没用,系统就是慢。
二、第一步:看谁在疯狂读写(最关键)
bash
iotop
快捷键:
- o:只看正在读写的进程
- P:按读写字节排序
你会立刻看到:
- 哪个 PID
- 哪个程序(mysqld、java、rsync、tar、gzip 等)
- 读速度、写速度
90% 的问题,这一步直接定位。
三、第二步:看哪个磁盘在忙
bash
iostat -x 1 2
重点看:
- util:磁盘繁忙度
- util ≥ 70% → 很忙
- util ≥ 100% → 跑满
- rMB/s、wMB/s:真实读写速度
- await:I/O 响应时间
- await < 10ms:正常
- await > 50ms:很慢
- await > 100ms:磁盘快挂了 / 被打满
四、第三步:看哪个文件在被疯狂读写
bash
lsof -p 进程PID
或者用:
bash
ls -lh /proc/进程PID/fd
能看到:
- 日志文件
- 数据文件
- 临时文件
五、第四步:看哪个目录 / 文件最大
bash
# 看根目录下谁最大
du -sh /* | sort -rh | head -10
# 看某个目录
du -sh /data/* | sort -rh | head -10
常见凶手:
- 超大日志
- 慢查询日志
- 大量小文件读写
- 数据库刷盘
六、线上 I/O 高 常见真凶(你对照看)
- MySQL 疯狂写
- 大量插入 / 更新
- 没有索引,全表扫描
- 刷 binlog/redo 日志
- 日志疯狂输出
- 程序疯狂打日志(ERROR 死循环打印)
- 日志没切割,文件巨大
- 定时任务在跑
- find、tar、gzip、rsync、备份
- 白天跑,直接打满磁盘
- SWAP 被使用
- 内存不够,用 swap = 超级慢
free -h - 磁盘本身故障
- util 100%,但没有进程读写
- await 特别高→ 硬盘快坏了
七、最简单万能排查流程(背这个)
- top 看 wa 高不高
- iotop 找耗 I/O 的进程
- iostat -x 看哪块盘忙
- lsof 看读写哪个文件
- du 看哪个目录大
- 处理:停进程 / 切日志 / 加索引 / 换盘
八、你可以直接用的一句话命令
bash
# 实时看I/O
iotop
# 看磁盘繁忙度
iostat -x 1
# 看最占空间的目录
du -sh /* | sort -rh | head 10
# 看某个进程在读写什么
lsof -p PID