先看awr报告top 5 timed events,若buffer busy waits占比超5%且time_waited_ms高,再结合segments by buffer busy waits定位争用段类型及对应class#(如索引段→220/130,表段头→4,undo段→17/18),并严格使用1小时内问题时段与正常时段报告对比分析。

Buffer Busy Waits在AWR里怎么定位
直接看 Top 5 Timed Events 部分,如果 buffer busy waits 排进前五且占比超过总 DB Time 的 5%,就得动手查。注意别只盯“次数”,要看 time_waited_ms 和平均等待毫秒数(Avg Wait(ms))——单次等 10ms 但发生 100 万次,比单次等 100ms 发生 1 万次更值得优先处理。
常见干扰项:gc buffer busy acquire 或 gc buffer busy release 是 RAC 环境特有,和单实例的 buffer busy waits 不是一回事,别混着分析。
查清是哪类块在争用
AWR 报告里没有直接告诉你 class#,得靠 Segments by Buffer Busy Waits 这一节反推:
- 如果高排位的是索引段(尤其名字带
_PK或_UK),大概率是索引叶块分裂导致的热块,对应 class# 220(DML 冲突)或 130(未缓存块) - 如果高排位的是表段本身,且集中在
SEGMENT_HEADER行,class# 很可能是 4(数据段头争用) - 如果高排位的是
UNDO$或UNDOTBS1这类回滚段名,class# 多为 17(UNDO 段头)或 18(UNDO 块)
没这节?说明 AWR 默认没采集——执行 awrrpt.sql 时选 “Advanced” 模式,或手动查 dba_hist_seg_stat 补充。
为什么只看1小时内的AWR报告
Buffer Busy Waits 是瞬时争用型问题,拖长报告时间会稀释峰值信号。比如某业务每晚 20:00–20:05 批量更新配置表,若拉取 19:00–21:00 的报告,等待事件可能被均摊成“不严重”;而 20:00–20:05 的报告里,buffer busy waits 占比可能飙到 40%+。
必须配一个“正常时段”报告对比——同样是 5 分钟,白天低峰期的 buffer busy waits 总等待时间如果是 200ms,问题时段突然变成 12000ms,这个 60 倍增幅才是真实压力点。
容易被忽略的 class# 130 场景
很多人一见 buffer busy waits 就查热块、加索引、拆分区,结果发现 db file sequential read 同步飙升——这时该回头检查 class# 是否为 130(数据块未缓存)。
典型表现:
- 多个会话几乎同时执行相同 SQL(如定时任务刷新缓存)
- 目标块不在 Buffer Cache,首个会话触发物理读,其余会话卡在
buffer busy waits等它读完 - AWR 中伴随大量
db file sequential read,且read by other session也高
解决不是加 Latch 或调参数,而是让块提前进缓存:对小配置表执行 alter table xxx storage(buffer_pool keep),或用 cache 提示强制缓存。











