Latch
Latch:门闩。
目的:
保证资源的串行访问
- 保护SGA的资源访问
- 保护内存的分配
保证执行的串行化
- 保护关键资源的串行执行
- 防止内存结构损坏
Latch 和 Enqueue 对比:
Latch | Lock(Enqueue) | |
---|---|---|
队列性 | ||
时长 | 很短 | 可能很长 |
层面 | 数据库内存资源层 | 业务应用层 |
目的 | 保证资源的完整性 | 保证业务操作的完整性 |
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争用:
例如:
没有使用变量绑定时:
create or replace procedure p1
as
l_cn number;
begin
for i in 1 .. 10000
loop
-- 拼接sql,不使用变量绑定
execute immediate 'select count(*) from t where x=' || i into l_cnt;
end loop;
end;
/
使用绑定变量:
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_hash
、prv_hash
,这两个字段用于找到这个数据块的下一个数据块头的hash地址和上一个数据块的hash地址。
会话访问数据块时,需要先申请一个bucket latch,然后通过hash bucket得到buffer header,最终找到对应的数据块:
- 数据块地址做hash运算
- 得到一个bucket latch
- 寻找数据块头
- 如果可以找到,则读取数据块到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$session
、v$session_wait
,可以定位相应持有资源的会话信息。
select * from v$latchholder;
v$latch_children
:存储子latch信息的视图,在SGA中有些资源使用多个latch保护,比如 library cache,这些多个latch保护同一个资源,称为子lath。
v$latch_children
和v$latch
一样。
Latch优化的思路
Latch导致的性能问题,通常是一个系统层面的问题,所以:
- AWR报告是一个比较好的入口
- 通过动态视图
v$latch
可以分析当前系统的latch资源情况 - 确定争用最大的latch
- 分析可能的原因
- 从应用层面和数据库层面考虑解决途径