shared pool与log buffer学习(五)

shared pool介绍及相关的latch(解析)

Latch:shared pool

Latch:library cache

我们知道Oracle通过SHARED POOL来实现SQL共享,减少硬解析等。而SQL的相关信息,如:SQL语句文本,SQL执行计划等都存放在SHARED POOL的Library Cache部分

其中Library Cache的结构如下图

可以看到其结构和BUFFER CACHE类似,为了能够在Library Cache中快速的查找到对应的SQL,也是通过将不同的SQL语句通过HASH函数HASH后放置到对应Hash Bucket来保存的。 下面看看图中黄色的块(右上角标注着:Object Handle):

 1) 这个块也就是所谓的Library Cache Object Handle,这个Handle描述Library Cache中对象的一些属性,如名称(Name),所属的命名空间(Namespace)、标记(Flags)、指向对

象所处的内存地址的指针(Heap 0)等。对应SQL来说,这个可以算是父游标。 

2) Heap 0用来存放与对象有直接关系的一些信息,比如对象类型、对象相关的表、实际的执行计划等

3)同一个Hash Bucket中的Object Handle相互链接形成一条Chain。 

关于Library Cache更详细的可以查阅Julian Dyke的LibraryCacheInternals.ppt。 Eygle网站上也有一张简洁的图:

下面先看SQL的的整个执行过程来,然后再看看执行过程中是怎么用到SHARED POOL的相关Latch。 

1) 当客户端执行一条SQL,这时候Oracle首先将SQL文本转换成ASCII值,然后根据HASH

函数计算该SQL对应的Hash Value。

 2) 根据得到的Hash Value到Library Cache中查找对应的Bucket,然后查找Bucket里是否存在该SQL? 

(Y)  如果存在,则接下来查找对应的子游标,这个时候将一直持有Library Cache 

Latch,直到找到对应的执行计划。然后释放Latch。(软解析)

(N)  如果不存在,就要去SHARE POOL里面获得可用空间,来生生成对应的Library Cache对象。这个时候就要获得Shared Pool Latch在SHARE POOL的Free List(SHRAE POOL通过Free List管理Free Chunk)查找可用的空间,之后释放Shared Pool Latch。接下来就开始进行硬解析过程,将执行解析后的执行计划等信息记录到Library Cache中,这个整个过程消耗大量的CPU,同时将一直持有Library Cache Latch,一直到硬解析结束。(硬解析) 

 根据获得的执行计划,开始执行SQL,如:到BUFFER CACHE查询数据等。  

 整个逻辑如下如:

当出现Latch竞争严重的时候: 

如果同时出现大量的Share Pool Latch和Library Cache Latch的话,根据上面的逻辑那说明数据库中存在大量的硬解析,这个时候就要查找那些SQL没有绑定变量。 

如果只是出现大量的Library Cache Latch的话,那么可能有两种情况: 

1) 当持有Library Cache Latch查找Bucket对应的Chain时候,发现存在高Version的SQL,这个时候就要扫描这些对应的子游标,整个过程将一直持有Latch,导致其他会话获取不到Latch进行操作。 

2) 大量的并发请求,而且不能实现SQL一次Parse Call多次Execution。 

 

字典缓冲区: dictionary cache,也叫row cache;

用于保存数据字典信息:如表空间相关信息、用户权限、objects信息、histogram信息等。
字典缓冲区在大小无法直接调整,只能通过调整共享池大小来调整字典缓冲区大小。
SYS@ bys3>select pool,name ,bytes/1024/1024 MBfrom v$sgastat where name like 'row cache%';
POOL        NAME                              MB
------------ -------------------------- ----------
shared pool  row cache childlatch      .004959106
shared pool  rowcache                 4.12324524

 

SubPool技术及优势:

从Oracle 9i开始,Shared Pool可以被分割为多个子缓冲池(SubPool)进行管理,以提高并发性,减少竞争。
Shared Pool的每个SubPool可以被看作是一个Mini Shared Pool,拥有自己独立的Free List、内存结构以及LRU List、shared pool latch。同时Oracle提供多个Latch对各个子缓冲池进行管理,从而避免单个Latch的竞争(Shared Pool Reserved Area同样进行分割管理)。从10G开始,每个SubPool由4个SUB PARTITION组成。

SubPool的个数和大小

每四个CPU分配一个SubPool,最多可以有7个。Shared Pool Latch也就从原来的一个增加到现在的7个。
在Oracle9i中,每个SubPool至少为128MB。
10G-10.2.0.3,每个SubPool至少为256MB
10.2.0.3之后,最少为512M。
_kghdsidx_count 隐含参数:ORACLE启动时,优化根据此参数设置SubPool数量。

NAME                             VALUE        ISDEFAULT  ISMOD     ISADJ

------------------------------------------------------------------------

_kghdsidx_count                        1        TRUE      FALSE     FALSE

SubPool缺点:

从ORACL 10G开始,ORACLE进程在某个SubPool中请求内存失败,会到下一个SubPool中请求---过小的SubPool碎片问题可能更严重--ORA-4031出现机率更大。
过多的SubPool还会带来更高的管理协调成本。
比如以下错误就是与SubPool相关:
ORA-04031: unable to allocate 4216 bytes of sharedmemory
("shared pool","unknownobject","sga heap(2,0)","library cache")

 

SQL语句的缓存结果集参考:http://www.itpub.net/thread-846890-1-1.html

log buffer 相关的latch

Latch:redo copy

Latch:redo allocation latch

当一个进程在修改数据时候将会产生Redo,这个Redo首先在PGA中保存。然后进程需要获取Redo Copy Latch(这个Latch的个数由隐含参数_log_simultaneous_copies决定),当获得Redo Copy Latch后,进程接着获取Redo Allocation Latch来分配Redo Log Buffer中的空间,空间分配完成后,释放Redo Allocation Latch。然后进程把PGA里临时存放的Redo信息复制到Redo Log Buffer,复制完成后,释放Redo Copy Latch


你可能感兴趣的:(shared pool与log buffer学习(五))