先说结论:磁盘 IO 高先看 iowait、await 和 %util,再分清是读多还是写多、随机还是顺序。常见元凶是慢查询全表扫描、日志刷盘、备份压缩、云盘 IOPS 限额。别一看到 IO 高就换 SSD,先找到是谁在打盘。
三个命令先跑:
iostat -x 1 5
# 看 await、r_await、w_await、%util
vmstat 1 5
# 看 wa(IO 等待)
iotop -o
# 看哪个进程在读写在打盘
await 是单次 IO 的平均等待时间,SSD 上长期高于 20ms 就值得查;%util 贴着 100% 说明设备忙不过来;wa 高但 %util 不高,可能是网络存储或虚拟化层的问题。
第一步:找进程
pidstat -d 1 5
iotop -o -P
# 找到读写最高的进程,再看它在干什么
如果是数据库,看慢查询和全表扫描;如果是 PHP/Java,看日志级别和临时文件;如果是备份/压缩,看调度时间;如果是系统进程,看是不是日志刷盘或内核问题。

第二步:看数据库
SHOW FULL PROCESSLIST;
SHOW ENGINE INNODB STATUS;
SHOW VARIABLES LIKE 'slow_query_log';
数据库是 IO 大户。全表扫描、没索引的排序、大事务、binlog 刷盘都会把磁盘打满。先把慢查询日志开起来,按 rows_examined 排序,补索引、拆查询、避免 N+1。
如果是写入高,看 binlog 同步、批量导入、备份任务;如果是读取高,看 buffer pool 是否太小、是否有大量随机读。

第三步:看日志和备份
- 日志级别调到 debug,写入量会翻几倍
- 访问日志每个请求一行,量大时 IO 很可观
- 备份、压缩、解压、rsync 都是顺序大 IO
- 定时任务集中在整点,容易和业务高峰重叠
把备份、压缩、日志归档挪到低峰,或者限制 ionice 优先级,能明显缓解业务抖动。
第四步:看云盘限额
云盘有 IOPS 和吞吐上限,规格不同差别很大。小容量云盘可能只有几百 IOPS,跑数据库会明显排队;突发型云盘有 burst 额度,用完就掉速。
# 看块设备队列和调度器
cat /sys/block/vda/queue/scheduler
cat /sys/block/vda/queue/nr_requests
如果 await 高但进程读写量不大,先确认云盘规格和限额,再考虑换盘或升配。

第五步:文件系统和挂载
ext4、xfs 的参数、挂载选项(noatime、nodiratime)会影响写入量;网络存储(NFS、CIFS)延迟高,不适合跑数据库。容器里还要看 volume 是本地盘还是网络盘。
第六步:优化和扩容
- 慢查询治理和索引优化
- 日志降级、轮转、异步刷盘
- 备份/压缩错峰,限制 IO 优先级
- 加内存扩大 buffer pool / page cache
- 换更高 IOPS 的云盘或本地 SSD
- 读写分离,把报表挪到从库
怎么预防
- 监控 await、%util、iowait 和云盘限额
- 慢查询日志常开,按周复盘
- 备份和日志归档错峰
- 数据库和业务盘分开
- 压测确认峰值 IOPS 不超过云盘上限
iostat 字段怎么看
r/s 和 w/s 是每秒读写次数,rkB/s 和 wkB/s 是吞吐,await 是平均等待,%util 是设备忙的比例。随机小 IO 多时,IOPS 先到顶;顺序大 IO 多时,吞吐先到顶。先判断类型,再谈优化。
用 fio 做基线
fio --name=randrw --filename=test --size=1G --bs=4k \
--iodepth=64 --ioengine=libaio --direct=1 --rw=randrw --rwmixread=75
在业务低峰跑一次,记录 IOPS、吞吐和 await,作为这台机器的基线。以后 IO 高时对比基线,能快速判断是业务涨了还是盘变慢了。
监控和告警
把 await、%util、iowait、云盘 IOPS 使用率接进监控,超过阈值告警。只看 CPU 和内存,磁盘先挂了你可能最后一个知道。
缓存和读写分离
读多写少的业务,先加 Redis 或 page cache 挡住热点读,再把报表、列表、搜索挪到从库。写多的业务看 binlog 和 redo 刷盘策略,必要时换更高 IOPS 的盘。缓存和读写分离能解决大部分 IO 压力,比直接换盘便宜。
如果 IO 高伴随大量随机读,先确认 buffer pool 是否太小;如果伴随大量顺序写,先确认备份和日志是否在高峰期跑。
压测前先热身,避免缓存冷启动把第一次结果拉低;记录基线时同时写清云盘规格、文件系统和挂载参数。
有条件的话,把云监控里的 IOPS 和吞吐曲线和宿主机 iostat 对照,能快速区分是云盘限额还是应用自己打满。
IO 问题多半有周期性,记录发生时间和任务排期,往往一眼就能对上。
,早发现早处理,比事后补救便宜得多。
常见问题 FAQ
Q1:IO 高但 CPU 不高,正常吗?
正常。IO 等待不占 CPU,wa 高说明进程在等磁盘。看 await 和 %util 才能判断严重程度。
Q2:换 SSD 能解决吗?
如果是云盘 IOPS 限额或随机读太多,换高 IOPS 盘有用;如果是慢查询全表扫描,换盘只是把问题推迟。
Q3:await 多少算高?
SSD 上长期高于 20ms 要查,机械盘 20ms 可能正常。结合 %util 和业务延迟一起看。
Q4:容器里怎么查?
在宿主机看 iostat 和 iotop,容器内看进程;注意 volume 是本地盘还是网络盘。
Q5:备份导致 IO 高怎么办?
错峰、限速、用快照备份,或者把备份放到从库/对象存储,别在主库上压缩。
总结
磁盘 IO 高的排查顺序是:iostat 看 await/util → iotop 找进程 → 查数据库和慢查询 → 看日志备份 → 确认云盘限额 → 优化或换盘。先找到谁在打盘,再决定花多少钱。
需要一台 IOPS 更稳的机器跑数据库或压测,可以按小时开一台萤光云香港 CN2 VPS,用 fio 先测一轮。







