服务器 IO 过高排查流程
实操篇 — 故障排查与优化
整体思路:先看全局 IO 状态 → 定位高 IO 进程 → 分析读写文件/磁盘 → 根因优化
一、整体磁盘 IO 概览(先确认是否真 IO 瓶颈)
1. 查看整机磁盘 IO
# 每秒刷新,看整体 IO、%util(核心指标)
iostat -xd 1
重点字段:
| 字段 | 说明 |
|---|---|
%util | 设备繁忙百分比,持续 >80% 基本判定 IO 瓶颈 |
rMB/s | 读吞吐量 |
wMB/s | 写吞吐量 |
await | IO 平均等待时间,正常 <5ms,>10ms 说明排队严重 |
%iowait | 系统 CPU 花在等待 IO 的时间,持续高 = IO 阻塞 |
2. 结合系统负载
top
# 看 %iowait 列,值高代表大量进程在等磁盘 IO
二、定位高 IO 进程
1. 实时查看进程 IO(首选)
# 按 IO 排序,每秒刷新
iotop -oP 1
DISK READ/DISK WRITE:直接看到进程实时读写速度- 找到流量大、持续占用的 PID、进程名
2. pidstat 简洁版
pidstat -d 1
# 查看每个进程的磁盘读写、IO 等待
三、定位进程读写文件
拿到高 IO PID(假设为 1234):
1. 查看进程打开的文件
lsof -p 1234
2. 跟踪进程实时读写
# 跟踪该 PID 的系统调用,重点看 read/write
strace -p 1234 -e trace=file,read,write
3. 查看目录整体读写
# 统计目录文件大小、增量,排查日志刷屏、大文件拷贝
du -sh /xxx/path
# 观察文件增长
watch -n1 ls -lh /xxx/path
四、区分 IO 类型判断根因
场景 1:大量写 IO(最常见)
典型现象:wMB/s 高、%util 满
常见原因:
- 日志狂打:应用日志、Nginx/Tomcat/数据库日志不停刷盘
- 数据库:MySQL 慢查询、大批量 INSERT/UPDATE、事务日志刷盘
- 定时任务:备份、同步、文件拷贝、解压压缩
- 应用:本地临时文件、缓存文件频繁写入
场景 2:大量读 IO
典型现象:rMB/s 高
常见原因:
- 数据库:全表扫描、索引失效、大量查询热点数据
- 程序批量读取大文件、离线分析、日志采集
- 缓存失效,大量请求直读磁盘
场景 3:随机 IO 高(数据库典型)
现象:await 很高、吞吐不大,但磁盘跑满
- MySQL/PostgreSQL 索引差、行锁、频繁小事务、分页查询烂
场景 4:磁盘硬件问题
- 单块机械盘(HDD)性能弱,并发 IO 直接打满
- 磁盘故障、RAID 降级、缓存策略异常
- 分区/挂载点不合理,热点集中单块盘
五、数据库专项排查(IO 高高发区)
以 MySQL 为例:
1. 查看慢查询
show variables like 'slow_query%';
# 分析慢日志
mysqldumpslow -s t /var/log/mysql/slow.log
2. 查看当前会话 IO、事务
show processlist;
show engine innodb status\G
3. 检查刷盘策略
innodb_flush_log_at_trx_commit、sync_binlog 配置过严会拉高写 IO。
六、快速临时缓解 + 根治方案
临时应急
- 暂停/杀掉异常高 IO 进程、定时任务
- 临时滚动清空暴涨日志(先备份)
- 数据库先 kill 掉耗时大查询
根治方向
| 方向 | 措施 |
|---|---|
| 日志 | 分级日志、轮转切割、关闭冗余 DEBUG 日志、远端日志收集 |
| 数据库 | 加索引、优化 SQL、分库分表、调整刷盘参数、升级 SSD |
| 应用 | 加本地缓存/Redis,减少磁盘直接读写 |
| 架构 | 冷热数据分离、大文件异步处理、避免同步大 IO 操作 |
七、排查命令速记(一条流)
# 1. 看整机 IO
iostat -xd 1
# 2. 抓高 IO 进程
iotop -o 1
# 3. 查进程打开文件
lsof -p PID
# 4. 跟踪读写行为
strace -p PID
# 5. 看系统负载 + iowait
top
关联文档
- ../storage/iostat 命令详解 — IO 查看工具详解
- Linux — Linux 系统管理主页
- ../../monitoring/监控与可观测性 — 系统监控体系
- ../../network/technology/eBPF 技术详解 — 内核级 IO 追踪