AWR不记录坏块事件,但可通过db file sequential/scattered read平均等待超100ms、集中于少数file#/block#,结合alert.log中ORA-01578/ORA-01110及V$DATABASE_BLOCK_CORRUPTION视图确认坏块。

AWR里找不到“坏块”直接指标,但能定位异常IO模式
Oracle AWR本身不记录“物理坏块”这个事件类型,它不会在DBA_HIST_ACTIVE_SESS_HISTORY或DBA_HIST_SYSTEM_EVENT里存“physical block corruption detected”这种行。真正触发坏块识别的是底层IO层(如存储、ASM磁盘、OS文件系统)返回错误后,Oracle在读取时抛出ORA-01578或ORA-01110,而这些错误属于“致命错误”,不进入AWR的等待事件统计——它们直接中断会话,不计入free buffer waits或db file sequential read的平均时间里。
所以你不能靠“查AWR等什么坏块等待事件”来发现坏块,而是要反向找那些**本不该出现的、持续性高延迟IO等待+伴随特定错误日志**的组合信号。
重点关注db file sequential read和db file scattered read的异常分布
物理坏块常导致单次读取超长阻塞(尤其全表扫描或索引范围扫描时遇到坏块),表现为这两个事件的Avg wait (ms)突然飙升,且集中在少数几个file#和block#上。
- 在AWR报告的“Top 5 Timed Foreground Events”中,如果
db file sequential read排进前3,且Avg wait> 100ms(OLTP环境),需警惕 - 下钻到“IO Stats → Tablespace IO Stats”页,查看哪些
TSNAME的Av Rd(ms)显著高于均值(比如>200ms),再结合Physical Reads是否集中于某1–2个数据文件 - 用以下SQL从
DBA_HIST_SYSTEM_EVENT提取异常文件号:
SELECT file#, AVG(time_waited_micro / wait_count) / 1000 avg_ms
FROM dba_hist_system_event e
JOIN dba_hist_filestatxs f ON e.dbid = f.dbid AND e.snap_id = f.snap_id
WHERE event_name IN ('db file sequential read', 'db file scattered read')
AND wait_count > 0
AND snap_id BETWEEN &start_snap AND &end_snap
GROUP BY file#
HAVING AVG(time_waited_micro / wait_count) / 1000 > 150
ORDER BY avg_ms DESC;必须交叉验证alert.log和V$DATABASE_BLOCK_CORRUPTION
AWR只是线索,确认坏块必须依赖两个落地证据:
-
alert.log里搜索ORA-01578、ORA-01110、corrupt、bad header,时间点要和AWR异常区间对齐 - 运行
SELECT * FROM V$DATABASE_BLOCK_CORRUPTION;—— 这个视图只记录当前已检测到、尚未修复的坏块,是唯一权威来源 - 注意:
V$DATABASE_BLOCK_CORRUPTION不包含ASM磁盘层面的坏块(如ASM disk header corruption),那得查asmcmd ls -l或kfod输出
别把free buffer waits误判为坏块信号
很多DBA看到AWR里free buffer waits占比高(比如你提到的65.2% DB time),第一反应是“磁盘坏了”。其实不是。
-
free buffer waits本质是DBWn写不过来,缓冲区链表没空闲块可用,根源通常是写IO慢(如归档满、ASM磁盘组过载、存储响应延迟高),和坏块无关 - 真有坏块时,更可能看到
read by other session或enq: TX - row lock contention突增——因为坏块导致事务回滚/重试/锁等待连锁反应 - 如果
free buffer waits和write complete waits同时高,优先查V$ASM_DISK_IOSTAT或存储队列深度,而不是翻坏块
坏块最隐蔽的特征不是等待多,而是“某几个逻辑读操作永远卡住、重试、失败”,AWR里看不到这种毛刺,得靠实时v$session_wait抓瞬时堆栈,或者用oradebug dump errorstack打异常进程快照。


















