ITPub博客

首页 > 数据库 > Oracle > Oracle latch free等待原理及优化方法

Oracle latch free等待原理及优化方法

原创 Oracle 作者:dingjun123 时间:2026-05-11 21:15:43 0 删除 编辑
Oracle Latch Free 等待是数据库内部内存结构保护机制的核心体现,理解其原理对诊断高并发场景的性能瓶颈至关重要。

一、Latch 核心原理

1. 本质定位

Latch 是 Oracle 用于保护 SGA 共享内存结构的低级串行化机制,与 Lock 的区别:
表格
维度 Latch Lock
保护对象 内存结构(Buffer Cache、Library Cache 等) 数据库对象(行、表、事务)
持续时间 极短(纳秒/微秒级) 较长(事务期间)
等待行为 自旋(Spin) → 休眠(Sleep) 直接入等待队列
死锁处理 无死锁检测,依赖编码规范 有死锁检测与解决机制

2. 获取机制(两阶段)

c
复制
// 伪代码逻辑int attempts = 0;while (attempts < spin_count) {      // 阶段1: 自旋
    if (try_get_latch()) return;     // 尝试获取
    attempts++;
    spin_cpu();                      // 空转消耗CPU}sleep();                              // 阶段2: 休眠,让出CPU
  • Spin:进程在 CPU 上忙等,不释放 CPU,避免上下文切换开销
  • Sleep:自旋次数耗尽后,进程主动休眠,等待被唤醒,产生 latch free 等待事件

3. 常见 Latch 类型及热点

表格
Latch 名称 保护对象 典型高并发场景
cache buffers chains Buffer Cache 中 Hash Bucket 链表 热点块、全表扫描、索引分裂
cache buffers lru chain LRU 链表 大量物理读、DBWR 写压力
shared pool Library Cache 内存分配 硬解析、版本过多、共享池碎片
library cache SQL/PLSQL 执行计划 大量并发硬解析、授权检查
row cache objects 数据字典缓存 序列高并发、大量 DDL
redo copy Redo Log Buffer 拷贝 高并发 DML、小事务批量提交
redo allocation Redo Log Buffer 空间分配 同上

二、诊断方法论

1. AWR/ASH 定位热点 Latch

sql
复制
-- 查看 Latch 等待分布(AWR)SELECT latch_name, 
       gets, misses, 
       ROUND(misses/DECODE(gets,0,1,gets)*100, 2) miss_pct,
       sleeps, spin_gets, wait_timeFROM v$latchWHERE misses > 0ORDER BY wait_time DESC;-- ASH 实时分析SELECT event, p1 latch_addr, p2 latch_num, p3 level#, 
       sql_id, count(*)FROM v$active_session_historyWHERE event LIKE '%latch%'GROUP BY event, p1, p2, p3, sql_idORDER BY count(*) DESC;

2. 关联 SQL 与对象

sql
复制
-- 通过 latch 地址关联具体对象(cache buffers chains 为例)SELECT /*+ RULE */ 
       e.owner ||'.'|| e.segment_name segment_name,
       e.segment_type,
       SUM(tch) touch_countFROM x$bh b, dba_extents eWHERE b.hladdr = '&latch_addr'           -- 从等待事件 P1 获取
  AND b.file# = e.file_id
  AND b.dbablk BETWEEN e.block_id AND e.block_id + e.blocks - 1GROUP BY e.owner, e.segment_name, e.segment_typeORDER BY SUM(tch) DESC;

三、分场景优化策略

场景1:Cache Buffers Chains 竞争(最常见)

根因:多个 Buffer 映射到同一 Hash Bucket,形成长链表
诊断:
sql
复制
-- 查找热点 Hash BucketSELECT hladdr, count(*), SUM(tch) FROM x$bh 
GROUP BY hladdr 
HAVING count(*) > 100 ORDER BY 3 DESC;-- 查找具体热点块SELECT obj, dbarfil, dbablk, tch 
FROM x$bh 
WHERE hladdr = '&hot_latch_addr';
优化手段:
表格
方法 适用场景 操作
反向索引 索引热块(如序列主键) REVERSE 关键字重建索引
分区表 大表全表扫描导致热块 将表分区,分散到不同 Hash Chain
增大 DB_BLOCK_LRU_LATCHES 11g 之前版本 增加 LRU Latch 数量(默认 CPU_COUNT)
优化 SQL 执行计划 全表扫描替代索引 添加合适索引,减少块访问
**避免 Select * ** 宽表热点块 只查询必要列,减少块占用 Buffer 数

场景2:Library Cache / Shared Pool 竞争

根因:硬解析、大量版本游标、授权检查
诊断:
sql
复制
-- 查找高版本 SQL(Version Count)SELECT sql_id, version_count, executions, 
       sql_text 
FROM v$sqlarea 
WHERE version_count > 100 ORDER BY version_count DESC;-- 查找无效ation原因SELECT * FROM v$sql_shared_cursor WHERE sql_id = '&sql_id';
优化手段:
  1. 使用绑定变量(根本解决)
    sql
    复制
    -- 差:硬解析SELECT * FROM t WHERE id = 1;SELECT * FROM t WHERE id = 2;-- 优:软解析SELECT * FROM t WHERE id = :b1;
  2. 设置 CURSOR_SHARING=FORCE(应急,慎用)
    sql
    复制
    ALTER SYSTEM SET cursor_sharing = 'FORCE';
  3. 定期 Flush Shared Pool(临时缓解,12c+ 使用 DBMS_SHARED_POOL.PURGE)
    sql
    复制
    -- 针对特定游标exec DBMS_SHARED_POOL.PURGE('&address, &hash_value', 'C');
  4. 增大 Shared Pool(仅当内存不足时)
    sql
    复制
    -- 检查 shared pool 碎片化SELECT * FROM v$shared_pool_reserved;

场景3:Redo Copy/Allocation 竞争

根因:高并发小事务批量提交
优化手段:
sql
复制
-- 增大 Redo Log BufferALTER SYSTEM SET log_buffer = 67108864;  -- 64M,需重启-- 使用批量提交替代单条提交-- 差:每行提交FOR i IN 1..10000 LOOP
    INSERT INTO t VALUES (i);
    COMMIT;  -- 产生大量 redo allocationEND LOOP;-- 优:批量提交FOR i IN 1..10000 LOOP
    INSERT INTO t VALUES (i);END LOOP;COMMIT;

四、高级诊断:Latch 持有者追踪

当 latch free 等待极高时,需找到 谁持有 Latch 不释放:
sql
复制
-- 查找 Latch 持有者(需快速执行,信息易失)SELECT s.sid, s.serial#, s.username, s.program,
       l.name, w.holding_user, w.holding_sessionFROM v$latchholder w, v$latch l, v$session sWHERE w.latch# = l.latch#
  AND w.sid = s.sid;-- 结合 Systemstate Dump(极端情况)oradebug setmypid
oradebug dump systemstate 266;  -- Level 266 含 Latch 持有栈

五、参数调优参考

表格
参数 默认值 调优建议
_spin_count 2000 单 CPU 或 CPU 极忙时可适当降低,减少 CPU 空转
_latch_classes 0 极少使用,Oracle 内部管理
db_block_lru_latches CPU_COUNT 11g+ 自动调整,一般不动
shared_pool_size 自动 硬解析严重时适当增大,但需配合绑定变量

六、快速决策树

plain
复制
Latch Free 高?
  ├─ cache buffers chains → 热点块 → 反向索引/分区/优化SQL
  ├─ library cache/shared pool → 硬解析 → 绑定变量/CURSOR_SHARING
  ├─ redo copy/allocation → 高并发DML → 增大log_buffer/批量提交
  └─ row cache objects → 序列/DDL → 序列Cache/减少DDL


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/7655508/viewspace-3117571/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-05-07

  • 博文量
    45
  • 访问量
    90559