Oracle 19c中latch: cache buffers chains争用根源是热块或热链,应优先通过V$ACTIVE_SESSION_HISTORY查CURRENT_FILE#和CURRENT_BLOCK#定位热点块,再关联DBA_OBJECTS.DATA_OBJECT_ID快速识别对象,而非调大db_cache_size或修改隐含参数。
oracle 19c 中出现 latch: cache buffers chains 等待,基本可以断定是 buffer cache 层面的 latch 争用,根源在“热块”或“热链”——不是配置太低,而是访问模式出了问题。优化核心不是调大 db_cache_size,而是快速定位并缓解争用源头。
怎么从 ASH 找出正在争用的热点块(19c 推荐路径)
Oracle 19c 的 DBA_HIST_ACTIVE_SESS_HISTORY 和实时 V$ACTIVE_SESSION_HISTORY 是最可靠入口,比查 X$BH.TCH 更准、更及时,尤其对短时突发争用。
-
V$ACTIVE_SESSION_HISTORY中EVENT = 'latch: cache buffers chains'的记录,直接提取CURRENT_FILE#和CURRENT_BLOCK#—— 这些字段在 19c 已稳定填充,无需依赖P1RAW解析 - 聚合统计时加
GROUP BY CURRENT_FILE#, CURRENT_BLOCK#, SQL_ID,能一眼看出哪些(文件号, 块号)组合被高频访问,且是否集中在同一 SQL - 避免用
DBA_HIST_ACTIVE_SESS_HISTORY查最近 5 分钟的问题:它的采样延迟可能达 10 秒,且默认只保留 1 小时快照;优先跑V$ASH实时视图 - 示例语句:
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 -- 最近 1 分钟 GROUP BY CURRENT_FILE#, CURRENT_BLOCK#, SQL_ID ORDER BY cnt DESC FETCH FIRST 10 ROWS ONLY;
拿到块号后,怎么快速确认对象和类型(别卡在 DBA_EXTENTS)
查 DBA_EXTENTS 在大库中可能慢到超时,尤其当分区多、索引深时。19c 提供了更快的替代路径。
- 用
DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE和DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK直接从地址反解(如果手头只有P1RAW) - 更推荐:查
DBA_OBJECTS关联V$BH的OBJ字段,但注意V$BH.OBJ对应的是DATA_OBJECT_ID,不是OBJECT_ID,必须用DBA_OBJECTS.DATA_OBJECT_ID关联 - 若块属于索引叶子块,
DBA_OBJECTS.OBJECT_TYPE显示为INDEX,但实际可能是分区索引的某个子分区 —— 此时看DBA_OBJECTS.SUBOBJECT_NAME比看PARTITION_NAME更准 - 警惕“伪热点”:某些系统表(如
WRI$_OPTSTAT_HISTHEAD_HISTORY)在自动统计信息收集期间会集中写入,块号固定但属正常行为,需结合SQL_ID和执行计划判断
为什么优化 SQL 比调参数更有效(19c 的现实约束)
19c 默认启用 _use_single_log_writer=TRUE 和更激进的 latch 优化,但 cache buffers chains 争用本质是逻辑读密集型访问引发的,参数调整空间极小。
-
_db_block_hash_latches隐含参数在 19c 中已固化为自适应值,硬改可能导致实例启动失败;官方明确不支持手动调整 - 增大
db_cache_size只会让更多块进入 cache,若 SQL 仍全表扫描或索引范围扫描过宽,hash chain 长度反而增加,争用可能加剧 - 真正有效的动作是压低单次执行的
BUFFER_GETS:比如把嵌套循环驱动表换掉、加提示强制走索引唯一扫描、拆分大事务减少重复块访问 - 一个典型信号:
V$SQL中BUFFER_GETS / EXECUTIONS > 10000且SQL_ID频繁出现在 ASH 的 CBC 等待中 —— 这类 SQL 优先重写,而非调 latch
最后提醒一点:19c 的 V$ACTIVE_SESSION_HISTORY 默认每秒采样一次,但若 latch: cache buffers chains 等待持续时间短于 10 毫秒,它可能根本不会被捕获。此时必须配合 ORA-600 跟踪或启用 sql_trace 抓取真实执行流,不能只信 ASH 汇总结果。


















