Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1104470
  • 博文数量: 276
  • 博客积分: 10077
  • 博客等级: 上将
  • 技术积分: 2513
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-24 20:31
文章分类

全部博文(276)

文章存档

2020年(1)

2015年(5)

2012年(2)

2011年(6)

2010年(7)

2009年(224)

2008年(31)

我的朋友

分类: Oracle

2009-07-07 11:24:40

看了一份文档,摘抄了部份内容.

+++
1)Shared pool 和 library cache latch争用原因一   ――    分析
Oracle的共享池由不同的结构组成。主要包括:数据字典缓存,sql区和库缓存。Shared pool latch主要用来保护共享池的内存结构,当分配或者释放共享池内存时需要先获得该latch。例如,为一个新的sql语句或pl/sql过程、函数、包,触发器等分配空间(硬解析)时,或者为换出、清除某些内存块,以便为新的对象腾出足够的空间时,都需要获取shared pool latch。shared pool和library cache latch争用通常是由于硬分析引起。硬分析需要分配新的游标,或者将已经换出的游标重新执行。硬分析过多说明sql语句没有充分绑定变量。硬分析是代价十分昂贵的操作,在分析期间需要一直持有ibrary cache latch。

当一个新的sql语句到达时,oracle首先在库缓存中检查是否已经有相同的语句存在。如果已经存在,则可以花费较小的代价执行该语句,这就是所谓的软分析。硬分析通常意味着较坏的性能,而软分析过多也不是什么好事。在软分析期间,需要持有library cache latch,并且oracle依然需要对语句进行语法和语义检查,除非该语句已经在会话的游标缓存中。你可以通过设置参数session_cached_cursors来减少library cache latch的持有时间(具体信息请查看oracle metalin,编号#30804.1和 #62143.1)。但是,减少软分析的最佳方法还是优化应用程序。最好是分析一次,执行多次(很像java的宣传口号),而不要分析一次,执行一次。你可以通过v$sqlarea的parse_calls列来查找分析过多的sql语句。

Oracle对此sql将进行几个步骤的处理过程:
1、语法检查(syntax check)

检查此sql的拼写是否语法。

2、语义检查(semantic check)

诸如检查sql语句中的访问对象是否存在及该用户是否具备相应的权限。

3、对sql语句进行解析(prase)

利用内部算法对sql进行解析,生成解析树(parse tree)及执行计划(execution plan)。

4、执行sql,返回结果(execute and return)

其中,软、硬解析就发生在第三个过程里。
Oracle利用内部的hash算法来取得该sql的hash值,然后在library cache里查找是否存在该hash值;

2)Shared pool latch争用原因二    ――   过大的共享池
共享池中可用内存分成不同的内存块(chunk),不同大小范围的块由不同的可用列表(freelist)来管理。在共享池中分配空间时,需要扫描可用列表,扫描期间,需要持有shared pool latch。过大的共享池会使得可用列表过长,从而使得shared pool latch的持有时间变长。在高并发环境中,latch持有时间过长就可能造成latch争用(表现为较高的sleeps和misses值),尤其是大量使用常量sql的系统,对这样的系统,不要一味想着加大共享池,更重要的是想一想你为什么会需要保存这么多不能共享的语句到共享池中。


3)Library cache latch争用原因三   ――    语句版本数过多
对于字符完全一致但是由于引用不同的对象而不能共享的sql语句,oracle使用多个子游标来指向该语句的不同版本。例如,系统中有三个名叫customer的表,但是属于不同的模式。则对于语句select * from customer,不同的模式执行该语句,语句字符上完全一样,其hash值完全一样,但是该语句无法共享,因为它引用的对象不同。所以会生成该语句的不同子版本。当一个sql语句有多个子版本时,oracle需要比较该语句的所有存在的子版本,在此期间需要持有library cache latch,这样可能导致library cache latch争用。解决这种情况也很简单,在系统中,尽量不要使用相同的对象名。


+++
Cache buffers chains latch
当一个数据块读入到sga中时,该块的缓冲区头(buffer header)会放置在一个hash bucket的链表(hash chain)中。该内存结构由一系列cache buffers chains子latch保护(又名hash latch或者cbc latch)

1)Cache buffers chains latch争用原因一 ―― 低效的sql语句
低效的sql语句是导致cache buffers chains latch争用的主要原因。在高并发系统中, latch free时间可能因此非常明显。典型的情况是,应用程序开启多个并发会话执行相同的低效sql,并且访问同样的数据集。

你应该时刻铭记下面三点:
A)每次逻辑读都需要请求一次latch。
B)只有获得某个latch之后才会停止对该latch的不断请求。
C)在某个时刻,只有一个进程可以获得cache buffers chains latch,而该latch可能用于保护很多的数据块,其中的某些块可能正在被其他进程请求(当然,前面也已经提过,oracle9i允许只读性质的cache buffers chains latch共享)。

一般而言,较少的逻辑读意味着较少的latch请求,也就意味着较少的latch争用和更好的系统性能。所以,你应该找出导致cache buffers chains latch争用的低效sql语句,优化这些语句,尽量降低其逻辑读。那些buffers_get/executions比值较大的sql可能就是你需要调整的语句。

2)Cache buffers chains latch争用原因二 ―― 热点块
热点块是导致cache buffers chains latch争用的另外一个主要原因。当多个进程重复访问一个或多个由同一个cache buffers chains latch保护的块时会导致该问题。这通常是应用程序引起的。在这种情况下,增加cache buffers chains latch的个数对热点块导致的争用没有什么作用。因为数据块分布在哪个hash bucket和hash chain上是由块地址(dba:data block address)和hash bucket的个数决定的,和hash latch的个数没有关系。只要块地址和hash bucket数没有改变,这些热点块还是会分布在原来的hash bucket和hash chain上,还是由原来的hash latch保护,那么就还会对这些hash latch产生争用。除非系统中latch数目显著的增加(这样每个latch管理的hash bucket就会很少,甚至一个latch管理一个hash bucket,这样原来的热点块可能就会有其他的几个latch来管理,而不再需要争用原来的那个latch)。

3)Cache buffers chains latch争用原因三 ―― 过长的hash chain
多个数据块可能分配到同一个hash bucket上。这些块组成一个链表(hash chain)。在一个大型系统中,一个hash bucket中可能有上百个数据块。从一个hash chain链表中搜索某个块,需要获得cache buffers chains latch,串行的进行。如果链表太长,使得latch持有时间相应增加,可能导致其他进程请求cache buffers chains latch失败。

阅读(1306) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~