跳过正文

数据库磁盘 I/O 瓶颈排查:基于 iostat 的核心指标解读与生产判断方法

Greatfinish
作者
Greatfinish
记录 Oracle、PostgreSQL、达梦、Linux、存储与生产环境故障处理经验。

引言
#

磁盘 I/O 是数据库性能分析中的关键因素之一。数据库的 SQL 执行、数据页读取、redo/归档写入、临时表空间排序、备份恢复等操作都会依赖底层存储性能。在生产环境中,可以通过操作系统层面的 iostatiotoppidstat 等工具快速观察磁盘负载、I/O 延迟、吞吐量和进程级 I/O 消耗,从而定位数据库是否存在磁盘 I/O 瓶颈。

iostat 属于 Linux sysstat 工具集,主要用于输出 CPU 与设备 I/O 统计信息。需要注意的是,iostat 默认第一组数据通常是系统启动以来的平均值,容易误导分析;生产排查时建议加 -y 跳过第一组历史平均值,只看实时采样数据。


一、常用监控命令
#

# 每 1 秒显示一次磁盘扩展统计,单位为 MB,跳过启动以来的第一组平均值
iostat -x -d -m -y 1

# 连续采样 10 次,每秒一次
iostat -x -d -m -y 1 10

# 显示所有磁盘和分区
iostat -x -d -m -p ALL -y 1

# 类似 top,按进程查看实时 I/O
iotop -oPa

# 查看每个进程的 I/O 统计
pidstat -d 1

# 查看 Oracle 数据库进程 I/O
pidstat -d -p $(pgrep -d, -f "ora_.*_${ORACLE_SID}") 1

# 先确认 MySQL 进程名
ps -ef | grep -i mysql | grep -v grep
# 查看 MySQL 进程 I/O
pidstat -d -p $(pidof mysqld) 1
# 查看 MySQL 进程下所有线程的 I/O
pidstat -d -t -p $(pidof mysqld) 1

# 先确认 达梦 进程名
ps -ef | grep -i dmserver | grep -v grep
# 查看指定进程 I/O,例如达梦 dmserver
pidstat -d -p $(pidof dmserver) 1
# 查看 达梦 进程下所有线程的 I/O
pidstat -d -t -p $(pidof dmserver) 1

二、iostat 核心指标解读
#

说明:以下阈值适用于通用数据库环境,重点以 Oracle OLTP/混合负载为基线,同时也适用于达梦、MySQL、PostgreSQL、SQL Server 等数据库的 I/O 初步判断。 实际阈值需要结合磁盘类型、RAID 级别、SAN/存储阵列、虚拟化平台、云盘规格以及业务基线综合判断。

指标含义通用数据库场景参考,以 Oracle 为基线
r/s, w/s每秒读 / 写请求次数,即 IOPS反映数据库随机读写压力。单块 10K/15K SAS HDD 通常约 150~300 IOPS;SATA SSD 通常数千到上万 IOPS;企业级 SAS/SATA SSD 可达数万 IOPS;NVMe SSD 可达数十万 IOPS,具体取决于型号、队列深度和阵列能力
rMB/s, wMB/s每秒读 / 写数据量,即吞吐量反映数据库大块读写能力。HDD 单盘常见 100250 MB/s;SATA SSD 常见 400550 MB/s;企业级 SAS/SATA SSD 可达 500MB/s~数 GB/s;NVMe SSD 可达数 GB/s
%util设备忙碌时间占比,表示该设备处理 I/O 的时间比例单块传统磁盘持续 > 80% 需要关注;如果同时 await 升高,通常说明磁盘接近瓶颈。对于 NVMe、多队列设备、SAN、云盘,%util 高不一定代表瓶颈,必须结合 awaitaqu-sz 和数据库等待事件判断
await平均每次 I/O 请求完成时间,单位毫秒,包含排队时间和实际服务时间数据库最关键指标之一。Oracle redo log、控制文件、数据文件 I/O 都对延迟敏感。NVMe SSD 通常应 < 1ms2ms;企业级 SSD 通常 < 2ms5ms;SATA SSD 通常 < 5ms10ms;HDD 通常 < 10ms20ms。持续 > 20ms 需要重点排查,> 50ms 通常已经明显影响数据库性能
aqu-sz / avgqu-sz平均 I/O 队列长度,不同 sysstat 版本字段名可能不同表示设备队列中等待处理的 I/O 数量。持续 > 2 且 await 升高,说明 I/O 开始排队;高并发数据库或高性能阵列中队列可以更高,但前提是 await 仍然稳定
avgrq-sz平均请求大小,通常以扇区为单位,1 扇区 = 512 字节可用于判断 I/O 模式。Oracle 常见数据块大小为 8KB,也可能是 16KB、32KB;对应约 16、32、64 个扇区。小请求通常代表随机 I/O,大请求通常代表全表扫描、备份、数据泵、RMAN、并行查询等顺序 I/O
rareq-sz, wareq-sz平均读 / 写请求大小,新版本 sysstat 中更常见用于区分读请求和写请求的大小。读请求大,可能是全表扫描、并行查询、备份读取;写请求大,可能是数据文件批量写、归档、备份、临时文件写入等

常见磁盘类型参考
#

磁盘 / 存储类型IOPS 参考吞吐量参考延迟参考数据库适用建议
7.2K SATA HDD80~150 IOPS100~180 MB/s10~20ms 或更高不建议承载核心数据库随机 I/O,可用于备份、归档、低频数据
10K / 15K SAS HDD150~300 IOPS150~250 MB/s5~15ms传统数据库环境常见,适合中低并发业务,建议配合 RAID10
SATA SSD数千到上万 IOPS400~550 MB/s0.5~5ms可用于中小型数据库,性能明显优于 HDD,但写入寿命和稳定性需关注
企业级 SAS SSD数万 IOPS500MB/s~数 GB/s0.2~2ms适合核心 OLTP 数据库,稳定性和持续写入能力更好
NVMe SSD数十万 IOPS数 GB/s0.05~1ms适合高并发、低延迟数据库场景,需关注多队列、NUMA、文件系统和调度策略
SAN 存储取决于控制器、缓存、RAID、后端磁盘取决于链路和阵列配置取决于存储负载企业 Oracle 常见架构,需要结合存储侧指标分析
云盘 / 分布式块存储取决于购买规格取决于购买规格波动较大重点关注 IOPS、吞吐上限、突发性能、云厂商限速策略

三、关键判断原则与典型现象表
#

现象判断含义可能原因处理方向
%util 高,await设备很忙,但响应速度正常高性能 SSD、NVMe、多队列存储、SAN 缓存命中较好不要单独根据 %util 判断瓶颈,继续观察数据库等待事件、SQL 响应时间和业务延迟
%util 高,await磁盘忙且 I/O 响应变慢,存在明显瓶颈风险磁盘能力不足、I/O 请求集中、存储后端繁忙、多个任务抢占同一磁盘检查热点磁盘、数据文件、redo log、归档、备份、批处理任务
await 高,%util 不一定高单次 I/O 延迟高,但设备未必满负载存储链路抖动、虚拟化存储争用、SAN 后端延迟、云盘限速、磁盘故障重点排查存储链路、云盘规格、SAN 性能、路径异常、数据库等待事件
aqu-sz / avgqu-sz 高,awaitI/O 请求已经排队并发 I/O 过高、存储处理能力不足、数据库大 SQL 或批处理集中运行降低并发任务、错峰批处理、优化 SQL、提升存储能力
r/s 高,rMB/s小块随机读较多索引回表多、热点 SQL 高频访问、执行计划不合理、缓存命中率不足检查索引、执行计划、统计信息、buffer cache 命中情况
r/s 高,await随机读延迟明显存储随机读能力不足、索引访问离散、数据分布差、热点块争用优化 SQL 和索引,减少随机回表,检查数据库等待事件
rMB/s 高,avgrq-sz大块顺序读较多全表扫描、并行查询、RMAN 备份、Data Pump 导出、报表查询检查大 SQL、并行度、备份任务、报表任务是否与业务高峰冲突
w/s 高,wMB/s小块随机写较多高频提交、小事务多、索引维护频繁、临时写入频繁检查提交频率、索引数量、事务设计、临时表空间使用
wMB/s 高,await大量写入且写延迟升高redo log 写入压力大、归档写入慢、批量 DML、备份或 ETL 写入检查 redo、归档、批量任务、备份任务、临时表空间和存储写性能
await 高但 rMB/swMB/s 不高吞吐没打满,但延迟很高随机 I/O、存储抖动、虚拟化争用、云盘 IOPS 限制、磁盘坏道或路径异常不要只看吞吐,重点排查 IOPS、延迟、队列、存储链路和数据库等待事件
avgrq-sz 较小,r/sw/s小 I/O 压力较大OLTP 随机访问、索引访问、频繁提交、热点数据访问关注 IOPS 和延迟,优化 SQL、索引、缓存和事务提交方式
avgrq-sz 较大,rMB/swMB/s大 I/O 压力较大全表扫描、并行查询、备份、导入导出、批量装载关注吞吐能力,检查任务时间窗口和存储带宽
CPU %iowaitCPU 大量时间在等待 I/O 完成数据库 I/O 延迟高、存储响应慢、大量进程等待磁盘结合 iostatpidstattop、数据库等待事件一起分析
pidstat 显示数据库进程读写很高I/O 主要由数据库产生SQL、大事务、备份、归档、临时空间、检查点等数据库行为继续从数据库内部定位具体 SQL、会话、等待事件和对象
pidstat 显示非数据库进程读写很高I/O 被外部进程抢占备份脚本、压缩、同步、杀毒、EDR、日志采集、系统任务调整任务时间,限制 I/O,排除非数据库进程干扰

四、生产环境建议告警阈值
#

说明:以下阈值适用于通用数据库生产环境,重点以 Oracle OLTP/混合负载为基线,同时也适用于 MySQL、PostgreSQL、达梦、SQL Server 等数据库场景。 实际告警阈值不应只依赖固定数值,应结合业务高峰期基线、磁盘类型、RAID/SAN/云盘规格、数据库等待事件和 SQL 响应时间综合判断。

指标关注阈值告警阈值严重告警阈值说明
%util持续 > 70%持续 > 85%持续 > 95% 且 await 升高传统 HDD 或单队列设备上参考价值较高;NVMe、多队列、SAN、云盘环境中不能单独判断瓶颈
awaitSSD 持续 > 5ms;HDD 持续 > 15msSSD 持续 > 10ms;HDD 持续 > 20ms持续 > 50ms数据库 I/O 排查最关键指标之一,表示平均 I/O 响应时间,包含排队时间和服务时间
aqu-sz / avgqu-sz持续 > 2持续 > 5持续 > 10 且 await 升高表示 I/O 队列深度。队列高但延迟低,可能是高性能设备正常并发;队列高且延迟高,说明 I/O 排队严重
r/s, w/s达到历史高峰基线的 70%达到历史高峰基线的 90%超过历史高峰并伴随 await 升高主要反映 IOPS 压力。小块随机读写场景下尤其重要
rMB/s, wMB/s达到设备或云盘规格上限的 70%达到规格上限的 85%达到规格上限的 95% 且业务变慢主要反映吞吐压力。备份、导入导出、全表扫描、批处理场景下重点关注
avgrq-sz明显偏离业务基线小 I/O 数量快速升高或大 I/O 持续打满请求大小异常变化并伴随延迟升高用于判断 I/O 类型变化。小请求通常偏随机 I/O,大请求通常偏顺序 I/O
CPU %iowait持续 > 10%持续 > 20%持续 > 40%表示 CPU 等待 I/O 完成的比例。需要结合 iostatpidstat 和数据库等待事件判断
数据库进程 kB_rd/skB_wr/s明显高于日常基线长时间维持高位高 I/O 同时业务响应明显下降通过 pidstat -d 判断 I/O 是否主要由数据库进程产生
非数据库进程 I/O出现在业务高峰期持续抢占磁盘带宽导致数据库 await 升高重点检查备份、压缩、同步、杀毒、EDR、日志采集、系统任务

不同磁盘类型的延迟参考
#

磁盘 / 存储类型正常参考关注阈值告警阈值说明
7.2K SATA HDD10~20ms> 20ms> 50ms不建议承载核心数据库随机 I/O
10K / 15K SAS HDD5~15ms> 15ms> 30ms传统数据库环境常见,建议配合 RAID10
SATA SSD0.5~5ms> 5ms> 10ms适合中小型数据库,需关注持续写入能力
企业级 SAS/SATA SSD0.2~2ms> 3ms> 5~10ms适合核心 OLTP 数据库
NVMe SSD0.05~1ms> 2ms> 5ms高性能低延迟场景,需结合队列深度判断
SAN 存储取决于阵列和链路明显高于历史基线持续高于基线 2 倍以上需要结合存储控制器、缓存、RAID、链路和多路径分析
云盘 / 分布式块存储取决于购买规格接近规格上限或延迟抖动持续限速或延迟突增重点关注 IOPS、吞吐上限、突发积分、云厂商限速策略

告警判断建议
#

生产环境中,不建议只设置单一指标告警。更推荐使用组合条件。

告警组合判断含义建议动作
%util > 85%await > 20ms磁盘繁忙且 I/O 响应变慢检查热点磁盘、数据库进程、备份、归档、批处理
aqu-sz > 5await > 20msI/O 请求排队明显检查并发任务、存储能力、数据库大 SQL
await > 50ms 持续 5 分钟I/O 延迟严重立即排查存储、数据库等待事件、系统任务
r/s 高但 rMB/s 不高,且 await 升高小块随机读压力大检查 SQL、索引、执行计划、缓存命中率
wMB/s 高且 await 升高大量写入导致延迟升高检查日志文件、归档、批量 DML、备份、ETL
CPU %iowait > 20%await 升高系统明显等待磁盘 I/O结合 iostatpidstat、数据库等待事件综合定位
非数据库进程 I/O 高且数据库响应变慢外部任务抢占磁盘调整备份、压缩、同步、杀毒、日志采集任务

五、总结
#

生产环境中的 I/O 告警不应只看 %util,更应关注 awaitaqu-sz、IOPS、吞吐量和数据库内部等待事件的组合变化。对于数据库系统来说,磁盘是否“忙”不是最关键的问题,I/O 延迟是否持续升高、请求是否排队、业务 SQL 是否变慢,才是判断 I/O 瓶颈的核心依据。