Latch

Latch:门闩。

目的:

  • 保证资源的串行访问

    • 保护SGA的资源访问
    • 保护内存的分配
  • 保证执行的串行化

    • 保护关键资源的串行执行
    • 防止内存结构损坏

Latch 和 Enqueue 对比:

Latch Lock(Enqueue)
队列性 03-Latch - 图1 03-Latch - 图2
时长 很短 可能很长
层面 数据库内存资源层 业务应用层
目的 保证资源的完整性 保证业务操作的完整性

Latch的位置:内存的SGA区(PGA不是会话共享的,所以不存在并发,也就不存在锁)。

Latch的应用(资源的请求和分配):

  • 共享池:sql解析、sql重用….
  • 数据缓冲池:

    • 数据访问,数据写入磁盘,数据读入内存
    • 修改数据块
    • 数据段扩展
    • ….

Latch的获取

Wait方式:

如果无法获取请求的Latch,则有两种情况:

  • spin(自旋):当一个会话无法获得需要的latch时,会继续使用cpu(cpu空转),达到一个间隔后,再次尝试申请latch,直到达到最大的重试次数
  • sleep:当一个会话无法获得需要的latch时,会等待一段时间(sleep),达到一个间隔后,再次尝试申请latch,如此反复,直到达到最大的重试次数。

No wait方式:如果无法获取请求的latch,不会发生sleep或者spin,转而去获取其他可用的Latch。

Shared pool的latch争用

使用绑定变量减少Shared Pool里的Latch争用:

例如:

没有使用变量绑定时:

  1. create or replace procedure p1
  2. as
  3. l_cn number;
  4. begin
  5. for i in 1 .. 10000
  6. loop
  7. -- 拼接sql,不使用变量绑定
  8. execute immediate 'select count(*) from t where x=' || i into l_cnt;
  9. end loop;
  10. end;
  11. /

使用绑定变量:

create or replace procedure p2
    as 
        l_cnt number;
    begin
        for i in 1 .. 10000
        loop
            -- 使用绑定变量
            select count(*) into l_cnt from t where x = i;
        end loop
    end;
/

Buffer Cache的Latch争用

Buffer Cache的机制:

从数据文件中读到内存中,Oracle通过Hash算法将这些数据块打散,通过计算出的hash值指向对应的数据块。

例如,数据文件编号为1,数据块编号为437,则oracle中的hash值为:(1 + 437) mod 4 = 2,内存中便用2这个hash地址指向这个数据块

数据块的信息可以通过基表x$bh查询,x$bh表中有两个字段:nxt_hashprv_hash,这两个字段用于找到这个数据块的下一个数据块头的hash地址和上一个数据块的hash地址。

会话访问数据块时,需要先申请一个bucket latch,然后通过hash bucket得到buffer header,最终找到对应的数据块:

  1. 数据块地址做hash运算
  2. 得到一个bucket latch
  3. 寻找数据块头
  4. 如果可以找到,则读取数据块到cache中。否则从磁盘读取数据块。

如果多个会话都要访问同一个数据块,则它们都要去同一个hash bucket中申请latch,同一个hash bucket中的latch一次只能分给一个会话,就造成了latch争用。这个数据块叫做”热块“。

或者分的 hash bucket数量比较少,很多数据块在同一个hash bucket中,也容易造成latch争用。

热块:

  • 表数据块争用
  • 热块索引数据热块
  • 文件头数据块并发修改

Latch相关视图

v$latch:Oracle对每个latch的统计信息的一个汇总,每一条记录表示一种latch。

select * from v$latch;

主要字段:

  • name:latch名称
  • gets:以willing to wait请求模式latch的请求成功数
  • misses:初次尝试请求不成功次数
  • sleeps:成功获取前sleeping次数
  • immediate_gets:以immediate模式latch请求数
  • immediate_misses:以immediate模式请求失败数

v$latchholder:包含了当前latch持有者的信息。通过视图的pid和sid信息,关联视图v$sessionv$session_wait,可以定位相应持有资源的会话信息。

select * from v$latchholder;

v$latch_children:存储子latch信息的视图,在SGA中有些资源使用多个latch保护,比如 library cache,这些多个latch保护同一个资源,称为子lath。

v$latch_childrenv$latch一样。

Latch优化的思路

Latch导致的性能问题,通常是一个系统层面的问题,所以:

  • AWR报告是一个比较好的入口
  • 通过动态视图v$latch可以分析当前系统的latch资源情况
  • 确定争用最大的latch
  • 分析可能的原因
  • 从应用层面和数据库层面考虑解决途径