首页 > Oracle > 与buffer cache相关的等待事件—latch free等待事件!
2014
01-19

与buffer cache相关的等待事件—latch free等待事件!

在前面文章介绍LRU链表和DBWR进程的时候,没有说到latch,这里单独拿出来说一下,本文只说明与buffer cache相关的latch,等待事件latch free中与buffer cache有关的有两种:cache buffers chains latch 和 cache buffers lru chain latch。看过前面介绍LRU链表和DBWR进程以后,这2个latch就比较好理解了。

对于buffer cache中的每个hash chain链表来说,都会由一个cache buffers chains latch的latch来保护对hash chain的并发操作,这种latch还有另一个名字:hash latch或者CBC latch。当然一个数据库中有很多个cache buffers chains latch,每个latch都叫做child cache buffers chains latch,每个child cache buffers chains latch会管理多个hash chain。cache buffers chains latch的数量由一个隐藏参数:_db_block_hash_latches来决定,而该隐藏参数的缺省值时候buffer cache中所含有的内存数据块的多少来决定的,满足如下公式:

·少于2052个时,_db_block_hash_latches = power(2,trunc(log(2,内存块数量- 4) – 1))

·多于131075个时,_db_block_hash_latches = power(2,trunc(log(2, db_block_buffers – 4) – 6))

·位于2052与131075 buffers之间,_db_block_hash_latches = 1024

可以通过如下sql来查询当前系统的cache buffers chains latch的数量:

既然知道了cache buffers chains latch 的数量,那么我们就可以算出每个latch管理多少个hash chain了,计算公式:hash chain的数量除以latch的数量:

通过如上查询所得:

      每个latch管理hash chain的数量=65536/2048=32.

当数据库在搜索和扫描hash chain的过程中,需要先获得cache buffers chains latch,并一直持有,直到找到所有的数据块才会释放该latch,当一个进程一直在扫描一个hash chain的时候,此时如果另一个进程也想扫描同一个hash chain,那这个进程就必须等待类型为cache buffers chains latch的latch free等待事件。

一般出现cache buffers chains latch,很多情况下是由sql导致的,如果sql语句需要访问过多的内存数据块,那么这个latch就会持有比较长的时间。这时就需要找出逻辑读比较大的sql语句,看是否能进行调整,在v$sqlarea视图中,buffer_gets/executions比值比较大的sql语句,如果和其他sql语句出现比较大的反差,那就需要考虑这条sql语句是否可以优化了,我这里整理了一下用来查找比较一偶针对性的,查找这种引起较为严重的cache buffers chains latch的sql语句:

引起cache buffers chains latch事件的还有另一个原因,那就是热点数据块的问题,指的就是多个session重复访问一个或者多个被同一个child cache buffers chains latch保护的内存数据块,可以通过如下sql来查找是否存在热点块:如果p1raw的值有很多,就说明session在等待同一个latch地址,系统存在热点块:

然后我们就可以根据p1raw的值去找到所对应的内存数据块以及对应的表的名称了:如下xxxxxxxx就是如上所查询出来的p1raw值,代入替换即可

我们可以通过将热点块分散到多个数据块当中,这样原来的热点块就变成了多个数据块,被hash到同一个latch的几率就降低了,如果一个热点块属于表,则可以先将表导出,然后增加表的pctfree,再导入数据,如果热点块属于索引,则可以设定较高的pctfree,然后重建索引,这样可能会增加索引的高度。

通过前面我们已经知道,每个working set都会有一个名为cache buffers lru chain的latch(也叫做lru latch)来管理。任何要访问working set的进程都必须先获得cache buffers lru chain latch。cache buffers lru chain latch争用也是由于低效的扫描过多的内存数据块的SQL语句引起的。调整这些语句以降低逻辑读和物理读。只要修改一下上面找引起cache buffers chains latch的SQL语句即可找到这样的SQL语句。

最后编辑:
作者:Jerry
一个积极向上的小青年,热衷于分享--Focus on DB,BI,ETL