AWR中db file sequential read排第一不等于磁盘慢,需交叉验证Load Profile、Instance Efficiency Percentages、Redo Size及IOWAIT_TIME,并结合Wait Event Histogram、v$asm_disk_iostat_sparse等精准定位真实IO瓶颈。

别只看Top 5 Events,先确认是不是真IO瓶颈
AWR里db file sequential read排第一,不等于磁盘慢。必须交叉验证Load Profile和Instance Efficiency Percentages:如果Physical Reads Per Second持续超2000,且Buffer Hit Ratio低于90%,才说明物理读压力真实存在;如果Logical Reads Per Second也同步飙升,大概率是SQL没走索引或内存太小,不是存储问题。
还要比对Redo Size Per Second——若IO压力上升时重做日志写入也翻倍,可能是应用批量提交导致LGWR频繁刷盘,进而拖累数据文件IO,这不是磁盘本身的问题。
-
IOWAIT_TIME在Operating System Statistics节占比超过20%,但db file sequential read等待不突出 → 瓶颈在ASM层或OS驱动,不在数据库逻辑层 - 查
v$asm_disk_iostat发现某盘READ_ERRS > 0→ 立即检查对应HEADER_STATUS是否为PROVISIONED或FAILED - 云环境(如AWS EBS gp3)必须用
v$asm_disk_iostat_sparse,否则看不到READ_TIME_WAIT,无法区分是ASM处理慢还是后端存储卡住
Wait Event Histogram才是IO物理瓶颈的最早信号
别信db file sequential read的平均等待毫秒数——它会被大量短延时IO拉低。真正暴露物理层排队的是Wait Event Histogram里的三个区间:
- 0–1 ms占比从75%骤降到40%以下 → I/O开始在OS或存储队列里排队,不再是“发完就回”
- 16–32 ms与32–64 ms区间计数同步激增超2倍,且与
db file parallel write共现 → 磁盘响应跟不上并发写入节奏 -
Wait Event Histogram Detail (4 sec to 2 min)中出现哪怕0.3%的db file sequential read→ 单次读卡住4秒以上,绝非SQL或缓存问题,是HBA队列深度严重不足或存储链路故障
定位具体慢盘或慢文件,绕过Tablespace IO Stats陷阱
Tablespace IO Stats对ASM完全无效:一个表空间的数据文件可能跨多个磁盘组,Av Rd(ms)是加权平均值,一块故障SSD延迟飙到2000ms,会被其他盘拉低到50ms,根本看不出问题。
必须下钻到磁盘或文件粒度:
- 查
v$asm_disk_iostat算出毫秒级延迟:AVG_READ_TIME = READ_TIME / READS * 10,OLTP环境持续>20ms就得干预 - 查
dba_hist_filestatxs时注意:readtim单位是百分之一秒,不是毫秒;必须用NULLIF(f.phyrds, 0)防除零 - 高延迟文件要结合
Physical Reads看分布:读次数少但avg_read_ms极高 → 存储链路问题(如SAN路径拥塞);读次数多且延迟高 → SQL或索引问题
ASM环境下必须查v$asm_disk_iostat_sparse或v$asm_disk_spare_stat
普通本地盘、SAN LUN用v$asm_disk_stat;但云/虚拟化稀疏盘(AWS EBS gp3、VMware VMDK)必须用v$asm_disk_iostat_sparse,否则漏掉关键指标READ_TIME_WAIT——它能分离ASM处理时间和后端存储响应时间。
还要关注稀疏盘特有的碎片化指标:
-
ALLOCATION_RATE_MB_PER_MIN在同组磁盘间严重不均(如某盘是其他盘5倍以上)→ LUN映射不均或底层QoS限速 -
FRAGMENTATION_PCT在1小时内从5%飙升至40% → 批量DELETE后未触发UNMAP,或云存储后端回收策略失效 - 多租户场景下,单个PDB的IO风暴可能被ASM平滑掩盖,必须通过ASH反向追踪
EVENT为cell single block physical read的具体会话和SQL
实际排查中最容易被忽略的是:Wait Event Histogram里那0.3%的4秒以上等待,以及v$asm_disk_iostat_sparse中READ_TIME_WAIT和READ_TIME的差值——这个差值才是真正属于存储后端的时间,它不骗人。



















