
什么是“library cache lock”
library cache lock控制会话在库缓存中的并发。它获取对象句柄上的锁,这样某一个会话可以阻止其他会话访问同一个对象。
会话可以长时间持有库缓存句柄,如此一来其他任何会话都不能更改被锁定的对象。
library cache lock可以定位对象在库缓存中的位置,在编译SQL或PL/SQL语句过程中,可以在语句涉及到的数据库对象(比如:表,视图,过程,函数,包,包主体,触发器,索引,群集,同义词)上获得library cache lock,并且在语句编译结束后释放。
游标(SQL和PL/SQL执行载体),管道和任何其他临时对象均不使用此锁。库高速缓存锁不是死锁类型,并且该操作是同步的。
什么是"Library cache pin"
该等待事件管理库缓存并发。将对象pin住会导致堆(heap)被加载到内存中。如果用户要修改或检查对象,则必须在锁定后获取一个latch。可以在NULL,SHARE或EXCLUSIVE模式下获取Pin,并且可以将其视为一种特殊的锁(lock)形式。等待“library cache pin”意味着其他某个会话以不兼容的模式持有该latch。
可以从当前已经被缓存在库缓存中的数据库对象(表,视图,过程,函数,包,包主体,触发器,索引,群集,同义词)上获取library cache pin。在库缓存中,数据库对象被缓存为两部分,句柄和对象。仅当对象部分被高速缓存时,library cache pin才能被持有。
跟library cache lock一样,它不是死锁,并且操作是同步的
为什么需要这两种类型的锁
lock和pin访问库高速缓存中的对象。lock管理进程之间的并发性,而pin则管理高速缓存的一致性(coherence)。为了访问对象,进程必须首先锁定对象句柄,然后pin住对象的堆栈(heap)。
在申请被批准之前,锁和闩的请求都将处于等待状态,这是一个可能的导致争用源头,因为没有NOWAIT请求模式。
通过获取对象句柄上的锁(lock),一个进程可以防止其他进程访问该对象,甚至阻止查看它是什么类型。它可以保持对对象的依赖性,而不会阻止其他进程访问该对象。获取锁也是在缓存中定位对象的唯一方法。进程通过单个操作定位并锁定对象。
如果该过程想实际检查或修改该对象,则它必须在该对象本身上获得一个pin(当然在这之前,需要首先获得句柄上的锁)。固定对象会导致有关对象及其堆的信息(如果它们尚未在内存中)被加载到内存中。保证此信息至少在释放pin之前一直保留在内存中。
Oracle需要Library Cache Lock和Library Cache Pin来编译包,存储过程,函数和视图。
这是为了确保在变更对象的时候,比如更改对象定义,删除对象,使用新的定义重建对象时,没有人使用该对象。
当会话对SQL语句进行硬解析时,该会话必须获取库缓存锁,以防止其他会话访问或修改同一对象。如果此事件累积了大量时间,则可能表明共享池太小或正在定期刷新。否则,表明数据库对象定义正在定期更改。
除了硬解析之外,如果会话要更改SQL中指定的对象的定义或进行任何修改,则它还必须获取库缓存锁以及库缓pin。pin是必需的,因为它需要将字典信息加载到内存中才能访问相同的代码。
通常如何减少库缓存争用
这些等待或通常是游标版本出现一般问题的症状。如果看到任何库缓存事件争用,值得立即在AWR报告中检查游标版本。
如何减少库缓存锁
我们首先需要确定库缓存争用是系统范围的还是与特定的sql或一组sql相关。是由一个特定查询或一个特定对象长时间保存“库缓存锁”,还是由许多查询在短时间内请求它,从而引起高竞争。
如果问题似乎是系统范围的,则高库高速缓存锁定通常是共享池大小不足或未共享sql的结果。减少争用的一些方法是:
通过增加共享池的大小来减少重载,因为如果池的大小不足,锁可能会花费很长时间。
通过将cursor_sharing设置为相似或强制来增加共享。
注意这可能会改变执行计划;因此,应彻底测试设置参数。
通过运行批处理作业来收集统计信息或与OLTP分开的任何其他维护作业,以减少无效性。
《Oracle性能诊断指南》(OPDG)为此等待提供了许多非常有用的诊断方案:

如何减少library cache pin
如果“library cache pin”的等待形成了大量的等待时间,那么确定这是一个还是两个等待很长一段时间的会话还是许多进程之间更严重的一般争用问题很重要:
如果存在阻塞情况,其中一个或两个进程被一个进程阻塞,则需要确定该进程不释放pin的原因。
如果普遍等待,则共享池可能需要调整。
什么是Library cache load lock
会话要加载数据库对象,就要试图找到数据库对象的加载锁(load lock),以便它可以加载该对象。
加载锁始终以独占模式获取,因此其他进程无法加载同一对象。如果加载锁繁忙,则会话将等待此事件,直到锁可用。
等待时间:3秒(其中PMON等1秒)
如何减少Library cache load lock
如果对象不在内存中,则无法在其上获取库缓存锁。必须将对象加载到内存中以获取锁。会话试图找到数据库对象的加载锁,以便它可以加载该对象。
为了防止多个进程同时请求加载同一对象,其他请求会话必须等待库高速缓存加载锁,因为该锁正忙于将对象加载到内存中。
Library cache load lock的等待是由于对象在内存中不可用。
库高速缓存中库高速缓存对象的不可用是由于共享池的大小不足导致的,这是由于未共享的sql导致频繁的重新加载或太多的硬解析。
为了避免这种情况,一般建议是:增加共享池(避免高负载);增加会话缓存的游标(以避免游标冲出共享池);将cursor_sharing设置为强制(以减少硬解析),同样,这可能会更改查询的计划和性能。这将更改文字以使用绑定;所以计划可能会改变。
library cache pin 和 library load lock的关系
在PL/SQL,视图等类型的编译或重新编译过程中,可能会发生Library cache pins and load locks。编译总是明确的(应用程序安装,升级,应用补丁程序),但是由于对象失效,对象的重新编译可能是透明的。
在处理与“神秘的”Library cache pins and load locks相关的速度下降时,我们应该寻找数据库对象失效的原因,更改了依赖数据库对象的“ LAST_DDL”属性就是其中一种可能。
当然,也有可能是维护对象的操作-ALTER,GRANT,REVOKE,替换视图等。同样,收集优化器统计信息也会使游标无效,从而导致重新加载库高速缓存。《Oracle Server Application Developer's Guide》将这种行为描述为依赖对象维护。
对象失效后,Oracle会在首次访问该对象时尝试重新编译该对象。当其他会话将对象固定在库缓存中时,可能会出现问题。显然,更活跃的用户和更复杂的依赖关系更容易发生这种情况。在某些情况下,等待对象重新编译甚至可能需要几个小时才能阻止所有尝试访问它的会话。





