41 Oracle深度学习笔记 shared pool底层知识大集合

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

41.Oracle深度学习笔记——shared_pool底层知识大集合

1     shared pool

Oracle引入Shared Pool就是为了帮助我们实现代码的共享和重用。

Shared Pool主要由两部分组成,一部分是库缓存(Library Cahce),另一部分是数据字典缓存(Data Dictionary Cache)。Library Cache主要用于存储SQL语句、SQL语句相关的解析树、执行计划、PL/SQL程序块(包括匿名程序块、存储过程、包、函数等)以及它们转换后能够被Oracle执行的代码等,这部分信息可以通过v$librarycache视图查询;至于DataDictionary Cache主要用于存放数据字典信息,包括表、视图等对象的结构信息,用户以及对象权限信息,这部分信息相对稳定,在Shared Pool中通过字典缓存单独存放,字典缓存的内容是按行(Row)存储的(其他数据通常按Buffer存储),所以又被称为Row Cache,其信息可以通过V$ROWCACHE查询。

Shared Pool各个部分协同工作以及与Buffer Cache的配合。如下图1

 

从Oracle Database 11g开始,在Shared Pool中划出了另外一块内存用于存储SQL查询的结果集,称为ResultCache Memory。以前Shared Pool的主要功能是共享SQL,减少硬解析,从而?高性能,但是SQL共享之后,执行查询同样可能消耗大量的时间和资源,现在Oracle尝试将查询的结果集缓存起来,如果同一SQL或PL/SQL函数多次执行(特别是包含复杂运算的SQL),那么缓存的查询结果可以直接返回给用户,不需要真正去执行运算,这样就又为性能带来了极大的提升。

    结果集缓存(Result Cache)是Oracle Database 11g新引入的功能,除了可以在服务器端缓存结果集(ServerResultCache)之外,还可以在客户端缓存结果集(Client Result Cache)。

服务器端的ResultCache Memory由两部分组成:

(1) SQL Query Result Cache:存储SQL查询的结果集。

(2) PL/SQL Function Result Cache:用于存储PL/SQL函数的结果集。

Oracle通过一个新引入初始化参数result_cache_max_size 来控制该Cache的大小。如果result_cache_max_size=0 则表示禁用该特性。参数result_cache_max_result 则控制单个缓存结果可以占总的ServerResult Cache大小的百分比。

初始地,数据库启动以后,Shared Pool多数是连续内存块。但是当空间分配使用以后,内存块开始被分割,碎片开始出现,Bucket列表开始变长。

Oracle请求Shared Pool空间时,首先进入相应的Bucket进行查找。如果找不到,则转向下一个非空的Bucket,获取第一个Chunk。分割这个Chunk,剩余部分会进入相应的Bucket,进一步增加碎片

最终的结果是,由于不停分割,每个Bucket上的内存块会越来越多,越来越碎小。通常Bucket 0的问题会最为显著,在这个测试数据库上,Bucket 0上的碎片已经达到9030个,而shared_pool_size设置仅为150MB。

通常如果每个Bucket上的Chunk多于2000个,就被认为是Shared Pool碎片过多。Shared Pool的碎片过多,是Shared Pool产生性能问题的主要原因。

碎片过多会导致搜索Free Lists的时间过长,而我们知道,Free Lists的管理和搜索都需要获得和持有一个非常重要的Latch,就 是Shared Pool Latch。Latch是Oracle数据库内部提供的一种低级锁,通过串行机制保护共享内存不被并发更新/修改所损坏。Latch的持有通常都非常短暂(通常微秒级),但是对于一个繁忙的数据库,这个串行机制往往会成为极大的性能瓶颈。

如果Free Lists链表过长,搜索这个Free Lists的时间就会变长,从而可能导致SharedPool Latch被长时间持有,在一个繁忙的系统中,这会引起严重的Shared PoolLatch的竞争。在Oracle 9i之前,这个重要的Shared PoolLatch只有一个,所以长时间持有将会导致严重的性能问题。

  

1.1     如何管理

Sharedpool和PGA都是由一个Oracle的内存管理器来管理,我们称之为KGH heap manager。Heap Manager不是一个进程,而是一串代码。Heap Manager主要目的就是满足server 进程请求memory 的时候分配内存或者释放内存。Heap Manager在管理PGA的时候,Heap Manager需要和操作系统来打交道来分配或者回收内存。但是呢,在shared pool中,内存是预先分配的,Heap Manager管理所有的空闲内存。当某个进程需要分配shared pool的内存的时候,Heap Manager就满足该请求,Heap Manager也和其他ORACLE模块一起工作来回收shared pool的空闲内存。Library cache Manager 可以看做是Heap Manager的客户端,因为library cache manager是根据Heap Manager来分配内存从而存放library cache objects。Library cache Manager控制所有的library cache object,包括package/procedure, cursor, trigger等等。

1.2     Hash Table and Hash Bucket

Librarycache是由一个hash table组成,这个hash table又由hash bucket组成的数组构成,每个hash bucket又是由一些相互指向的library cache handle所组成,library cache object handle就指向具体的library cache object以及一些引用列表。

图2:

1.3     Library Cache handle

我们对Library cache中所有对象的访问是通过利用library cache handle来实现的,也就是说我们想要访问library cache object,我们必须先找到library cache handle。Library cache handle指向library cache object,它包含了library object的名字,命名空间,时间戳,引用列表,lock对象以及pin对象的列表信息等等。Library cache handle也被library cache用来记录哪个用户在这个这个handle上有lock,或者是哪个用户正在等待获得这个lock。那么这里我们也知道了library cache lock是发生在handle上的。

    当一个进程请求library cache object,library cache manager就会应用一个hash 算法,从而得到一个hash值,根据相应的hash值到相应的hash bucket中去寻找。这里的hash算法原理与buffer cache中快速定位block的原理是一样的。如果library cache object在内存中,那么这个library cache handle就会被找到。有时候,当shared pool不够大,library cache handle会保留在内存中,然而library cache heap由于内存不足被age out,这个时候我们请求的object heap就会被重载。最坏的情况下,library cache handle在内存中没有找到,这个时候就必须分配一个新的library cache handle,同时object heap也会被加载到内存中。

1.4     LibraryCache Object

LibraryCache Object是由一些独立的heap所组成,前面说了Library cache handle指向Library cache Object,其实handle是指向第一个heap,这个heap 我们就称之为heap 0。Heap 0记录了指向其他heap的指针信息。

如下图3

  

2     Library Cache Lock概念

图4   


Library cacheHandle 里保存了lock 和 pin的信息。而且在Librarycache handle和child cursor上都有lock和pin。它们称为library cache lock和library cache pin。

     Librarycachelock/pin是用来控制对librarycache object的并发访问的。Lock管理并发,pin管理一致性,lock是针对于librarycache handle,而pin是针对于heap。

       当我们想要访问某个librarycache object,我们首先要获得这个指向这个object的handle的lock,获得这个lock之后我们就需要pin住指向这个object的heap。

 

       当我们对包,存储过程,函数,视图进行编译的时候,Oracle就会在这些对象的handle上面首先获得一个librarycache lock,然后再在这些对象的heap上获得pin,这样就能保证在编译的时候其它进程不会来更改这些对象的定义,或者将对象删除。

 

       当一个session对SQL语句进行硬解析的时候,这个session就必须获得librarycache lock,这样其他session就不能够访问或者更改这个SQL所引用的对象。如果这个等待事件花了很长时间,通常表明共享池太小(由于共享池太小,需要搜索free的chunk,或者将某些可以被移出的object page out,这样要花很长时间),当然了,也有可能另外的session正在对object进行修改(比如split分区),而当前session需要引用那个table,那么这种情况下我们必须等另外的session进行完毕。

 

Library Cache lock有3中模式:

       (1)Share(S):     当读取一个library cache object的时候获得

       (2)Exclusive(X): 当创建/修改一个library cache object的时候获得

       (3)Null(N):     用来确保对象依赖性

        比如一个进程想要编译某个视图,那么就会获得一个共享锁,如果我们要create/drop/alter某个对象,那么就会获得exclusive lock。Null锁非常特殊,我们在任何可以执行的对象(cursor,function)上面都拥有NULL锁,我们可以随时打破这个NULL锁,当这个NULL锁被打破了,就表示这个对象被更改了,需要从新编译。

       NULL锁主要的目的就是标记某个对象是否有效。比如一个SQL语句在解析的时候获得了NULL锁,如果这个SQL的对象一直在共享池中,那么这个NULL锁就会一直存在下去,当这个SQL语句所引用的表被修改之后,这个NULL锁就被打破了,因为修改这个SQL语句的时候会获得Exclusive锁,由于NULL锁被打破了,下次执行这个SQL的时候就需要重新编译。

 

Library Cache pin有2种模式:

       (1)Share(S):     读取object heap

       (2)Exclusive(X):修改object heap

        当某个session想要读取object heap,就需要获得一个共享模式的pin,当某个session想要修改object heap,就需要获得排他的pin。当然了在获得pin之前必须获得lock。

        在Oracle10gR2中,library cache pin被library cache mutex所取代。

     Library cachelatch用来控制对library cache object的并发访问。前面已经提到,我们要访问library cacheobject之前必须获得librarycachelock, lock不是一个原子操作(原子操作就是在操作程中不会被打破的操作,很明显这里的lock可以被打破), Oracle为了保护这个lock,引入了library cache latch机制,也就是说在获得librarycachelock之前,需要先获得library cache latch,当获得library cache lock之后就释放librarycache latch。

 

       如果某个librarycache object没有在内存中,那么这个lock就不能被获取,这个时候需要获得一个librarycache load lock latch,然后再获取一个librarycache load lock,当load lock获得之后就释放library cache load lock latch。

        librarycache latch受隐含参数_KGL_LATCH_COUNT的控制,默认值为大于等于系统中CPU个数的最小素数,但是Oracle对其有一个硬性限制,该参数不能大于67。

       注意:我们去查询_kgl_latch_count有时候显示为0,这是一个bug。

 Oracle利用下面算法来确定library cache object handle是由哪个子latch来保护的:

       latch#= mod(bucket#,#latches)

 

       也就是说用哪个子latch去保护某个handle是根据那个handle所在的bucket号,以及总共有多少个子latch来进行hash运算得到的。

3     Library cache lock/pin

Library cache lock/pin是用来控制对library cache object的并发访问的。Lock管理并发,pin管理一致性,lock是针对于library cache handle,而pin是针对于heap。

当我们想要访问某个library cache object,我们首先要获得这个指向这个object的handle的lock,获得这个lock之后我们就需要pin住指向这个object的heap。

当我们对包,存储过程,函数,视图进行编译的时候,Oracle就会在这些对象的handle上面首先获得一个library cache lock,然后再在这些对象的heap上获得pin,这样就能保证在编译的时候其它进程不会来更改这些对象的定义,或者将对象删除。

当一个session对SQL语句进行硬解析的时候,这个session就必须获得library cache lock,这样其他session就不能够访问或者更改这个SQL所引用的对象。如果这个等待事件花了很长时间,通常表明共享池太小(由于共享池太小,需要搜索free的chunk,或者将某些可以被移出的object page out,这样要花很长时间),当然了,也有可能另外的session正在对object进行修改(比如split 分区),而当前session需要引用那个table,那么这种情况下我们必须等另外的session进行完毕。

Library Cache lock有3中模式:

l  Share(S):     当读取一个library cache object的时候获得

l  Exclusive(X): 当创建/修改一个librarycache object的时候获得

l  Null(N):     用来确保对象依赖性

 

比如一个进程想要编译某个视图,那么就会获得一个共享锁,如果我们要create/drop/alter某个对象,那么就会获得exclusive lock。Null锁非常特殊,我们在任何可以执行的对象(cursor,function)上面都拥有NULL锁,我们可以随时打破这个NULL锁,当这个NULL锁被打破了,就表示这个对象被更改了,需要从新编译。NULL锁主要的目的就是标记某个对象是否有效。比如一个SQL语句在解析的时候获得了NULL 锁,如果这个SQL的对象一直在共享池中,那么这个NULL锁就会一直存在下去,当这个SQL语句所引用的表被修改之后,这个NULL锁就被打破了,因为修改这个SQL语句的时候会获得Exclusive 锁,

由于NULL锁被打破了,下次执行这个SQL的时候就需要从新编译。

Library Cache pin有2种模式:

l  Share(S):     读取object heap

l  Exclusive(X):修改object heap

 

Library Cache pin没有什么好说的,当某个session想要读取object heap,就需要获得一个共享模式的pin,当某个session想要修改object heap,就需要获得排他的pin。当然了在获得pin之前必须获得lock。

 

下面就是一个在Oracle10g RAC环境中的Library cache lock的案例

这个RAC环境有2个节点

4     Library cache Latch

Library cache latch用来控制对library cacheobject的并发访问。前面已经提到,我们要访问library cache object之前必须获得library cache lock, lock不是一个原子操作(原子操作就是在操作程中不会被打破的操作,很明显这里的lock可以被打破),Oracle为了保护这个lock,引入了library cache latch机制,也就是说在获得library cache lock之前,需要先获得librarycache latch,当获得library cache lock之后就释放library cache latch。

如果某个library cache object没有在内存中,那么这个lock就不能被获取,这个时候需要获得一个librarycache load lock latch,然后再获取一个library cache load lock,当load lock获得之后就释放librarycache load lock latch。

Library cache latch竞争还有可能是具有高version_count的SQL导致的,某个session去执行一个具有很高version_count的SQL需要pin住child cursor,而由于child cursor过多,在未pin住child cursor之前不会释放librarycache latch,这样当其他session想运行该SQL的时候就会发生library cache latch争用,那么遇到这种情况请检查cursor_sharing参数的设置,另外请查询是否遇到bug,或者由于系统中不同schema出现大量同名的表名,这样请更改设计。

      在第二个案例中,由于shared pool设置过小还导致了shared pool latch处于top wait event 中的第二名。Sharedpool latch是用来干嘛的呢?Shared pool latch用来保护共享池的结构,在分配,释放共享池空间的时候就会获得该latch,那么在这个案例中,由于共享池太小,在对一个新的SQL进行硬解析的时候需要老化某些对象,为新对象腾出空间,那么这个释放空间的过程就需要获得shared pool latch。当然了,在进行硬解析,也需要获得一个shared pool latch因为硬解析需要申请分配sharedpool空间,而分配空间的时候就需要获得该latch。

5     MOS说明

MOS 的文档【122793.1】里说导致librarycache lock通常有2种原因:

 (1)A DML operation that is hangingbecause the table which isaccessed is currently undergoing changes (ALTERTABLE). This may take quite along time depending on the size of the table andthe type of the modification(e.g. ALTER TABLE x MODIFY (col1 CHAR(200) on atable with thousands of records)

In this case,V$LOCK will show that the session doing the 'ALTERTABLE' with an exclusive DMLenqueue lock on the table object (LMODE=6, TYPE=TMwhere ID1 is the OBJECT_IDof the table). The waiting session however does notshow up in V$LOCK yet so inan environment with a lot of concurrent sessions theV$LOCK information will beinsufficient to track down the culprit blocking youroperation.

 (2)The compilation of package willhang on Library Cache Lock andLibrary Cache Pin if any users are executing aprocedure/function defined in thesame package.

6     library cache概述

一个实例中的library cache包括了不同类型对象的描述,如:游标,索引,表,视图,过程,等等.这些对象不能在他们被使用的时候改变,他们在被使用的时候会被一种librarylocks and pins的机制锁住.一个会话中,需要使用一个对象,会在该对象上先得到一个librarylock(null, shared or exclusive模式的)这是为了,防止其他会话也访问这个对象(例如:重编译一个包或视图的时候,会加上exclusive类型的锁)或更改对象的定义.

总的来说,librarycache pin和librarycache lock都是用于sharepool的并发控制的。pin和lock都可以看作是一种锁。locks/pins会在SQL语句执行期间一直保持,在结束的时候才释放。Lock锁的等级比pin要高。

 每个想使用或修改已经locked/pin的对象的SQL语句,将会等待事件'librarycache pin'或'librarycache lock'直到超时.超时,通常发生在5分钟后,然后SQL语句会出现ORA-4021的错误.如果发现死锁,则会出现ORA-4020错误

7      library cachepin和library cache lock成因

lock主要有三种模式:Null,share(2),Exclusive(3).
在读取访问对象时,通常需要获取Null(空)模式以及share(共享)模式的锁定.
在修改对象时,需要获得Exclusive(排他)锁定.

同样pin有三种模式,Null,shared(2)和exclusive(3).
只读模式时获得共享pin,修改模式获得排他pin.

模式为shared(2)的pin会阻塞任何exclusive(3)的pin请求。

模式为shared(3)的pin也会阻塞任何exclusive(2)的pin请求。

不同的操作会对对象请求不同的lock/pin
1、所有的DDL都会对被处理的对象请求排他类型的lock和pin
2、对视图,过程,包的编译都要请求排他的lock和pin

当要对一个过程或者函数进行编译时,需要在librarycache中pin该对象。在pin该对象以前,需要获得该对象

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow
这里写图片描述
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值