Oracle数据库使用闩锁(latch)来管理SGA内存的分配和释放,Latch是用于保护SGA中共享数据结构的一种串行化锁定机制。Latch的实现是与操作系统相关的,尤其和一个进程是否需要等待一个latch、需要等待多长时间有关。
Latch是一种能够极快地被获取和释放的锁,它通常用于保护描述buffer cache中block的数据结构。比如数据缓存中的某个块要被读取,我们会获得这个块的latch,这个过程叫做pin;另外一个进程恰好要修改这个块,他也要pin这个块,此时他必须等待。当前一个进程释放latch后才能pin住,然后修改。如果多个进程同时请求的话,他们之间将出现竞争,没有一个入队机制,一旦前面进程释放latch,后面的进程就蜂拥而上,没有先来后到的概念,这个和Lock是有本质区别的。这一切都发生的非常快,因为Latch的特点是快而短暂,当然这个只是大致过程。
闩锁统计包括闩锁活动、闩锁休眠中断、锁定未命中源、互斥睡眠摘要、父锁存统计信息、子锁存统计信息
Latch Activity包含了两百多种闩锁。
“Get请求”、“Pct Get Miss”和“Avg Slps/Miss”是愿意等待闩锁Get请求的统计信息
“NoWait Requests”、“Pct NoWait Miss”表示无等待闩锁获取请求
两者的“Pct未命中”应非常接近0.0
照老规矩进行排序后,筛选出重点看一下。
cache buffers chains的意思是当一个数据块读入到sga中时,该块的块头(buffer header)地址存放在一个hash bucket的链表(hash chain)中。该内存结构由一系列cache buffer chains子latch保护(cbc latch)。对buffer cache中的块,要select或者update、insert、delete等,都得先获得cache buffer chains子latch,以保证对chain的排他访问。若在过程中发生争用,就会等待latch:cache buffer chains事件。简单说来就是对热点块的争用或者长时间执行的SQL语句对块的争用。
原因一:低效率的SQL语句(主要体现在逻辑读过高)
cache buffers chains latch很大程度与逻辑读有关,所以要观注v$sql中BUFFER_GETS/EXECUTIONS大的语句。
同时每一个逻辑读需要一个latch get 操作及一个cpu操作,这样的sql也会很耗cpu资源。
原因二:热块(访问过于频繁)
1)下面查询查出Top 5 的争用的latch address。
select *
from ( select CHILD#,ADDR,GETS ,MISSES,SLEEPS
from v$latch_children
where name = 'cache buffers chains' and misses>0 and sleeps>0 order by 5 desc, 1, 2, 3)
where rownum<6;
2)然后利用下面查询找出Hot block。
select e.owner ||'.'|| e.segment_name segment_name, e.extent_id extent#,
x.dbablk - e.block_id + 1 block#, x.tch, x.tim ,l.child#
from v$latch_children l, x$bh x, dba_extents e
where x.hladdr = '&ADDR' and e.file_id = x.file# and x.hladdr = l.addr
and x.dbablk between e.block_id and e.block_id + e.blocks -1
order by x.tch desc ;
3)关注SQL ordered by Gets 和 Segments by Logical Reads。
simulator hash latch,simulator意为模拟。也就是说当Oracle在内存中进行数据块处理时。实际上还会在预先分配的Buffer中进行相关信息记录,如DBA信息,当数据块被老化之后,下次读取时。假设请求的数据在Simulator内存中存在,则觉得继续缓存该数据块是有意义的,通过监控并模拟统计这些操作,并对计算结果加权运算。就能够实现对于内存的调整建议。
在模拟过程中。也是通过Latch来实现的,相关的Latch就有 simulator lru latch 、 simulator hash latch等.
就Buffer Cache而言。假设系统中该类争用严重,则能够考虑关闭db_cache_advice。也就是说simulator hash latch和cache buffers chains是有很大关系的,解决上述问题是首要的。
objet queue header operation未知。
cache buffers lru chain闩锁竞争与解决当用户进程需要读数据到buffer cache时,或cache buffer根据lru算法进行管理时,就不可避免地要扫描lru list获取可用buffer或更改buffer的状态,我们知道,oracle的buffer cache是共享内存,可以为众多并发进程并发访问,所以在搜索的过程中必须获取latch(latch是oracle的一种串行锁机制,用于保护共享内存结构),锁定内存结构,防止并发访问损坏内存中的数据.
cache buffers lru chain闩锁竞争与解决当用户进程需要读数据到buffer cache时,或cache buffer根据lru算法进行管理时,就不可避免地要扫描lru list获取可用buffer或更改buffer的状态,我们知道,oracle的buffer cache是共享内存,可以为众多并发进程并发访问,所以在搜索的过程中必须获取latch(latch是oracle的一种串行锁机制,用于保护共享内存结构),锁定内存结构,防止并发访问损坏内存中的数据.
如果该latch竞争激烈,通常有如下方法可以采用.
适当的增大buffer cache,这样可以减少读数据到buffer cache的机会,减少扫描lru list的竞争可以适当增加lru latch的数量,修改_db_block_lru_latches参数可以实现,但是该参数通常来说是足够的,除非在oracle support的建议下或确知是该参数带来的影响,否则不推荐修改通过多缓冲池技术,可以减少不希望的数据老化和全表扫描等操作对于default池的冲击,从而可以减少竞争。也同样以解决cache buffers chains为主。
checkpoint queue latch问题未知,有的说是bug问题。
row cache objects行缓存对象:行缓存对象闩锁内容通常意味着数据字典中存在争用。这个问题也可能是过度解析依赖公共同义词的SQL语句的症状。增加共享池通常可以解决这个锁存问题。通常在库缓存闩锁问题出现之前就增加共享池。简而言之,减少硬解析,增加共享池。
simulator lru latch未知。
关于Latch Sleep Breakdown如上,不再重复。
关于Latch Miss Sources有些太偏底层,早已超出所学范围了。
本文分享自 python与大数据分析 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!