AWR报告中latch: cache buffers chains高占比并非缓存不足,而是SQL反复扫描同一buffer header(热块),需结合V$ASH的CURRENT_FILE#和CURRENT_BLOCK#(19c+已稳定填充)实时定位热点块与SQL_ID,而非依赖AWR汇总数据。

AWR 报告里出现 latch: cache buffers chains 高占比,不是缓存配小了,而是有 SQL 正在反复扫描同一组 buffer header(即“热链”或“热块”),AWR 只是暴露现象,不能直接定位到具体块和 SQL_ID —— 必须结合实时 ASH 或历史 ASH 的原始采样字段才能下钻。
为什么 AWB/ASH 中的 CURRENT_FILE# 和 CURRENT_BLOCK# 在 19c+ 可信
Oracle 19c 起,V$ACTIVE_SESSION_HISTORY 的 CURRENT_FILE# 和 CURRENT_BLOCK# 字段已稳定填充,不再依赖解析 P1RAW。这比查 X$BH.TCH 更准、更及时,尤其对持续几十秒的突发争用。
- 别用
DBA_HIST_ACTIVE_SESS_HISTORY查最近 1 分钟问题:它默认每 10 秒采样一次,且快照只保留 1 小时,容易漏掉短时尖峰 -
V$ACTIVE_SESSION_HISTORY是内存视图,采样粒度为 1 秒(实际受 _ash_sampling_interval 控制,默认 1s),更适合抓实时争用 - 如果数据库启用了
ASH并未被刷出内存,V$ASH比 AWR 报告里的汇总等待事件明细更细粒度
怎么从 ASH 快速锁定热点块与对应 SQL_ID
运行以下语句(注意时间范围控制在 60 秒内):
SELECT CURRENT_FILE# fn, CURRENT_BLOCK# blk, SQL_ID, COUNT(*) cnt FROM V$ACTIVE_SESSION_HISTORY WHERE EVENT = 'latch: cache buffers chains' AND SAMPLE_TIME > SYSDATE - 1/1440 GROUP BY CURRENT_FILE#, CURRENT_BLOCK#, SQL_ID ORDER BY cnt DESC FETCH FIRST 10 ROWS ONLY;
- 结果中
fn+blk组合重复出现次数高,说明是热点块;若多个SQL_ID共享同一(fn, blk),说明是多会话争用同一块 - 若某
SQL_ID单独占绝大多数cnt,优先检查该 SQL 的执行计划是否走了全表扫描或嵌套循环驱动大表 - 避免直接查
DBA_EXTENTS定位对象:分区多、索引深时可能超时;改用DBA_OBJECTS.DATA_OBJECT_ID关联V$BH.OBJ
拿到 (file#, block#) 后怎么快速识别对象类型和归属
不要走 DBA_EXTENTS → DBA_OBJECTS 两层关联的老路。19c 推荐路径:
- 先确认该块是否在 buffer cache 中:查
V$BH过滤FILE# = &fn AND DBABLK = &blk,看TCH值是否显著高于均值(比如 > 50) - 用
OBJ字段直接关联DBA_OBJECTS.DATA_OBJECT_ID(不是OBJECT_ID),语句示例:SELECT OWNER, OBJECT_NAME, OBJECT_TYPE, SUBOBJECT_NAME FROM DBA_OBJECTS WHERE DATA_OBJECT_ID = (SELECT OBJ FROM V$BH WHERE FILE# = &fn AND DBABLK = &blk AND ROWNUM = 1); - 若
OBJECT_TYPE是INDEX,但SUBOBJECT_NAME非空,说明是分区索引子分区,别只看PARTITION_NAME - 警惕系统表伪热点:如
WRI$_OPTSTAT_HISTHEAD_HISTORY在自动统计信息收集窗口期会短暂成为热点,非业务 SQL 引起
真正难的不是查出哪块热,而是判断“为什么这块被高频访问”——可能是低效 SQL、缺失索引、反向索引误用、或应用层循环更新单行。这些无法靠调参绕过,必须回到 SQL 执行路径本身。AWR 提供的是“发生了什么”,而 V$ASH 的原始字段才是“正在发生什么”的快照入口。


















