oracle等待事件5——库高速缓存上的等待事件 下

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 原文转自:http://www.eygle.com/archives/2004/10/shared_pool-5.html Oracle使用两种数据结构来进行shared pool的并发控制:lock 和 pin,Lock比pin具有更高的级别.

原文转自:http://www.eygle.com/archives/2004/10/shared_pool-5.html

Oracle使用两种数据结构来进行shared pool的并发控制:lock 和 pin,Lock比pin具有更高的级别.

Lock在handle上获得,在pin一个对象之前,必须首先获得该handle的锁定,锁定主要有三种模式: Null,share,Exclusive.
在读取访问对象时,通常需要获取Null(空)模式以及share(共享)模式的锁定.
在修改对象时,需要获得Exclusive(排他)锁定.

在锁定了Library Cache对象以后,一个进程在访问之前必须pin该对象.
同样pin有三种模式,Null,shared和exclusive.
只读模式时获得共享pin,修改模式获得排他pin.

通常我们访问、执行过程、Package时获得的都是共享pin,如果排他pin被持有,那么数据库此时就要产生等待.
在很多statspack的report中,我们可能看到以下等待事件:


Top 5 Wait Events
~~~~~~~~~~~~~~~~~                                             Wait     % Total
Event                                               Waits  Time (cs)   Wt Time
-------------------------------------------- ------------ ------------ -------
library cache lock                                 75,884    1,409,500   48.44
latch free                                     34,297,906    1,205,636   41.43
library cache pin                                     563      142,491    4.90
db file scattered read                            146,283       75,871    2.61
enqueue                                             2,211       13,003     .45
          -------------------------------------------------------------       


                      

这里的library cache lock和library cache pin都是我们关心的.接下来我们就研究一下这几个等待事件.

(一).LIBRARY CACHE PIN等待事件

Oracle文档上这样介绍这个等待事件:
"library cache pin" 是用来管理library cache的并发访问的,pin一个object会引起相应的heap被载入内存中(如果此前没有被加载),Pins可以在三个模式下获得:NULL,SHARE,EXCLUSIVE,可以认为pin是一种特定形式的锁.
当Library Cache Pin等待事件出现时,通常说明该Pin被其他用户已非兼容模式持有.

"library cache pin"的等待时间为3秒钟,其中有1秒钟用于PMON后台进程,即在取得pin之前最多等待3秒钟,否则就超时.
"library cache pin"的参数如下,有用的主要是P1和P2:
                P1 - KGL Handle address.
                P2 - Pin address
                P3 - Encoded Mode & Namespace

"LIBRARY CACHE PIN"通常是发生在编译或重新编译PL/SQL,VIEW,TYPES等object时.编译通常都是显性的,如安装应用程序,升级,安装补丁程序等,另外,"ALTER","GRANT","REVOKE"等操作也会使object变得无效,可以通过object的"LAST_DDL"观察这些变化. 当object变得无效时,Oracle 会在第一次访问此object时试图去重新编译它,如果此时其他session已经把此object pin到library cache中,就会出现问题,特别时当有大量的活动session并且存在较复杂的dependence时.在某种情况下,重新编译object可能会花几个小时时间,从而阻塞其它试图去访问此object的进程.

下面让我们通过一个例子来模拟及解释这个等待:

1.创建测试用存储过程

 

 
[oracle@jumper udump]$ sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.3.0 - Production on Mon Sep 6 14:16:57 2004

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Connected to an idle instance.

SQL> startup
ORACLE instance started.

Total System Global Area   47256168 bytes
Fixed Size                   451176 bytes
Variable Size              29360128 bytes
Database Buffers           16777216 bytes
Redo Buffers                 667648 bytes
Database mounted.
Database opened.
SQL> create or replace PROCEDURE pining
  2  IS
  3  BEGIN
  4          NULL;
  5  END;
  6  /

Procedure created.

SQL> 
SQL> create or replace procedure calling
  2  is
  3  begin
  4          pining;
  5          dbms_lock.sleep(3000);
  6  end;
  7  /

Procedure created.

SQL>        
       

2.模拟
首先执行calling过程,在calling过程中调用pining过程,此时pining过程上获得共享Pin,如果此时尝试对pining进行授权或重新编译,将产生Library Cache Pin等待
直到calling执行完毕.

session 1:

 

[oracle@jumper oracle]$ sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.3.0 - Production on Mon Sep 6 16:13:43 2004

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

Connected to:
Oracle9i Enterprise Edition Release 9.2.0.3.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.3.0 - Production

SQL> exec calling

 

此时calling开始执行

session 2:


[oracle@jumper udump]$ sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.3.0 - Production on Mon Sep 6 16:14:16 2004

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

Connected to:
Oracle9i Enterprise Edition Release 9.2.0.3.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.3.0 - Production

SQL> grant execute on pining to eygle;

 

此时session 2挂起

ok,我们开始我们的研究:

从v$session_wait入手,我们可以得到哪些session正在经历library cache pin的等待

 

 
SQL> select sid,seq#,event,p1,p1raw,p2,p2raw,p3,p3raw,state
    from v$session_wait where event like 'library%';

 SID       SEQ# EVENT                       P1 P1RAW            P2 P2RAW            P3  WAIT_TIME SECONDS_IN_WAIT STATE
---- ---------- ------------------- ---------- -------- ---------- -------- ---------- ---------- --------------- -------
   8        268 library cache pin   1389785868 52D6730C 1387439312 52B2A4D0        301          0               2 WAITING
等待3秒就超时,seq#会发生变化
SQL> 
 SID       SEQ# EVENT                       P1 P1RAW            P2 P2RAW            P3  WAIT_TIME SECONDS_IN_WAIT STATE
---- ---------- ------------------- ---------- -------- ---------- -------- ---------- ---------- --------------- -------
   8        269 library cache pin   1389785868 52D6730C 1387439312 52B2A4D0        301          0               2 WAITING
SQL> 
 SID       SEQ# EVENT                       P1 P1RAW            P2 P2RAW            P3  WAIT_TIME SECONDS_IN_WAIT STATE
---- ---------- ------------------- ---------- -------- ---------- -------- ---------- ---------- --------------- --------
   8        270 library cache pin   1389785868 52D6730C 1387439312 52B2A4D0        301          0               0 WAITING
      
      

在这个输出中,P1 列是Library Cache Handle Address,Pn字段是10进制表示,PnRaw字段是16进制表示

我们看到,library cache pin等待的对象的handle地址为:52D6730C
通过这个地址,我们查询X$KGLOB视图就可以得到对象的具体信息:

关于这个视图的详细解释参考:http://blog.csdn.net/changyanmanman/article/details/7611758   第3个

Note: X$KGLOB--[K]ernel [G]eneric [L]ibrary Cache Manager [OB]ject

 

 
SQL> col KGLNAOWN for a10
SQL> col KGLNAOBJ for a20
SQL> select ADDR,KGLHDADR,KGLHDPAR,KGLNAOWN,KGLNAOBJ,KGLNAHSH,KGLHDOBJ
from X$KGLOB where KGLHDADR ='52D6730C'
/


ADDR     KGLHDADR KGLHDPAR KGLNAOWN   KGLNAOBJ       KGLNAHSH KGLHDOBJ
-------- -------- -------- ---------- ------------- ---------- --------
404F9FF0 52D6730C 52D6730C SYS        PINING        2300250318 52D65BA4      
      

这里KGLNAHSH代表该对象的Hash Value

KGLNAOWN ——当前处于library cache pin的owner

KGLNAOBJ——当前处于library cache pin的对象

由此我们知道,在PINING对象上正经历library cache pin的等待.


然后我们引入另外一个内部视图X$KGLPN:

关于这个视图的详细解释参考:http://blog.csdn.net/changyanmanman/article/details/7611758      第2个

Note:X$KGLPN--[K]ernel [G]eneric [L]ibrary Cache Manager object [P]i[N]s

 

 
select a.sid,a.username,a.program,b.addr,b.KGLPNADR,b.KGLPNUSE,b.KGLPNSES,b.KGLPNHDL,b.kGLPNLCK, b.KGLPNMOD, b.KGLPNREQ 
from v$session a,x$kglpn b 
where a.saddr=b.kglpnuse and b.kglpnhdl = '52D6730C' and b.KGLPNMOD<>0
/

  SID  USERNAME    PROGRAM        ADDR     KGLPNADR KGLPNUSE KGLPNSES KGLPNHDL KGLPNLCK  KGLPNMOD KGLPNREQ
----- ----------- -------------- -------- -------- -------- -------- -------- -------- ---------- ----------
   13  SYS        sqlplus@jumper. 404FA034 52B2A518 51E2013C 51E2013C 52D6730C 52B294C8     2                   0
                  hurray.com.cn (TNS V1-V3)   
           

通过联合v$session,可以获得当前持有该handle的用户信息.
对于我们的测试sid=13的用户正持有该handle

那么这个用户正在等什么呢?

 

 
SQL> select * from v$session_wait where sid=13;
 SID   SEQ#   EVENT    P1TEXT    P1     P1RAW  P2TEXT  P2  P2RAW P3TEXT  P3 P3RAW  WAIT_TIME SECONDS_IN_WAIT STATE
----- ----- -------- ---------- ------- ----- ------ ---- ----- ------ --- --------         --------        ------------------------ -------
 13    25   PL/SQL  duration  120000   0001D4C0        0    00           0    00                 0                1200               WAITING
            lock timer

Ok,这个用户正在等待一次PL/SQL lock timer计时.

得到了sid,我们就可以通过v$session.SQL_HASH_VALUE,v$session.SQL_ADDRESS等字段关联v$sqltext,v$sqlarea等视图获得当前session正在执行的操作.

 

 
SQL> select sql_text from v$sqlarea where v$sqlarea.hash_value='3045375777';

SQL_TEXT
--------------------------------------------------------------------------------
BEGIN calling; END;
      
      

这里我们得到这个用户正在执行calling这个存储过程,接下来的工作就应该去检查calling在作什么了.

我们这个calling作的工作是dbms_lock.sleep(3000)
也就是PL/SQL lock timer正在等待的原因

至此就找到了Library Cache Pin的原因.

简化一下以上查询:

1.获得Library Cache Pin等待的对象

 

 
SELECT addr, kglhdadr, kglhdpar, kglnaown, kglnaobj, kglnahsh, kglhdobj
  FROM x$kglob
 WHERE kglhdadr IN (SELECT p1raw
                      FROM v$session_wait
                     WHERE event LIKE 'library%')
/

ADDR     KGLHDADR KGLHDPAR KGLNAOWN   KGLNAOBJ               KGLNAHSH KGLHDOBJ
-------- -------- -------- ---------- -------------------- ---------- --------
404F2178 52D6730C 52D6730C SYS        PINING               2300250318 52D65BA4
      

2.获得持有等待对象的session信息

 

 
SELECT a.SID, a.username, a.program, b.addr, b.kglpnadr, b.kglpnuse,
       b.kglpnses, b.kglpnhdl, b.kglpnlck, b.kglpnmod, b.kglpnreq
  FROM v$session a, x$kglpn b
 WHERE a.saddr = b.kglpnuse
   AND b.kglpnmod <> 0
   AND b.kglpnhdl IN (SELECT p1raw
                        FROM v$session_wait
                       WHERE event LIKE 'library%')
/
SQL> 

       SID USERNAME   PROGRAM                                          ADDR     KGLPNADR KGLPNUSE 
KGLPNSES KGLPNHDL KGLPNLCK   KGLPNMOD   KGLPNREQ
---------- ---------- ------------------------------------------------ -------- -------- -------- 
-------- -------- -------- ---------- ----------
        13 SYS        sqlplus@jumper.hurray.com.cn (TNS V1-V3)         404F6CA4 52B2A518 51E2013C 
51E2013C 52D6730C 52B294C8          2          0
      

3.获得持有对象用户执行的代码

 

 
SELECT sql_text
  FROM v$sqlarea
 WHERE (v$sqlarea.address, v$sqlarea.hash_value) IN (
          SELECT sql_address, sql_hash_value
            FROM v$session
           WHERE SID IN (
                    SELECT SID
                      FROM v$session a, x$kglpn b
                     WHERE a.saddr = b.kglpnuse
                       AND b.kglpnmod <> 0
                       AND b.kglpnhdl IN (SELECT p1raw
                                            FROM v$session_wait
                                           WHERE event LIKE 'library%')))
/

SQL_TEXT
--------------------------------------------------------------------------------
BEGIN calling; END;
      

在grant之前和之后我们可以转储一下shared pool的内容观察比较一下:

 

SQL> ALTER SESSION SET EVENTS 'immediate trace name LIBRARY_CACHE level 32';

Session altered.

在grant之前:

从前面的查询获得pining的Handle是52D6730C:

 

 
******************************************************
BUCKET 67790:
  LIBRARY OBJECT HANDLE: handle=52d6730c
  name=SYS.PINING 
  hash=891b08ce timestamp=09-06-2004 16:43:51
  namespace=TABL/PRCD/TYPE flags=KGHP/TIM/SML/[02000000]
  kkkk-dddd-llll=0000-0011-0011 lock=N pin=S latch#=1
--在Object上存在共享pin
--在handle上存在Null模式锁定,此模式允许其他用户继续以Null/shared模式锁定该对象
  lwt=0x52d67324[0x52d67324,0x52d67324] ltm=0x52d6732c[0x52d6732c,0x52d6732c]
  pwt=0x52d6733c[0x52b2a4e8,0x52b2a4e8] ptm=0x52d67394[0x52d67394,0x52d67394]
  ref=0x52d67314[0x52d67314, 0x52d67314] lnd=0x52d673a0[0x52d67040,0x52d6afcc]
    LIBRARY OBJECT: object=52d65ba4
    type=PRCD flags=EXS/LOC[0005] pflags=NST [01] status=VALD load=0
    DATA BLOCKS:
    data#     heap  pointer status pins change    alloc(K)  size(K)
    ----- -------- -------- ------ ---- ------     -------- --------
        0 52d65dac 52d65c90 I/P/A     0 NONE       0.30     0.55
        4 52d65c40 52d67c08 I/P/A     1 NONE       0.44     0.48
      

在发出grant命令后:

 

 
******************************************************
BUCKET 67790:
  LIBRARY OBJECT HANDLE: handle=52d6730c
  name=SYS.PINING 
  hash=891b08ce timestamp=09-06-2004 16:43:51
  namespace=TABL/PRCD/TYPE flags=KGHP/TIM/SML/[02000000]
  kkkk-dddd-llll=0000-0011-0011 lock=X pin=S latch#=1
--由于calling执行未完成,在object上仍让保持共享pin
--由于grant会导致重新编译该对象,所以在handle上的排他锁已经被持有
--进一步的需要获得object上的Exclusive pin,由于shared pin被calling持有,所以library cache pin等待出现.
  lwt=0x52d67324[0x52d67324,0x52d67324] ltm=0x52d6732c[0x52d6732c,0x52d6732c]
  pwt=0x52d6733c[0x52b2a4e8,0x52b2a4e8] ptm=0x52d67394[0x52d67394,0x52d67394]
  ref=0x52d67314[0x52d67314, 0x52d67314] lnd=0x52d673a0[0x52d67040,0x52d6afcc]
    LIBRARY OBJECT: object=52d65ba4
    type=PRCD flags=EXS/LOC[0005] pflags=NST [01] status=VALD load=0
    DATA BLOCKS:
    data#     heap  pointer status pins change    alloc(K)  size(K)
    ----- -------- -------- ------ ---- ------     -------- --------
        0 52d65dac 52d65c90 I/P/A     0 NONE       0.30     0.55
        4 52d65c40 52d67c08 I/P/A     1 NONE       0.44     0.48      

实际上recompile过程包含以下步骤,我们看一下lock和pin是如何交替发挥作用的:
1.存储过程的library cache object以排他模式被锁定,这个锁定是在handle上获得的exclusive锁定可以防止其他用户执行同样的操作,同时防止其他用户创建新的引用此过程的对象.
2.以shared模式pin该对象,以执行安全和错误检查.
3.共享pin被释放,重新以排他模式pin该对象,执行重编译.
4.使所有依赖该过程的对象失效
5.释放exclusive lock和exclusive pin


(二).LIBRARY CACHE LOCK等待事件

如果此时我们再发出一条grant或compile的命令,那么library cache lock等待事件将会出现:

session 3:

 

 
[oracle@jumper oracle]$ sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.3.0 - Production on Tue Sep 7 17:05:25 2004

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.3.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.3.0 - Production

SQL> alter procedure pining compile;

      

此进程挂起,我们查询v$session_wait视图可以获得以下信息:

 

 
SQL> select * from v$session_wait;

 SID SEQ# EVENT               P1TEXT                  P1 P1RAW    P2TEXT               P2 P2RAW    
P3TEXT              P3 P3RAW     WAIT_TIME SECONDS STATE  
---- ---- ------------------- --------------- ---------- -------- ------------ ---------- -------- 
---------------- -------------- ---------- ------  ---
  11  143 library cache pin   handle address  1390239716 52DD5FE4 pin address  1387617456 52B55CB0 
100*mode+namespace 301 0000012D          0       6 WAITING
  13   18 library cache lock  handle address  1390239716 52DD5FE4 lock address 1387433984 52B29000 
100*mode+namespace 301 0000012D          0       3 WAITING
   8  415 PL/SQL lock timer   duration        120000     0001D4C0                       0 00       
                    0 00                0      63 WAITING
....

13 rows selected
     

由于handle上的lock已经被session 2以exclusive模式持有,所以session 3产生了等待.

我们可以看到,在生产数据库中权限的授予、对象的重新编译都可能会导致library cache pin等待的出现.所以应该尽量避免在高峰期进行以上操作.

另外我们测试的案例本身就说明:如果Package或过程中存在复杂的、交互的依赖以来关系极易导致library cache pin的出现.所以在应用开发的过程中,我们也应该注意这方面的内容.

 
 
 

library cache lock和library cache pin到底是什么


可能有很多朋友从来就没有搞清楚过到底什么是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。

 

是不是感觉很混乱?没关系,我们一点一点往下看。很抱歉,我这里引用了大量英文,因为我觉得如果翻译出来就失去了原先的味道。

 

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

Both library cache lock and library cache pin are provided to access objects in the library cache.Library cache lock manages concurrency between processes, whereas library cache pin manages cache coherence. In order to access an object in library cache, a process must first lock the library cache object handle, and then pin the object data heap itself. Requests for both library cache lock and library cache pin will wait until granted. This is a possible source of contention, because there is no NOWAIT request mode.

By acquiring a library cache lock on the library cache object handle, a process can prevent other processes from accessing the object, or even finding out what type it is. It can even maintain a dependency on an object without preventing other processes from accessing the object. Acquiring a library cache lock is also the only way to locate an object in cache—a process locates and locks an object in a single operation.

If the process wants to actually examine or modify the object, then it must acquire a library cache pin on the object data heap itself (after acquiring a library cache lock on the library cache object handle).Pinning the object causes information about the object and its data heaps to be loaded into memory if they were not already there. This information is guaranteed to remain in memory at least until the pin is released. Locks and pins are externalized in X$KGLLK and X$KGLPN, respectively.

 

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

a)         Library cache lock有三种lock mode,分别是shareexclusivenullA process acquires a share library cache lock if it intends only to read the object. For example, it wants to reference the object during compilation. A process acquires an exclusive library cache lock if it intends to create or modify the object. For example, it wants to drop the object from the database. Null library cache locks are a special case. They are acquired on objects that are to be executed like child cursor, procedure, function, package, or type body. You can use them to maintain an interest on an object for a long period of time (session persistency), and to detect if the object becomes invalid. You can break null library cache lock at any time. This is used as a mechanism to notify a session that an executable object is no longer valid. If a null library cache lock is broken, and thus the object is invalidated, then it is an indication to the user who was holding the null library cache lock that the object needs to be recompiled. A null library cache lock is acquired during the parse phase of SQL statement execution and is held as long as the shared SQL area for that statement remains in the shared pool. A null library cache lock does not prevent any DDL operation, and can be broken to allow conflicting DDL operations, hence the term “breakable parse lock.” A null library cache lock on an object is broken when there is an exclusive library cache pin on the object.

b)         Library cache pin有两种lock mode,分别是shareexclusive When a process pins an object data heap that is not in memory, the process can determine whether the data heap is to be loaded in the PGA or SGA. An object must be pinned in Exclusive mode if it is to be modified. However, the process first will always pin the object in Share mode, examine it for errors and security checks, and then, if necessary, (such as needing modification) pin it in Exclusive mode. An object is never pinned in Exclusive mode if only read access is required.This is because all dependent transient objects (cursors) are invalidated (null locks broken) when an object is unpinned from Exclusive mode. The effect would be unnecessary recompilation and reparsing of all dependent packages, procedures, and functions.

 

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

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

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.5.0

Connected as ipra

 

SQL> select name,level#,gets,misses,sleeps,immediate_gets,immediate_misses from v$latch where name like ‘library%’;

 

NAME                                                   LEVEL#       GETS     MISSES     SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES

————————————————– ———- ———- ———- ———- ————– —————-

library cache                                               5    9221760       1608        800           2596           76766

library cache lock                                          6   13548247        582          6              0                0

library cache lock allocation                               3     208273          0          0              0                0

library cache pin                                           6    4207462        193          0              2                0

library cache hash chains                                   9          0          0          0              0                0

library cache pin allocation                                3      57276          0          0              0                0

library cache load lock                                     5      24848          0          0              1                0

 

7 rows selected

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

 

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

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

The library cache latches serialize access to the objects in the library cache. Access to library cache objects always occurs through library cache locks. Because locking an object is not an atomic instruction, a library cache latch is acquired before the library cache lock request and is released after it. For most operations, the library cache latches are used, and therefore they can become a point of contention.

If an object is not in memory, then a library cache lock cannot be acquired on it. In order to prevent multiple processes to request the load of the same object simultaneously, another latch must be acquired before the load request. This is the library cache load lock latch. The library cache load lock latch is taken and held until a library cache load lock is allocated, then the latch is released. Loading of the object is performed under the library cache load lock and not under the library cache load lock latch as it may take quite a long time.

 

这里提到了几点值得我们关注:

a)        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)。

b)         Library cache load lock是另外一种enqueue。The session tries to find the library cache load lock for the database object so that it can load the object. The library cache load lock is always obtained in Exclusive mode, so that no other process can load the same object. If the library cache load lock is busy the session will wait on this event until the lock becomes available.

 

好了,现在我们来验证一下,还是上述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不变:

SQL> select name,level#,gets,misses,sleeps,immediate_gets,immediate_misses from v$latch where name like ‘library%’;

 

NAME                                                   LEVEL#       GETS     MISSES     SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES

————————————————– ———- ———- ———- ———- ————– —————-

library cache                                               5    9222166       1608        800           2596           76766

library cache lock                                          6   13548760        582          6              0                0

library cache lock allocation                               3     208287          0          0              0                0

library cache pin                                           6    4207656        193          0              2                0

library cache hash chains                                   9          0          0          0              0                0

library cache pin allocation                                3      57278          0          0              0                0

library cache load lock                                     5      24848          0          0              1                0

 

7 rows selected

从结果里我们可以看到,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就可以了:

SQL> select * from scott.emp_temp;

 

EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO  ISINSPECT

—– ———- ——— —– ———– ——— ——— —— ———-

 

SQL> select name,level#,gets,misses,sleeps,immediate_gets,immediate_misses from v$latch where name like ‘library%’;

 

NAME                                                   LEVEL#       GETS     MISSES     SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES

————————————————– ———- ———- ———- ———- ————– —————-

library cache                                               5    9223549       1608        800           2596           76766

library cache lock                                          6   13550296        582          6              0                0

library cache lock allocation                               3     208348          0          0              0                0

library cache pin                                           6    4208118        193          0              2                0

library cache hash chains                                   9          0          0          0              0                0

library cache pin allocation                                3      57294          0          0              0                0

library cache load lock                                     5      24856          0          0              1                0

 

7 rows selected

由于我们执行了一个需要硬解析的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:

SQL> select name,level#,gets,misses,sleeps,immediate_gets,immediate_misses from v$latch_children where name like ‘library%’;

 

NAME                                                   LEVEL#       GETS     MISSES     SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES

————————————————– ———- ———- ———- ———- ————– —————-

library cache                                               5    3274551       1301         94            187                0

library cache                                               5    2218356        116         80            933                0

library cache                                               5    3731320        191        626           1476           76766

library cache lock                                          6    5339737        362          3              0                0

library cache lock                                          6    6223353        194          3              0                0

library cache lock                                          6    1987799         26          0              0                0

library cache pin                                           6    1484918        184          0              0                0

library cache pin                                           6     891695          3          0              2                0

library cache pin                                           6    1831837          6          0              0                0

library cache pin allocation                                3      23177          0          0              0                0

library cache pin allocation                                3       8272          0          0              0                0

library cache pin allocation                                3      25849          0          0              0                0

library cache lock allocation                               3      75900          0          0              0                0

library cache lock allocation                               3      28229          0          0              0                0

library cache lock allocation                               3     104237          0          0              0                0

library cache hash chains                                   9          0          0          0              0                0

library cache hash chains                                   9          0          0          0              0                0

library cache hash chains                                   9          0          0          0              0                0

 

18 rows selected

注意,结果里并没有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。

这里需要我们了解的是:

a)         从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

 

b)         Mutex和latch是互相独立,没有任何关系的:Latches and mutexes are independent mechanisms i.e. a process can hold a latch and a mutex at the same time. In the case of process death, latches are always cleaned up before mutexes. There is no generic mutex deadlock detection (unlike latches). There is no mutex/latch hierarchy.

 

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

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0

Connected as nbs

 

SQL>  select name,level#,gets,misses,sleeps,immediate_gets,immediate_misses from v$latch where name like ‘library%’;

 

NAME                                                                 LEVEL#       GETS     MISSES     SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES

—————————————————————- ———- ———- ———- ———- ————– —————-

library cache load lock                                                   5          0          0          0             0                0

 

SQL> select name,level#,gets,misses,sleeps,immediate_gets,immediate_misses from v$latch_children where name like ‘library%’;

 

NAME                                                                 LEVEL#       GETS     MISSES     SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES

—————————————————————- ———- ———- ———- ———- ————– —————-

 

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


3 Comments on “library cache lock和library cache pin到底是什么”

  1. wxjzqymtl

    有两个问题想请教博主
    1.在dsi405中提到shared cursor包括sql和pl/sql对象,我理解的pl/sql对象不就是package,function这些吗,而dsi中也指出还有一类存储对象procedure和function等。我就疑惑了这些package,function到底是属于存储对象还是过渡对象
    2.文章中提到当加载database object时会用到library cache load lock,以及在举例中引用了硬解析来说明会加载相关信息到child cursor的heap 6中也会用到library cache load lock。我想问的是此lock的使用时机是只在load数据库对象时才使用还是load所有对象(包括游标对象)时都是用

    • 1、Shared cursor中包括的pl/sql对象是指匿名pl/sql对象
      2、library cache load lock用于防止并发的load同样内容到同一个地方,不是仅用于shared cursor

  2. wxjzqymtl

    谢谢博主的回复

    library cache lock和library cache pin到底是什么(续)

    Posted: December 16, 2011 | Author:  | Filed under: Oracle | Tags:  | 2Comments »

    这篇文章是“library cache lock和library cache pin到底是什么”的姊妹篇,在这篇文章里,我们通过测试得到了如下结论:

    1、  针对cursor的library cache lock的lock mode确实是null,无论该cursor所对应的sql是硬解析还是软解析;

    2、  MOS上说Oracle说从10.2.0.2以后,会用mutex取代针对cursor的library cache pin,但我的测试结果是在10.2.0.5中,虽然在sql的软解析时确实已经不存在library cache pin,但如果是硬解析,依然存在library cache pin

    3、  sql的软解析时,library cache pin的lock mode始终是S;

    4、  sql的硬解析时,library cache pin的lock mode一般是X,但在10.2.0.1中,即使是硬解析,也存在lock mode为S的library cache pin。

     

    这里测试所采用的方法就是event 10049,这个事件在10gR2以后,专门被用来trace library cache lock和library cache pin。但好多朋友不太会用这个事件,我这里以一个实例的方式介绍了如何用10049事件来trace单个sql的library cache lock和library cache pin。

     

    我们先从10.2.0.1开始说起:

    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0

    Connected as SYS

     

    10.2.0.1中_kks_use_mutex_pin的值为false,表示Oracle不会用mutex取代针对cursor的library cache pin:

    SQL> select name,value,description from sys.all_parameters where name like ‘_kks%’;

     

    NAME                           VALUE      DESCRIPTION

    —————————— ———- ————————————————–

    _kks_use_mutex_pin             FALSE      Turning on this will make KKS use mutex for cursor pins.

     

    SQL> select * from scott.emp;

     

    EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO

    —– ———- ——— —– ———– ——— ——— ——

     7981 CUIHUA                7981                                

     7369 SMITH      CLERK      7902 1980-12-17     800.00               20

     7499 ALLEN      SALESMAN   7698 1981-2-20     1600.00    300.00     30

     ……省略显示部分内容

     7800 JAME3      CLERK      7698 1981-12-3      950.00               30

     

    13 rows selected

     

    SQL> select hash_value,sql_text from v$sqlarea where sql_text like ‘select * from scott.emp%’;

     

    HASH_VALUE SQL_TEXT

    ———- ——————————————————————————–

      52404428 select * from scott.emp

     

    SQL> select to_char(52404428,’XXXXXXXX’) from dual;

     

    TO_CHAR(52404428,’XXXXXXXX’)

    —————————-

      31FA0CC

     

    现在我们要来trace针对上述sql的library cache pin和library cache lock,方法我之前已经说了,就是用event 10049,用10049的难点在于如何确定level。

    确定10049针对单个sql的level值的算法如下:

    首先,10049的level可能会有如下一些值:

    #define KGLTRCLCK  0×0010                       /* trace lock operations */

    #define KGLTRCPIN  0×0020                       /* trace pin operations  */

    #define KGLTRCOBF  0×0040                       /* trace object freeing  */

    #define KGLTRCINV  0×0080                       /* trace invalidations   */

    #define KGLDMPSTK  0×0100                  /* DUMP CALL STACK WITH TRACE */

    #define KGLDMPOBJ  0×0200                  /* DUMP KGL OBJECT WITH TRACE */

    #define KGLDMPENQ  0×0400                 /* DUMP KGL ENQUEUE WITH TRACE */

    #define KGLTRCHSH  0×2000                          /* DUMP BY HASH VALUE */

     

    其次,我们是要针对单个sql,所以需要用到这个sql的hash value,以便将10049和这个sql联系起来,即我们一定要用到KGLTRCHSH,也就是0×2000;

    另外我们是要trace library cache lock和library cache pin,所以我们一定要用到KGLTRCLCK和KGLTRCPIN,即0×0010和0×0020;

    最后就是我们需要把这个sql的hash value的16进制的后两个byte拿出来,作为10049的level的前缀。

     

    从上面结果中我们可以看到,select * from scott.emp的hash value的16进制的后两个byte是0xA0CC。另外KGLTRCHSH | KGLTRCLCK | KGLTRCPIN = 0×2000 | 0×0010 | 0×0020 = 0×2030。按照上述算法,select * from scott.emp的10049的最终level值就是0xa0cc2030,也就是2697732144:

    SQL> select to_number(‘a0cc2030′,’XXXXXXXXXXXX’) from dual;

     

    TO_NUMBER(‘A0CC2030′,’XXXXXXXX

    ——————————

                        2697732144

     

    现在我们设置好10049后再执行一遍上述sql,以观察10.2.0.1下sql的软解析时library cache pin和library cache lock:

    SQL> oradebug setmypid

    已处理的语句

    SQL> oradebug event 10049 trace name context forever,level 2697732144

    已处理的语句

     

    SQL> select * from scott.emp;

     

    EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO

    —– ———- ——— —– ———– ——— ——— ——

     7981 CUIHUA                7981                                

     7369 SMITH      CLERK      7902 1980-12-17     800.00               20

     7499 ALLEN      SALESMAN   7698 1981-2-20     1600.00    300.00     30

     ……省略显示部分内容

     7800 JAME3      CLERK      7698 1981-12-3      950.00               30

     

    13 rows selected

     

    SQL> oradebug tracefile_name

    d:\oracle\admin\cuihua\udump\cuihua_ora_5808.trc

     

    相应的trace文件(d:\oracle\admin\cuihua\udump\cuihua_ora_5808.trc)的内容为:

    *** 2011-06-01 11:59:35.500

    KGLTRCLCK kglget     hd = 0x33938118  KGL Lock addr = 0x3174A99C mode = N

    KGLTRCLCK kglget     hd = 0x33938034  KGL Lock addr = 0x31716F50 mode = N

    KGLTRCPIN kglpin     hd = 0×33938034  KGL Pin  addr = 0x31718A28 mode = S

    KGLTRCPIN kglpndl    hd = 0×33938034  KGL Pin  addr = 0x31718A28 mode = S

    KGLTRCLCK kgllkdl    hd = 0×33938034  KGL Lock addr = 0x31716F50 mode = N

    KGLTRCLCK kgllkdl    hd = 0×33938118  KGL Lock addr = 0x3174A99C mode = N

     

    hd = 0×33938118所对应的library cache object的name就是select * from scott.emp:

    SQL> select sql_text from v$sqlarea where address=’33938118′;

     

    SQL_TEXT

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

    select * from scott.emp

     

    hd = 0×33938034就是hd = 0×33938118的子cursor:

    SQL> select kglhdadr,kglhdpar,kglnaobj from x$kglob where kglhdadr=’33938034′;

     

    KGLHDADR KGLHDPAR KGLNAOBJ

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

    33938034 33938118 select * from scott.emp

     

    很明显,从上述trace文件中我们可以得出如下结论:

    1、10.2.0.1中,sql软解析时,针对cursor的library cache lock的lock mode确实是null;

    2、10.2.0.1中,sql软解析时,针对cursor的library cache pin的lock mode确实是S;

     

    现在我们来观察10.2.0.1下sql的硬解析时library cache pin和library cache lock:

    SQL> shutdown immediate

    数据库已经关闭。

    已经卸载数据库。

    ORACLE 例程已经关闭。

    SQL> startup

    ORACLE 例程已经启动。

     

    Total System Global Area  608174080 bytes

    Fixed Size                  1250404 bytes

    Variable Size             318770076 bytes

    Database Buffers          281018368 bytes

    Redo Buffers                7135232 bytes

    数据库装载完毕。

    数据库已经打开。

     

    SQL> select hash_value,sql_text from v$sqlarea where sql_text like ‘select * from scott.emp%’;

     

    HASH_VALUE SQL_TEXT

    ———- ——————————————————————————–

     

    SQL> oradebug setmypid

    已处理的语句

    SQL> oradebug event 10049 trace name context forever,level 2697732144

    已处理的语句

    SQL> select * from scott.emp;

     

    EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO

    —– ———- ——— —– ———– ——— ——— ——

     7981 CUIHUA                7981                                

     7369 SMITH      CLERK      7902 1980-12-17     800.00               20

     7499 ALLEN      SALESMAN   7698 1981-2-20     1600.00    300.00     30

     ……省略显示部分内容

     7800 JAME3      CLERK      7698 1981-12-3      950.00               30

     

    13 rows selected

     

    SQL> oradebug tracefile_name

    d:\oracle\admin\cuihua\udump\cuihua_ora_5016.trc

     

    相应的trace文件(d:\oracle\admin\cuihua\udump\cuihua_ora_5016.trc)的内容为:

    KGLTRCLCK kglget     hd = 0x206ECF90  KGL Lock addr = 0x3174E068 mode = N

    KGLTRCPIN kglpin     hd = 0x206ECF90  KGL Pin  addr = 0x317187C0 mode = X

    KGLTRCPIN kglpndl    hd = 0x206ECF90  KGL Pin  addr = 0x317187C0 mode = X

    KGLTRCLCK kglget     hd = 0x33B19238  KGL Lock addr = 0x3174E618 mode = N

    KGLTRCPIN kglpin     hd = 0x33B19238  KGL Pin  addr = 0x31717F28 mode = X

    KGLTRCPIN kglpndl    hd = 0x33B19238  KGL Pin  addr = 0x31717F28 mode = S

    KGLTRCLCK kgllkdl    hd = 0x33B19238  KGL Lock addr = 0x3174E618 mode = N

    KGLTRCLCK kgllkdl    hd = 0x206ECF90  KGL Lock addr = 0x3174E068 mode = N

     

    SQL> select kglhdadr,kglhdpar,kglnaobj from x$kglob where kglhdadr=’33B19238′;

     

    KGLHDADR KGLHDPAR KGLNAOBJ

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

    33B19238 206ECF90 select * from scott.emp

     

    很明显,从上述trace文件中我们可以得出如下结论:

    1、10.2.0.1中,sql硬解析时,针对cursor的library cache lock的lock mode依然是null;

    2、10.2.0.1中,sql硬解析时,针对cursor的library cache pin的lock mode一般是X,但也存在lock mode为S的library cache pin,且这个S是针对子cursor的。

     

    好了,10.2.0.1就告一段落,我们现在来看看10.2.0.5:

    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.5.0

    Connected as SYS

     

    MOS上说:从10.2.0.2开始,Oracle_kks_use_mutex_pin的默认值改成了true,表明Oracle将用mutex替代针对cursorlibrary cache pin

    但实际情况并不完全是这样,详情见后面的测试:

    SQL> select name,value,description from sys.all_parameters where name like ‘_kks%’;

     

    NAME                           VALUE      DESCRIPTION

    —————————— ———- ————————————————–

    _kks_use_mutex_pin             TRUE       Turning on this will make KKS use mutex for cursor pins.

     

    SQL> select * from scott.emp;

     

    EMPNO ENAME      JOB   MGR HIREDATE         SAL       COMM     DEPTNO

    ———- ———- ——— ———- ——— ———- ———- ———-

    7369 SMITH      CLERK          7902 17-DEC-80        800                    20

    7499 ALLEN    SALESMAN        7698 20-FEB-81       1600        300         30

    ……省略显示部分内容

    7934 MILLER     CLERK           7782 23-JAN-82       1300                    10

     

    14 rows selected.

     

    SQL> select hash_value,sql_text from v$sqlarea where sql_text like ‘select * from scott.emp%’;

     

    HASH_VALUE SQL_TEXT

    ———- ——————————–

      52404428 select * from scott.emp

     

    SQL> oradebug setmypid

    Statement processed.

    SQL> oradebug event 10049 trace name context forever,level 2697732144

    Statement processed.

     

    SQL> select * from scott.emp;

     

    EMPNO ENAME      JOB   MGR HIREDATE         SAL       COMM     DEPTNO

    ———- ———- ——— ———- ——— ———- ———- ———-

    7369 SMITH      CLERK          7902 17-DEC-80        800                    20

    7499 ALLEN    SALESMAN        7698 20-FEB-81       1600        300         30

    ……省略显示部分内容

    7934 MILLER     CLERK           7782 23-JAN-82       1300                    10

     

    14 rows selected.

     

    SQL> oradebug tracefile_name

    /u01/app/oracle/admin/testdb/udump/testdb_ora_1237156.trc

     

    $ cat /u01/app/oracle/admin/testdb/udump/testdb_ora_1237156.trc

    /u01/app/oracle/admin/testdb/udump/testdb_ora_1237156.trc

    Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 – 64bit Production

    With the Partitioning, OLAP, Data Mining and Real Application Testing options

    ORACLE_HOME = /u01/app/oracle/product/10.2.0

    System name:    AIX

    Node name:      P550_03_LD

    Release:        3

    Version:        5

    Machine:        0001DA17D600

    Instance name: testdb

    Redo thread mounted by this instance: 1

    Oracle process number: 15

    Unix process pid: 1237156, image: oracle@P550_03_LD (TNS V1-V3)

     

    *** 2011-06-01 13:38:07.949

    *** ACTION NAME:() 2011-06-01 13:38:07.944

    *** MODULE NAME:(sqlplus@P550_03_LD (TNS V1-V3)) 2011-06-01 13:38:07.944

    *** SERVICE NAME:(SYS$USERS) 2011-06-01 13:38:07.944

    *** SESSION ID:(146.3) 2011-06-01 13:38:07.944

    KGLTRCLCK kgllkal    hd = 0x700000022595c38  KGL Lock addr = 0x70000001f724d78 mode = N

    KGLTRCLCK kglget     hd = 0x700000022595c38  KGL Lock addr = 0x70000001f724d78 mode = N

    KGLTRCLCK kgllkal    hd = 0x7000000226ec4f8  KGL Lock addr = 0x70000001f74e128 mode = N

    KGLTRCLCK kgllkdl    hd = 0x7000000226ec4f8  KGL Lock addr = 0x70000001f74e128 mode = N

    KGLTRCLCK kgllkdl2   hd = 0x7000000226ec4f8  KGL Lock addr = 0x70000001f74e128 mode = 0

    KGLTRCLCK kgllkdl    hd = 0x700000022595c38  KGL Lock addr = 0x70000001f724d78 mode = N

    KGLTRCLCK kgllkdl2   hd = 0x700000022595c38  KGL Lock addr = 0x70000001f724d78 mode = 0

    这里mode=0应该是表示调用kgllkdl2所产生的library cache lock在调用完上述方法后已经释放了。

     

    SQL> select kglhdadr,kglhdpar,kglnaobj from x$kglob where lower(kglhdadr)=’07000000226ec4f8′;

     

    KGLHDADR         KGLHDPAR         KGLNAOBJ

    —————- —————- ——————————————————————————–

    07000000226EC4F8 0700000022595C38 select * from scott.emp

     

    很明显,从上述trace文件中我们可以得出如下结论:

    10.2.0.5中,sql软解析时,针对cursorlibrary cache pin确实已经不存在;

     

    现在我们来观察10.2.0.5下sql的硬解析时library cache pin和library cache lock:

    $ sqlplus ‘/ as sysdba’;

     

    SQL*Plus: Release 10.2.0.5.0 – Production on Wed Jun 1 13:42:11 2011

     

    Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.

     

     

    Connected to:

    Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 – 64bit Production

    With the Partitioning, OLAP, Data Mining and Real Application Testing options

     

    SQL> shutdown immediate

    Database closed.

    Database dismounted.

    ORACLE instance shut down.

    SQL> startup

    ORACLE instance started.

     

    Total System Global Area  314572800 bytes

    Fixed Size                  2096032 bytes

    Variable Size              96470112 bytes

    Database Buffers          209715200 bytes

    Redo Buffers                6291456 bytes

    Database mounted.

    Database opened.

     

    SQL> oradebug setmypid

    Statement processed.

    SQL> oradebug event 10049 trace name context forever,level 2697732144

    Statement processed.

     

    SQL> select * from scott.emp;

     

    EMPNO ENAME      JOB   MGR HIREDATE         SAL       COMM     DEPTNO

    ———- ———- ——— ———- ——— ———- ———- ———-

    7369 SMITH      CLERK          7902 17-DEC-80        800                    20

    7499 ALLEN    SALESMAN        7698 20-FEB-81       1600        300         30

    ……省略显示部分内容

    7934 MILLER     CLERK           7782 23-JAN-82       1300                    10

     

    14 rows selected.

     

    SQL> oradebug tracefile_name

    /u01/app/oracle/admin/testdb/udump/testdb_ora_1536246.trc

     

    $ cat /u01/app/oracle/admin/testdb/udump/testdb_ora_1536246.trc

    /u01/app/oracle/admin/testdb/udump/testdb_ora_1536246.trc

    Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 – 64bit Production

    With the Partitioning, OLAP, Data Mining and Real Application Testing options

    ORACLE_HOME = /u01/app/oracle/product/10.2.0

    System name:    AIX

    Node name:      P550_03_LD

    Release:        3

    Version:        5

    Machine:        0001DA17D600

    Instance name: testdb

    Redo thread mounted by this instance: 1

    Oracle process number: 15

    Unix process pid: 1536246, image: oracle@P550_03_LD (TNS V1-V3)

     

    *** ACTION NAME:() 2011-06-01 13:42:44.913

    *** MODULE NAME:(sqlplus@P550_03_LD (TNS V1-V3)) 2011-06-01 13:42:44.913

    *** SERVICE NAME:(SYS$USERS) 2011-06-01 13:42:44.913

    *** SESSION ID:(159.3) 2011-06-01 13:42:44.913

    DBRM(kskinitrm) cpu_count : old(0) -> new(2)

    kwqmnich: current time::  5: 42: 44

    kwqmnich: instance no 0 check_only flag 1

    kwqmnich: initialized job cache structure

    *** 2011-06-01 13:44:13.657

    KGLTRCLCK kgllkal    hd = 0x7000000225ccfa8  KGL Lock addr = 0x70000001f725560 mode = N

    KGLTRCLCK kglget     hd = 0x7000000225ccfa8  KGL Lock addr = 0x70000001f725560 mode = N

    KGLTRCPIN kglpin     hd = 0x7000000225ccfa8  KGL Pin  addr = 0x70000001f726378 mode = X

    KGLTRCPIN kglpndl    hd = 0x7000000225ccfa8  KGL Pin  addr = 0x70000001f726378 mode = X

    KGLTRCLCK kgllkal    hd = 0x7000000225abf18  KGL Lock addr = 0x70000001f733120 mode = N

    KGLTRCLCK kglget     hd = 0x7000000225abf18  KGL Lock addr = 0x70000001f733120 mode = N

    KGLTRCPIN kglpin     hd = 0x7000000225abf18  KGL Pin  addr = 0x70000001f726840 mode = X

    KGLTRCPIN kglpndl    hd = 0x7000000225abf18  KGL Pin  addr = 0x70000001f726840 mode = X

    KGLTRCLCK kgllkdl    hd = 0x7000000225abf18  KGL Lock addr = 0x70000001f733120 mode = N

    KGLTRCLCK kgllkdl2   hd = 0x7000000225abf18  KGL Lock addr = 0x70000001f733120 mode = 0

    KGLTRCLCK kgllkdl    hd = 0x7000000225ccfa8  KGL Lock addr = 0x70000001f725560 mode = N

    KGLTRCLCK kgllkdl2   hd = 0x7000000225ccfa8  KGL Lock addr = 0x70000001f725560 mode = 0

     

    SQL> select kglhdadr,kglhdpar,kglnaobj from x$kglob where lower(kglhdadr)=’07000000225abf18′;

     

    KGLHDADR         KGLHDPAR         KGLNAOBJ

    —————- —————- ——————————————————————————–

    07000000225ABF18 07000000225CCFA8 select * from scott.emp

     

    很明显,从上述trace文件中我们可以得出如下结论:

    1、10.2.0.5中,sql硬解析时,依然存在library cache pin

    2、10.2.0.5中,sql硬解析时,针对cursor的library cache pin的lock mode始终是X;

     


    2 Comments on “library cache lock和library cache pin到底是什么(续)”

    1. wxjzqymtl

      首先非常博主的这篇文章,最近一直想搞清楚在sql语句被解析与执行阶段
      对应的lock与pin的模式以及引用的数据库对象的lock和pin的模式分别是什么,
      您的这篇文章给了我一个清晰的思路,我想向您确认两个问题
      1.10049事件对lock,pin模式的跟踪周期是从sql开始解析一直到执行结束吗?
      因为通过10049事件trace的最后结果是无论软,硬解析lock,pin的模式最后分别都是N和S;
      可是一个sql语句执行结束后他的lock和pin的模式都会变为0,也就是释放锁资源,这个结果
      是通过library_cache event看到的,还是说10049只跟踪从解析开始到结束(除锁资源释放的那个过程)
      2.您的这个案例中只是针对cursor类对象来跟踪其解析与执行阶段lock,pin模式的不断变化,如果
      我还想跟踪相应的游标中引用的对象的lock,pin模式的变化的话有办法吗?

      • 1、10049只跟踪从解析开始到执行结束中间的过程,如果要查看cursor的lock和pin在执行结束后的状态,可以对相关library cache做dump
        2、10049是用来跟踪一些基本的library cache function(如pin、lock等),不仅限于cursor


 

相关文章
|
6月前
|
存储 缓存 Android开发
安卓Jetpack Compose+Kotlin, 使用ExoPlayer播放多个【远程url】音频,搭配Okhttp库进行下载和缓存,播放完随机播放下一首
这是一个Kotlin项目,使用Jetpack Compose和ExoPlayer框架开发Android应用,功能是播放远程URL音频列表。应用会检查本地缓存,如果文件存在且大小与远程文件一致则使用缓存,否则下载文件并播放。播放完成后或遇到异常,会随机播放下一首音频,并在播放前随机设置播放速度(0.9到1.2倍速)。代码包括ViewModel,负责音频管理和播放逻辑,以及UI层,包含播放和停止按钮。
|
Oracle 关系型数据库 流计算
Flink CDC不支持直接连接到Oracle ADG备库进行数据同步
Flink CDC不支持直接连接到Oracle ADG备库进行数据同步
320 1
|
存储 Oracle 关系型数据库
Oracle中“ORA-00060: 等待资源时检测到死锁” 或存储过程编译卡死的一种解决方法
Oracle中“ORA-00060: 等待资源时检测到死锁” 或存储过程编译卡死的一种解决方法
830 0
|
4月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
102 1
|
7月前
|
SQL Oracle 关系型数据库
实时计算 Flink版产品使用合集之和Oracle数据同步必须是使用主库吗
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStreamAPI、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
实时计算 Flink版产品使用合集之和Oracle数据同步必须是使用主库吗
|
2月前
|
Oracle 关系型数据库 MySQL
shell获取多个oracle库mysql库所有的表
请注意,此脚本假设你有足够的权限访问所有提到的数据库。在实际部署前,请确保对脚本中的数据库凭据、主机名和端口进行适当的修改和验证。此外,处理数据库操作时,务必谨慎操作,避免因错误的脚本执行造成数据损坏或服务中断。
43 0
|
5月前
|
Oracle 关系型数据库 Linux
讲解linux下的Qt如何编译oracle的驱动库libqsqloci.so
通过这一连串的步骤,可以专业且有效地在Linux下为Qt编译Oracle驱动库 `libqsqloci.so`,使得Qt应用能够通过OCI与Oracle数据库进行交互。这些步骤适用于具备一定Linux和Qt经验的开发者,并且能够为需要使用Qt开发数据库应用的专业人士提供指导。
169 1
讲解linux下的Qt如何编译oracle的驱动库libqsqloci.so
|
4月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot引入Caffeine作为缓存库的问题如何解决
|
5月前
|
设计模式 存储 缓存
Java面试题:结合单例模式与Java内存模型,设计一个线程安全的单例类?使用内存屏障与Java并发工具类,实现一个高效的并发缓存系统?结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
Java面试题:结合单例模式与Java内存模型,设计一个线程安全的单例类?使用内存屏障与Java并发工具类,实现一个高效的并发缓存系统?结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
43 0
|
6月前
|
消息中间件 Oracle 关系型数据库
使用 cx_Oracle 在 Oracle 中等待记录并执行操作
问题背景: 在第一个 Python 项目中,需要等待记录被插入 Oracle 表中,一旦记录存在,就调用 Python 函数。目前使用 cx_Oracle 库,采用一种无限循环的方式来查询表。如果记录存在,就调用函数,然后等待 5 秒后重新开始循环。但这种方式效率不高,等待时间太长,并且系统看起来很慢。如果不想要每秒都向数据库发送查询,是否有其他方法来等待记录并执行操作?

推荐镜像

更多