应直接查v$active_session_history的current_file#和current_block#定位热点块,严格过滤buffer busy waits等事件、限定1小时内样本、聚合取Top5,并用DBA_EXTENTS区间匹配定位对象,结合P3(class#)判断争用类型,RAC下需关注gc等待和LCK0协调。

直接查 v$active_session_history 的 current_file# 和 current_block#
v$active_session_history 不暴露物理块地址,但 current_file# 和 current_block# 是唯一直接指向热点块的线索。别查 sql_text 或模糊匹配 event,那会漏掉真实争用点。
- 过滤必须严格:event IN ('buffer busy waits', 'read by other session')
- 时间窗口要窄:sample_time > SYSDATE - 1/24(最近 1 小时),避免历史噪声干扰
- 聚合后只取 Top 5:FETCH FIRST 5 ROWS ONLY,全表扫 v$active_session_history 极慢
示例语句:
SELECT current_file#, current_block#, COUNT(*) cnt
FROM v$active_session_history
WHERE event IN ('buffer busy waits', 'read by other session')
AND sample_time > SYSDATE - 1/24
GROUP BY current_file#, current_block#
ORDER BY cnt DESC
FETCH FIRST 5 ROWS ONLY;
用 DBA_EXTENTS 做区间匹配,不是等值查询
current_block# 是逻辑块号,不能拿它去 JOIN DBA_OBJECTS.object_id —— 会错。必须走 DBA_EXTENTS,且条件是区间判断:
- &BLOCK_ID BETWEEN block_id AND block_id + blocks - 1
- 一个块只属于一个 extent,但可能跨多个 segment(比如分区表)
查不到结果?说明该块属于系统段:
- 回滚段 → 查
v$rollstat - 临时段或 UNDO 块 → 查
v$tempseg_usage - LOB 段 → 先查
DBA_LOBS找真实段名(如SYS_LOB0000098765X$$),再定位
别跳过 P3(class#),它决定调优方向
Oracle 12c 起,P3 是块类型编号(class#),不是原因码。跳过这步就动手改参数,基本白忙。
- P3 = 1:普通数据块热 → 常见于升序主键 INSERT、小表全扫
- P3 = 4:段头争用 → 表空间还在用 MSSM,FREELIST 是单点瓶颈
- P3 = 13:undo header 争用 → 需检查事务粒度,考虑增加 undo 表空间或拆分大事务
CURRENT_OBJ# = 0 不代表没对象,可能是刚进入逻辑读、还没绑定段名——这时更要盯紧 current_file# 和 current_block#。
注意 RAC 下的 LCK0 协调和 false negative
RAC 环境下,buffer busy waits 可能由远程实例的 LCK0 进程协调引发,ASH 样本未必稳定捕获本地 current_file#/current_block#。
- 如果 Top 热点块反复出现但 DBA_EXTENTS 查不到用户对象,优先怀疑是 undo header 或 global cache header 块
- gc buffer busy acquire 平均等待 >10 ms 且仅由少数会话触发,基本锁定 RAC 热点块,跟整体负载无关
最易被忽略的是:current_obj# 在索引叶块、根块、undo header 块上经常为空或不准,直接 JOIN dba_objects 会漏掉关键线索。











