文档内容
|
用途 |
|
排错步骤 |
|
什么是"Library cache lock" ? |
|
什么是"Library cache pin" ? |
|
为什么需要这两种不同类型的锁? |
|
减少Library Cache 竞争的一般建议 |
|
如何降低 library cache lock 等待 |
|
如何降低 library cache pin 等待 |
|
什么是 Library cache load lock? |
|
如何减少 Library cache load lock |
|
Library cache pin 与 library load lock 是什么关系 |
|
提示 |
|
已知问题: |
|
参考 |
适用于 : Oracle Database - Personal Edition - 版本 8.1.7.4 和更高版本 Oracle Database - Standard Edition - 版本 8.1.7.4 和更高版本 Oracle Database - Enterprise Edition - 版本 8.1.7.4 和更高版本 本文档所含信息适用于所有平台
用途
下面文档中将提供关于 Library cache lock, Library cache pin 与 Library cache load lock 等待事件的一些简明的知识。
排错步骤
这个事件控制对 library cache 的并发使用。 它获取一个对象句柄(object handle)上的锁,从而:
定位 library cache 中的一个对象同样也需要这个锁。 在解析或编译 SQL 或 PL/SQL 语句期间,我们需要获得被引用的数据库对象(表,视图,过程,函数,包,包体,触发器,索引,聚簇,同义词)的 library cache lock;这个锁在解析与编译结束时会被释放。 cursor(SQL 与 PL/SQL 区),管道(pipes)和其它的瞬时(transient)对象不使用这个锁。 Library cache lock 上的死锁不会被自动检测到,对其的操作是同步进行的。 参数:
这个事件管理 library cache 并发。Pin 住一个对象会使它使用的 heap 被载入到内存中。如果一个使用者想要修改或检查这个对象,它必须在获得 lock 之后再取得一个 pin。Pin 可以用 NULL, SHARE, EXCLUSIVE 模式获得,并且可以看做是一种特殊的 lock。等待"library cache pin"意味着这个 PIN 正被某个其它 session 以不兼容的模式持有。
访问当前被缓存到 library cache 中的数据库对象(表,视图,过程,函数,包,包体,触发器,索引,聚簇,同义词)的时候需要获得 library cache pin; 在 library cache 中,数据库对象被缓存成两部分:句柄(handle)和对象(object); 这个锁(pin)只有当"object"部分被缓存的时候才会被持有。
Library cache pin 上的死锁不会被自动检测到,对其的操作是同步进行的。 注意:在10g以后,"library cache pin"已经被 mutex 取代。 参见: Document 1298015.1 WAITEVENT: "cursor: pin S wait on X" Reference Note
Lock 与 pin 都用于访问在 library cache 中的对象。Lock 管理不同进程间的并发,pin 则管理缓冲区的一致性。为了访问一个对象,进程必须首先锁定(lock)这个对象的句柄(handle),然后它自己 pin 住对象的内存堆。
Lock 与 pin 请求会一直等待直到获得为止,这是一个引起争用的可能的原因,因为它没有 NOWAIT 请求模式。
通过获得一个在对象句柄上的锁,一个进程能防止其它进程访问这个对象,甚至不可以查看它的类型。它还能在维护对象依赖关系的同时不阻止其它进程访问这个对象。获取一个 lock 同样也是在缓存中查找对象的唯一途径。查找并锁住对象是在一个操作中完成的。 如果一个进程想检查或修改一个对象,那么它必须获得一个在这个对象上的 pin (获得了在句柄上的锁之后)。Pin这个动作会将相应对象的信息载入到内存,如果之前没有的话,同时还能确保这些信息保留在内存直到 pin 被释放。 Oracle 在分析/编译 Package/Procedure/Function/View 时需要 Library Cache Lock 和 Library Cache Pin。这是为了确保在分析/编译期间, 没有其它人可以对这些对象的定义进行改变,或者删除、重建这个对象。 当一个 SQL 语句被一个 session 硬解析时,这个 session 需要获得一个 library cache lock 以便阻止其它 session 去访问或修改同一个对象。如果这个事件等待很长时间。这表明可能 shared pool 过小或经常发生对象被 flush 出去的清醒。还有,这表明数据库对象被经常修改。 除了硬解析,如果一个 session 要更改被 SQL 语句引用的对象的定义或对其做任何更改,就必须获得一个 library cache lock 和 library cache pin。需要 Pin 的原因是需要加载数据字典信息到内存中来修改这个对象。
Document 34579.1 WAITEVENT: "library cache pin" Reference Note
下边会介绍一下解决不同竞争的不同的方法。但是,很多时候这些现象都是由于 SQL 语句的版本数造成的。如果您看到了任何跟 library cache 相关的竞争,应该立刻检查 AWR Report 确保没有版本数很高(比如几百)的 SQL 语句。 如果有的话请参见以下文档解决:
Document 296377.1 Troubleshooting: High Version Count Issues
我们首先要确认的是 library cache 的竞争是整个系统层面的还是只发生在某个或某些 SQL 语句上。这个"library cache lock"是被一个特定的 SQL 持有很长的时间吗?或者总是在等待某个特定的对象?还是说这个锁在短时间内被请求的次数很多从而造成的竞争? 如果问题是在整个系统层面发生的,一般来说是由于 shared pool 太小或 SQL 语句不共享造成的。一些解决竞争的方法:
Oracle Performance Diagnostic Guide (OPDG) 针对这个等待事件提供了一些非常有用的诊断场景: Oracle Performance Diagnostic Guide (OPDG) 可以在以下文档中下载:
Document 390374.1 Oracle Performance Diagnostic Guide (OPDG)
如果您发现是某条或某些SQL产生的问题,那么需要检查为什么它持有锁的时间会那么长。 以下文档可以用来找到谁在持有锁以及在哪个对象上:
Document 122793.1 How to Find which Session is Holding a Particular Library Cache Lock
如果"library cache pin"等待的时间很长那么很重要的一点就是判断是只有一两个 process 在等待还是有很多的 process 都在等待。
Document 62143.1 Troubleshooting: Tuning the Shared Pool and Tuning Library Cache Latch Contention
Session 尝试去查找数据对象上的 load lock,以便能加载这个对象。
Load lock 一定是以排它模式获得,以便没有其它进程可以加载同一个对象。如果无法获得 load lock,那么 session 将等待这个事件,直到其变为可用状态。 等待时间: 3秒(PMON 会等待1秒) 参数:
如果一个对象不在内存中,那么我们不能对其申请 library cache lock。 因此,需要将这个对象加载到内存中。 然后,session 尝试找到数据库对象的 load lock,以便它能载入这个对象。 为了阻止多进程同时请求加载同一个对象,其它同样请求的 session 将等待 library cache load lock 因为这个对象正在被加载到内存中。 等待 library cache load lock 是由于对象在内存中是不存在的。 Library cache 中的对象不存在,是由于 shared pool 过小引起的频繁重新装载,或太多的硬解析缘于不共享的 SQL。 避免这种等待的通常建议:
Document:94036.1 Init.ora Parameter "CURSOR_SHARING" Reference Note
Library cache pin 和 load lock 可能出现在对 PL/SQL, views, types 等的编译与重编译期间。这种编译总是显式的(比如应用安装,升级,打补丁)。但是对象重编译也可能发生在对象失效期间。 在处理那些“奇怪“的 library cache pin 和 load lock 等待时,我们需要检查为什么对象失效了。很有可能失效是由于某些操作修改了它所依赖的对象的"LAST_DDL"。通常来说这些操作包括对象维护操作,比如 ALTER, GRANT, REVOKE, replacing views 等等。还有就是收集 optimizer statistics 也会造成 cursor 失效,进而导致 library cache 的重装载。这个现象在 Oracle Server Application Developer's Guide 的object dependency maintenance 部分有描述。 对象失效以后,Oracle 尝试在第一次访问这个对象时去重编译它。有些情况下,如果其它 session 已经 pin 住这个对象,可能就会出现问题。 很显然,在有大量活跃用户与复杂依赖关系(例如,很多交叉依赖的 packages 或package bodies)的情况下更容易出现问题。有些时候对对象的编译会持续数小时从而阻止其它 session 对其的访问。 在 library cache dump, level 10 可以看到: 查找 ALTER ... COMPILE 语句和 lock=X 或 pin=X 的 objects/handles.
Document 1309738.1 High 'library cache lock' Wait Time Due to Invalid Login Attempts Document 10018789.8 Spin in kgllock / DB hang with high library cache lock waits Document 7423411.8 Process may hang waiting for "library cache load lock" with no holder Document 7706138.8 Process may hang waiting for "library cache load lock" with no holder Document 9675816.8 Bug 9675816 - Self deadlock with 'library cache lock' waits
参考 NOTE:7423411.8 - Bug 7423411 - Process may hang waiting for "library cache load lock" with no holder NOTE:10018789.8 - Bug 10018789 - Spin in kgllock / DB hang with high library cache lock waits on ADG NOTE:1298015.1 - WAITEVENT: "cursor: pin S wait on X" Reference Note NOTE:296377.1 - Troubleshooting: High Version Count Issues NOTE:7706138.8 - Bug 7706138 - Process may hang waiting for "library cache load lock" with no holder NOTE:94036.1 - Init.ora Parameter "CURSOR_SHARING" Reference Note NOTE:34579.1 - WAITEVENT: "library cache pin" Reference Note NOTE:122793.1 - How to Find which Session is Holding a Particular Library Cache Lock NOTE:9675816.8 - Bug 9675816 - Self deadlock with 'library cache lock' waits / OERI:17059 NOTE:62143.1 - Troubleshooting: Tuning the Shared Pool and Tuning Library Cache Latch Contention
