【恩墨学院】??深入解析library cache lock与library cache pin



深入了解oracle数据库内部原理,才能在遭遇故障或者性能问题时顺藤摸瓜,找到根源。


可能有很多朋友从来就没有搞清楚过到底什么是library cache lock和library cache pin,它们到底是enqueue还是latch?它们的作用是什么?


本文我会根据官方文档的一些介绍,谈一谈我的理解和感悟。如果内容中有不尽严谨的地方,请大家多包涵,同时也欢迎大家留言讨论,


我们通常说的library cache lock和library cache pin是enqueue,不是latch,它们是两种DDL lock。但需要我们注意的是,在11gR1之前,Oracle中又存在名为library cache lock和library cache pin的latch。


是不是感觉很混乱?没关系,我们一点一点往下看。


作为enqueue,library cache lock和library cache pin的作用是什么?


library cache lock and library cache pin都是从来对ibrary cache中的对象进行访问时使用到的,Library cache lock 管理多进程间的并发, library cache pin 则用于维护Cache的一致性。为了访问library cache中的对象,进程首先需要锁住library cache中的对象的句柄,然后pin住对象数据堆栈, library cache lock 和 library cache pin的请求发出后都需要等待,因为在没有Nowait选项的环境下,一般都会发生资源争夺。


通过获取library cache中的对象句柄上的 library cache lock锁,就能够防止其他进程对同一对象的访问,当然也可以在不阻止其他进程访问对象的情况下保持对象的依赖性。获取library cache lock 是唯一的能够定位cache中的对象的方法。在每一次单独的数据库操作中,进程会对一个对象进行定位和锁定。


如果一个对象要检测或者修改一个对象的话,则在获取到library cache lock 之后还需要pin住对象数据堆栈本身,在pin住一个对象数据的过程中,如果对应数据并不存在于内存中的话,会被加载到内存当中。这些数据会在内存中保留至pin的过程结束。locks和pin的相关信息在外部被分别存储在X$KGLLK和X$KGLPN中。


作为enqueue,library cache lock和library cache pin有哪几种lock mode?


01


Library cache lock有三种锁定的模式,分别是share、exclusive和null。如果一个进程只是想读取一个对象的话,一般需要获取share library cache lock锁,比如说,只是在编译的过程中引用一个对象的话。如果进程是想创建或者修改一个对象的话,则需要获取独占模式的library cache lock。例如,如果是想把一个对象从数据库中删除的话。


没有library cache locks是一种特殊的情况,比如说在执行一个子游标,存储过程,函数,包,或者类型体的时候需要的对象,这些对象的信息会在会话中保留很长的时间,可以通过这些信息检测对象是否失效。


一个 null类型的library cache lock,可能随时会被破坏。这个机制也被用来检测会话中的可执行对象是否失效。当一个null类型的 library cache lock 被破坏之后,对象就会变成失效状态,也就意味着持有null类型的 library cache lock 的对象需要被重新编译。


在执行一条SQL语句的解析过程中,会申请null类型的library cache lock ,并且这个library cache lock 在SQL语句存在于shared pool的整个期间,它都会存在于shared SQL Area。


一个null类型的library cache lock 不能保护DDL的操作,如果需要执行有冲突的DDL语句的话,此时Null 类型的library cache lock 会被破坏掉。这就是所谓的“可破坏的解析锁”。


一般来说,但有其他类型的library cache lock 锁要锁定一个对象的话,该对象上现有的null类型的library cache lock 就会被破坏。


02


Library cache pin有两种lock mode,分别是share和exclusive。 当一个进程所pin的对象数据堆栈不在内存中时,进程会决定这些数据是否需要被加载到PGA或者SGA当中,如果一个数据希望被修改的话,那么必须以独占的模式被pin住。


然而,在这之前,当一个进程想要pin住一个对象的时候,必须首先以Share的模式pin住。对对象做相关错误检查和安全检查,之后,在有必要的情况下,比如说需要修改,就会改为独占的模式pin住,如果只是需要对数据进行读操作的话,则对象肯定不会以独占的模式被pin住。这是因为如果对象被从独占模式取消pin 的话,所有的临时对象比如游标,都将会失效,变成null类型的锁定。这可能会导致一些不必要的重新编译,比如依赖的包,存储过程或者函数等。



作为latch,library cache lock和library cache pin的作用是什么?


这是一个很纠结的问题,既然已经有了作为enqueue的library cache lock和library cache pin,为什么在11gR1以前,Oracle里还有同名latch,而且明显这些同名latch是在被使用:


OCM 培训课程


从结果里我们可以看到,对于10.2.0.5而言,Oracle存在7种跟library cache相关的latch,除了library cache hash chains latch之外,其他的跟library cache相关的latch,Oracle都有使用。


0?wx_fmt=gif


那么library cache lock latch、library cache pin latch以及大家最耳熟能详的library cache latch等等,这些latch是做什么用的呢?

也许我们可以从下面的一段文字中找到答案:


library cache latches顺序地访问library cache中的对象,访问library Cache中的对象地都是通过library cache locks完成的,因为锁住一个对象是个原子操作,而library cache latch在library cache lock 的请求之前和释放之后都会需要。


对于大部分的操作来说,都会使用到Library Cache latches,因此也就有可能会导致争用。


如果一个对象不存在于内存中,这时候就不能在该对象上请求library cache lock。为了防止对个进程同时访问同一个对象,并希望将该对象加载到内存中这种情况的发生,在数据真正被加载到内存之前,还有另外一个latch是需要用到的。这就是library cache load lock latch。


library cache load lock latch会在Library Cache Load lock分配到释放的整个期间都会持有。加载对象的过程一般是通过 library cache load lock 锁定对象而不是library cache load lock latch,因为后者需要花的时间可能比较长。


有几点值得我们关注


1


Oracle使用上述library cache latches(包括library cache latch、library cache lock latch、library cache pin latch、library cache pin allocation latch、library cache load lock latch)的目的是控制并发访问library cache object所需要的相关的enqueue或者是为了控制并发访问library cache中的相关的内存结构。比如用相关的library cache lock latch控制并发获得library cache lock。


这里我猜测Oracle用library cache lock latch控制并发获得library cache lock,用library cache pin latch控制并发获得library cache pin,用library cache load lock latch控制并发获得library cache load lock,用library cache latch去控制并发访问library cache object handle中的某些结构,如library cache object handle中的flag中的special status flag (special status flags are protected by the library cache latch. Examples of these flags indicate that: The object is valid; The object is authorized; The object has compilation errors)。


2


Library cache load lock是另外一种enqueue。会话尝试找到数据库对象上的library cache load lock,然后才能将数据加载到内存中。library cache load lock一直被以Exclusive的模式持有,如果library cache load lock被占用的话,会话就会处于等待状态,直到library cache load lock被释放。


好了,现在我们来验证一下,还是上述10.2.0.5的环境,我将上述sql(select name,level#,gets,misses,sleeps,immediate_gets,immediate_misses from v$latch where name like ‘library%’)马上再执行一遍,这是软解析,必然要获得library cache lock,不需要获得library cache load lock,所以对应的latch应该表现为library cache lock latch的gets增加,library cache load lock latch的gets不变:


OCM 培训课程


从结果里我们可以看到,library cache lock latch的gets从13548247递增到了13548760,library cache pin latch的gets从4207462递增到了4207656,但library cache load lock latch的gets还是保持24848不变。


现在我们来让library cache load lock latch的gets发生变化,这是非常容易的事情,我们只需要执行一个需要硬解析的sql就可以了:


OCM 培训课程


由于我们执行了一个需要硬解析的sql,导致Oracle需要获得library cache load lock以便load相关信息到这个sql的子cursor的heap 6中,而要获得library cache load lock,必须先持有library cache load lock latch。从上述结果中我们可以看到,此时library cache load lock latch的gets已经发生了变化,从24848递增到了24856。


接下来我们再来看一看上述library cache latches的子latch情况:


SQL> show parameter cpu_count

NAME          TYPE         VALUE

———————————— ———–

cpu_count    integer        2


这里cpu的个数为2,显然上述library cache latches的子latch应该为3:


OCM 培训课程


注意,结果里并没有library cache load lock latch,说明library cache load lock latch没有children,它是一个solitary类型的latch。


从10.2.0.2开始,Oracle将_kks_use_mutex_pin的默认值改成了true,这意味着从10.2.0.2开始,Oracle里将再不会有针对cursor的library cache pin等待,取而代之的是mutex等待,具体表现为cursor: pin *等待,如cursor: pin S wait on X。


这里需要我们了解的是:

1、从10.2.0.2开始,Oracle只是用mutex替代了针对cursor的library cache pin,这并不代表从10.2.0.2开始Oracle里就没有library cache pin等待了。比如这个例子里的library cache pin等待就发生在10.2.0.4中:http://www.dbsnake.net/solve-library-cache-pin.html


2、Mutex和latch是互相独立,没有任何关系的:一个进程可以同时持有一个mutex 和latch,在僵死进程中,latches会比mutex更早清除,跟latch不一样的是,mutex没有通用的互斥锁检测。也不存在锁的层级结构。


从11gR1开始,Oracle用mutex替换了library cache latches,并引了一个新的等待事件:library cache: mutex *,我们来看一下这个知识点:


OCM 培训课程


从结果里我们可以看到,在11.2.0.1里,各种library cache latches都没有了,只剩下了library cache load lock latch,而且Oracle还没有使用这个latch,因为gets是0。


恩墨学院隶属于云和恩墨(北京)信息技术有限公司,致力于提供专业高水准的oracle数据库与大数据培训服务,挖掘培养大数据与数据库人才。恩墨学院提供包括个人实战技能培训、个人认证培训、企业内训在内的全方位大数据和数据库技术培训。ACE级别超强师资,配备专业实验室,沉浸式学习与训练,专业实验室、配备专业助教指导训练。能迅速融入专家圈子,业内资源丰富,迅速积累职场人脉。oracle数据库课程包括:Oracle DBA实战班、Oracle OCM考试、Oracle OCP考试等。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28530558/viewspace-2150558/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/28530558/viewspace-2150558/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值