+++++buffer cache 深度解析(16)


通过前面我们已经知道,每个 set都会有一个名为cachelru chain的latch(也叫做lru latch)来管理 。任何要访问 set的进程都必须先获得cachelru chain latch 。cachelru chain latch争用也是由于低效的扫描过多的内存数据块的SQL语句引起的 。调整这些语句以降低逻辑读和物理读 。只要修改一下上面找引起cachelatch的SQL语句即可找到这样的SQL语句 。
select /**//*+ rule */ s.sql_textfrom x$bh a,dba_extents b,(select * from (select addr from v$latch_childrenwhere name = 'cache buffers lru chain' order by sleeps desc)where rownum<11) c,v$sqltext swhere a.hladdr = c.addrand a.dbarfil = b.relative_fnoand a.dbablk between b.block_id and b.block_id + b.blocksand s.sql_text like '%'||b.segment_name||'%' and b.segment_type='TABLE'order by s.hash_value,s.address,s.piece/
4.3.2busy waits等待
当一个在读取或修改 cache里的内存数据块时,首先必须获得cachelatch,获得以后,到hash chain上遍历直到找到需要的 后 。这时,该必须在该 上以share或模式(具体哪个模式由该的操作决定)获得一个 lock或一个 pin 。一旦 被pin住,就将释放cachelatch,然后可以在该上进行操作了 。如果无法获得 pin,那么该就会等待 busy waits等待事件 。该等待事件不会出现在的私有PGA里 。
busy waits等待事件不能像latch free等待那样可以相对比较容易的进行事后跟踪 。对于该等待事件,提供了v$视图 。v$里的记录都是 busy waits等待事件发生时进行更新的 。也就是说,该视图体现的都是 busy waits等待事件的统计数据 。但这只能给你提供一个大概的 busy waits的分布 。如果要想具体的诊断该等待事件,只能当发生该等待时,到v$里去找原因,从而才能找到解决的办法 。处理 busy wait等待事件时,首先使用下面的SQL语句找到发生等待的数据块类别以及对应的 。
select 'Segment Header' class,a.segment_type, a.segment_name, a.partition_namefromdba_segments a, v$session_wait bwherea.header_file= b.p1anda.header_block = b.p2andb.event= 'buffer busy waits'unionselect 'Freelist Groups' class,a.segment_type, a.segment_name, a.partition_namefromdba_segments a, v$session_wait bwhereb.p2 between a.header_block + 1 and (a.header_block + a.freelist_groups)anda.header_file= b.p1anda.freelist_groups > 1andb.event= 'buffer busy waits'unionselect a.segment_type || ' block' class,a.segment_type, a.segment_name, a.partition_namefromdba_extents a, v$session_wait bwhereb.p2 between a.block_id and a.block_id + a.blocks - 1anda.file_id= b.p1andb.event= 'buffer busy waits'andnot exists (select 1fromdba_segmentswhereheader_file= b.p1andheader_block = b.p2);
然后,根据不同的数据块类型进行相应的处理 。
1) 如果数据块类型为data block,如果版本为10g之前,则可以同时参照p3列的值来共同诊断 。如果p3为130意味着同时有很多在访问同一个data block,而且该data block没有在内存里,而必须从磁盘上获取 。有三种方法可以降低该事件出现的频率:
a、降低并发性 。这个比较难实现 。
b、找出并优化含有这些的SQL语句,以降低物理和逻辑读 。
c、增加和。
如果没有足够的,当同时对同一个表进行时,这就很容易引起 busy waits等待 。如果正在等待 busy waits的正在进行操作,那么需要检查以下那个表有多少了 。当然,由于的不足主要会导致对于 的 busy waits等待 。
如果p3为220意味着有多个同时修改在一个block(该block已经被读入内存了)里的不同的行 。这种情况通常出现在高DML并发性的环境里 。有三种方法可以降低该事件出现的频率:
a、降低并发性 。这个比较难实现 。
b、通过增加减少block里含有的行数 。
c、将该对象移到拥有较小block尺寸的表空间里(9i或以上) 。