zoukankan      html  css  js  c++  java
  • Library cache lock/pin详解

    Library cache lock/pin

    一、概述

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

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

     

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

    二、library cache pin和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


    当要对一个过程或者函数进行编译时,需要在library cache中pin该对象。在pin该对象以前,需要获得该对象handle的锁定,如果获取失败,就会产生library cache lock等待。如果成功获取handle的lock,则继续在library cache中pin该对象,如果pin对象失败,则会产生library cache pin等待。

    如果是存储过程或者函数,可以这样认为:如果存在librarycache lock等待,则一定存在library cache pin等待;反过来,如果存在library cache pin等待,不一定会存在library cache lock等待;
    但如果是表引起的,则一般只有library cache lock等待,则不一定存在library cache pin。

    可能发生library cache pin和library cache lock的情况:
    1、在存储过程或者函数正在运行时被编译。
    2、在存储过程或者函数正在运行时被对它们进行授权、或者移除权限等操作。
    3、对某个表执行DDL期间,有另外的会话对该表执行DML或者DDL。
    4、PL/SQL对象之间存在复杂的依赖性

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

    例如:
    SES1:
    执行:exec p_sleep;
    假设存储过程p正在运行,且运行时间很长
    SES2:
    执行:grant execute on p_sleep to system
    对p进行编译,如果之前没有其他会话lock存储过程p的handle,则本会话会将获取p的handle锁定;但会话pin p时会失败,此时在SES2上产生library cache pin等待。如果超过5分钟仍然不能完成pinp,则会报错:
    ORA-04021: 等待锁定对象 SUK.P_SLEEP 时发生超时。此时,本会话会释放p的handlelock。(也可能是ORA-04020错误)
    SES3:
    执行:grant execute on p_sleepto system
    在这个会话中继续编译p,则该会话在获取p的handle锁定时会失败,在本会话产生librarycache lock等待。如果SES2超时,则本会话会获取p的handlelock,v$session_wait上的等待事件也由librarycache lock变成ibrary cache pin,直到超时。

    librarycache pin
    查询v$session_wait视图中library cache pin对应的P1、P2、P3
    P1 = Handle address
    这个就是引起library cache pin等待的对象被pin到library cache中的handle。一般用P1RAW(十六进制)代替p1(十进制)
    可以用以下sql查询那个用户下的那个对象正在被请求pin:
    SELECT kglnaown "Owner", kglnaobj "Object"
    FROM x$kglob
    WHERE kglhdadr='&P1RAW'

    返回的OBJECT可能是具体的对象,也可能是一段SQL。

    P2 =Pin address
    自身的pin地址。一般用P2RAW(十六进制)代替P2(十进制)

    P3 = Encoded Mode & Namespace

    library cache pin和library cache lock(一)我们简单介绍了介绍library cache pin和librarycache lock的成因,下面介绍如何解决library cache pin和library cache lock等待。

    三、解决方法

    有两种方法可以查询library cache pin的相关信息,推荐使用第二种。

    使用这种方法前,有必要先了解以下表或视图:x$kglob、x$kgllk、x$kglpn、DBA_KGLLOCK

    1) x$kglob

    该基表主要是library cache object的相关信息。
    X$KGLOB--[K]ernel [G]eneric [L]ibrary Cache Manager [OB]ject
    引用该基表的视图有﹕GV$ACCESS、GV$OBJECT_DEPENDENCY、GV$DB_OBJECT_CACHE、GV$DB_PIPES、DBA_LOCK_INTERNAL﹑DBA_DDL_LOCKS

    2) x$kgllk
    该基表保存了library cache中对象的锁信息,主要用于解决library cache lock。
    其名称含义是:
    [K]ernel Layer 
    [G]eneric Layer 
    [L]ibrary Cache Manager ( defined and mapped from kqlf ) 
    Object Locks 
    X$KGLLK - Object [L]oc[K]s 

    引用该基表的视图有﹕
    DBA_DDL_LOCKS ﹑DBA_KGLLOCK ﹑GV$ACCESS﹑GV$OPEN_CURSOR 

    SQL> desc x$kgllk;
    名称 类型
    ---------- -----------
    ADDR RAW(4)
    INDX NUMBER
    INST_ID NUMBER
    KGLLKADR RAW(4)
    KGLLKUSE RAW(4) ---会话地址(对应v$session的saddr)
    KGLLKSES RAW(4) ---owner地址
    KGLLKSNM NUMBER ---SID
    KGLLKHDL RAW(4) ---句柄
    KGLLKPNC RAW(4) ---the address of the call pin
    KGLLKPNS RAW(4) ---对应跟踪文件中的session pin值 
    KGLLKCNT NUMBER 
    KGLLKMOD NUMBER ---持有锁的模式(0为nolock/pin held﹐1为null,2为share﹐3为exclusive) 
    KGLLKREQ NUMBER ---请求锁的模式(0为nolock/pin held﹐1为null,2为share﹐3为exclusive) 
    KGLLKFLG NUMBER ---cursor的状态﹐8(10g前)或2048(10g)表示这个sql正在运行﹐
    KGLLKSPN NUMBER ---对应跟踪文件的savepoint的值
    KGLLKHTB RAW(4)
    KGLNAHSH NUMBER ---sql的hash值(对应v$session的sql_hash_value)
    KGLLKSQLID VARCHAR2(13) ---sql ID,sql标识符
    KGLHDPAR RAW(4) ---sql地址(对应v$session的sql_address) 
    KGLHDNSP NUMBER
    USER_NAME VARCHAR2(30) ---会话的用戶名
    KGLNAOBJ VARCHAR2(60) ---对象名称或者已分析并打开cursor的sql的前60个字符

    3) x$kglpn
    X$KGLPN--[K]ernel [G]eneric [L]ibrary Cache Manager object [P]i[N]s 
    它是与x$kgllk相对应的表﹐是关于pin的相关信息。它主要用于解决library cache pin
    引用该表的视图有﹕
    DBA_KGLLOCK

    SQL>desc x$kglpn;
    名称 类型
    ------------ ----------------------------
    ADDR RAW(4)
    INDX NUMBER
    INST_ID NUMBER
    KGLPNADR RAW(4)
    KGLPNUSE RAW(4) ---会话地址(对应v$session的saddr)
    KGLPNSES RAW(4) ---owner地址
    KGLPNHDL RAW(4) ---句柄
    KGLPNLCK RAW(4)
    KGLPNCNT NUMBER
    KGLPNMOD NUMBER ---持有pin的模式(0为no lock/pin held﹐1为null,2为share﹐3为exclusive) 
    KGLPNREQ NUMBER ---请求pin的模式(0为no lock/pin held﹐1为null,2为share﹐3为exclusive)
    KGLPNDMK NUMBER
    KGLPNSPN NUMBER ---对应跟踪文件的savepoint的值

    4) DBA_KGLLOCK
    DBA_KGLLOCK是一个视图,它联合了x$kgllk和x$kglpn的部分信息。 
    通过查询,我们可以知道DBA_KGLLOCK视图的构建语句:
    SQL> SELECT * FROM DBA_VIEWS WHERE VIEW_NAME='DBA_KGLLOCK';

    select kgllkuse, kgllkhdl, kgllkmod, kgllkreq, 'Lock' kgllktype from x$kgllk 
    union all 
    select kglpnuse, kglpnhdl, kglpnmod, kglpnreq, 'Pin' kgllktype from x$kglpn

    了解了用到的几个主要视图或表的结构,我们就可以写出编写查询来查看相关信息:
    方法一、只能查询librarycache pin相关信息
    SQL> SELECT distinct decode(kglpnreq,0,'holding_session:'||s.sid,'waiting_session: '||s.sid) sid,
    2 s.SERIAL#, kglpnmod "Pin Mode", kglpnreq "ReqPin",a.sql_text,kglnaown "Owner", kglnaobj "Object"
    3 FROM x$kglpn p, v$session s,v$sqlarea a,v$session_wait sw,x$kglob x
    4 WHERE p.kglpnuse=s.saddr
    5 AND kglpnhdl=sw.p1raw
    6 and kglhdadr=sw.p1raw
    7 and event like 'library cache%'
    8 and (a.hash_value, a.address) IN (
    9 select
    10 DECODE (sql_hash_value,
    11 0,
    12 prev_hash_value,
    13 sql_hash_value
    14 ),
    15 DECODE (sql_hash_value, 0, prev_sql_addr, sql_address)
    16 from v$session s2
    17 where s2.sid=s.sid
    18 )
    19 ;

    SID SERIAL# Pin Mode Req Pin SQL_TEXT Owner Object
    -------------------- ---------- ---------- -------------------------------------------------- ------------ --------------------
    blocked_sid: 16 195 0 3 grant execute on p_s SUK P_SLEEP
    blocker_sid: 20 15 2 0 begin p_sleep; end; SUK P_SLEEP

    得到这个结果后,你可以根据实际情况kill掉阻塞的会话或者被阻塞的会话。


    方法二、可以查询library cache pin和library cache lock 的信息


    selectDistinct /*+ ordered */ w1.sid waiting_session,
    h1.sid holding_session, 
    w.kgllktype lock_or_pin, 
    od.to_owner object_owner, 
    od.to_name object_name, 
    oc.Type, 
    decode(h.kgllkmod, 0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive', 
    'Unknown') mode_held, 
    decode(w.kgllkreq, 0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive', 
    'Unknown') mode_requested,
    xw.KGLNAOBJ wait_sql,xh.KGLNAOBJ hold_sql 
    from dba_kgllock w, dba_kgllock h, v$session w1, 
    v$session h1,v$object_dependency od,V$DB_OBJECT_CACHE oc,x$kgllk xw,x$kgllk xh
    where 
    (((h.kgllkmod != 0) and (h.kgllkmod != 1) 
    and ((h.kgllkreq = 0) or (h.kgllkreq = 1))) 
    and 
    (((w.kgllkmod = 0) or (w.kgllkmod= 1)) 
    and ((w.kgllkreq != 0) and (w.kgllkreq != 1)))) 
    and w.kgllktype = h.kgllktype 
    and w.kgllkhdl = h.kgllkhdl 
    and w.kgllkuse = w1.saddr 
    and h.kgllkuse = h1.saddr 
    And od.to_address = w.kgllkhdl 
    And od.to_name=oc.Name 
    And od.to_owner=oc.owner 
    And w1.sid=xw.KGLLKSNM
    And h1.sid=xh.KGLLKSNM 
    And (w1.SQL_ADDRESS=xw.KGLHDPAR And w1.SQL_HASH_VALUE=xw.KGLNAHSH)
    And (h1.SQL_ADDRESS=xh.KGLHDPAR And h1.SQL_HASH_VALUE=xh.KGLNAHSH) 
    ;



    WAITING_SESSION HOLDING_SESSION LOCK_OR_PIN OBJECT_OWNER OBJECT_NAME TYPEMODE_HELD MODE_REQUESTED WAIT_SQL HOLD_SQL
    --------------- --------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------- --------------------------------------------------------------------------------------------------------------------------------------
    18 19 Lock SUK P_SLEEP PROCEDURE Exclusive Exclusive grant execute on p_sleepto system grant execute on p_sleep to system
    19 12 Pin SUK P_SLEEP PROCEDURE Share Exclusive grant execute on p_sleep tosystem begin p_sleep; end;
    23 25 Lock SUK P_SLEEP2 PROCEDURE Exclusive Exclusive grant execute on p_sleep2to system grant execute on p_sleep2 to system
    25 14 Pin SUK P_SLEEP2 PROCEDURE Share Exclusive grant execute on p_sleep2 tosystem begin p_sleep2; end;


    为了避免这种情况,可以在编译过程或函数等对象时,先查看一下是否有会话正在使用该对象,查询语句如下:

    SELECT Distinct sid using_sid, 
    s.SERIAL#, kglpnmod "Pin Mode", kglpnreq "Req Pin",kglnaown"Owner", kglnaobj "using_Object"
    FROM x$kglpn p, v$session s,x$kglob x 
    WHERE p.kglpnuse=s.saddr 
    AND kglpnhdl=kglhdadr 
    And p.KGLPNUSE = s.saddr 
    And kglpnreq=0 
    And upper(kglnaobj) = upper('&obj'); 

    如果有结果返回,则等待这些对话的操作执行完毕再重新编译,也可以把这些会话kill。

    四、其他解决方法
    上面主要是用到SQL查询相关信息的解决方法,也可以使用10046、trace等方法实现。至于用那种方法好,见仁见智。



    Howto Find which Session is Holding a Particular Library Cache Lock [ID 122793.1]

    Troubleshooting Details

    CommonSituations 

    • A DML operation that is hanging because the table which is accessed is currently undergoing changes (ALTER TABLE). This may take quite a long time depending on the size of the table and the type of the modification (e.g. ALTER TABLE x MODIFY (col1 CHAR(200) on a table with thousands of records)

    Inthis case, V$LOCK will show that the session doing the 'ALTER TABLE' with anexclusive DML enqueue lock on the table object (LMODE=6, TYPE=TM where ID1 isthe OBJECT_ID of the table). The waiting session however does not show up inV$LOCK yet so in an environment with a lot of concurrent sessions the V$LOCKinformation will be insufficient to track down the culprit blocking youroperation.

    • The compilation of package will hang on Library Cache Lock and Library Cache Pin if any users are executing a procedure/function defined in the same package.

    Method1: Systemstate Analysis

    Systemstate event willcreate a tracefile containing detailed information on every Oracle process.This information includes all the resources held & requested by a specificprocess.

    While an operation is hanging, open a new session and launch the followingstatement:

    For Oracle 9.2.0.1 or higher:

    $sqlplus '/ as sysdba'
    oradebug setmypid
    oradebug unlimit
    oradebug dump systemstate266


    For older versions you can use the following syntax that is also possible inhigher versions.The level 266 is not available before 9.2.0.6

    alter session setmax_dump_file_size=unlimited;
    alter session set events'immediate trace name systemstate level 10'


     Oracle will create a systemstate tracefile in your USER_DUMP_DESTdirectory.

    Get the PID (ProcessID) of the 'hanging' session:

    select pid from v$process where addr=
    (select paddr fromv$session where sid= <sid_of_hanging_session> );


    The systemstate dump contains a separate section with information for eachprocess.
    Open the tracefile and do a search for "PROCESS <PID fromabove>".
    In the process section search for the wait event by doing a search on 'waitingfor'.

    PROCESS20: 
    ---------------------------------------- 
    SO: 0x7d2bd820, type: 2, owner: (nil), flag: INIT/-/-/0x00 
    (process) Oracle pid=20, calls cur/top: 0x7d3d62d0/0x7d3d85dc, flag: (0) - 
    int error: 0, call error: 0, sess error: 0, txn error 0 
    (post info) last post received: 109 0 4 
    last post received-location: kslpsr 
    last process to post me: 7d2b8d94 1 6 
    last post sent: 0 0 24 
    last post sent-location: ksasnd 
    last process posted by me: 7d2b8d94 1 6 
    (latch info) wait_event=0 bits=0 
    Process Group: DEFAULT, pseudo proc: 0x7d2ed5dc 
    O/S info: user: oracle, term: pts/7, ospid: 19759 
    OSD pid info: Unix process pid: 19759, image: goblin.forgotten.realms (TNSV1-V3) 

    <cut> 

    (session) sid: 141 trans: (nil), creator: 0x7d2bd820, flag: (41) USR/-BSY/-/-/-/-/-
    DID: 0001-0014-00000668, short-term DID: 0000-0000-00000000 
    txn branch: (nil) 
    oct: 6, prv: 0, sql: 0x62d01c34, psql: 0x7c20f24c, user: 542/SCOTT 
    service name: SYS$USERS 
    O/S info: user: oracle, term: pts/7, ospid: 19758, machine:goblin.forgotten.realms
    program: sqlplus@goblin.forgotten.realms (TNS V1-V3) 
    application name: SQL*Plus, hash value=3669949024 
    waiting for 'library cache lock' blocking sess=0x(nil) seq=36 wait_time=0seconds since wait started=11
    handle address=62d064dc, lockaddress=79f88a68, 100*mode+namespace=c9

    • Use the handle address to find information on the object locked:

    SO: 0x79f88a68, type: 53,owner: 0x7d3d62d0, flag: INIT/-/-/0x00
    LIBRARY OBJECT LOCK: lock=79f88a68 handle=62d064dc request=S
    call pin=(nil) session pin=(nil) hpc=0000 hlc=0000
    htl=0x79f88ab4[0x79e71e60,0x79e71e60] htb=0x79e71e60 ssga=0x79e716fc
    user=7d3a13b8 session=7d3a13b8 count=0 flags=[0000] savepoint=0xce
    LIBRARY OBJECT HANDLE: handle=62d064dc mtx=0x62d06590(0) cdp=0
    name=SCOTT.EMPLOYEES


    We see the library object lock is being requested in Shared mode (request=S)
    Name of the the object is SCOTT.EMPLOYEES

    • Use the 'handle address' to find the process that is holding the lock on  your resource by doing a search on the address within the same tracefile.

    PROCESS 18: 
    ---------------------------------------- 
    SO: 0x7d2bcca8, type: 2, owner: (nil), flag: INIT/-/-/0x00 
    (process) Oracle pid=18, calls cur/top: 0x79f3ab84/0x7d3d5fc8, flag: (0) - 
    int error: 0, call error: 0, sess error: 0, txn error 0 
    (post info) last post received: 109 0 4 
    last post received-location: kslpsr 
    last process to post me: 7d2b8d94 1 6 
    last post sent: 0 0 24 
    last post sent-location: ksasnd 
    last process posted by me: 7d2b8d94 1 6 

    <cut> 

    SO: 0x75fe8f7c, type: 53, owner: 0x7b751914, flag: INIT/-/-/0x00 
    LIBRARY OBJECT LOCK: lock=75fe8f7c handle=62d064dc mode=X
    call pin=(nil) session pin=(nil) hpc=0000 hlc=0000 
    htl=0x75fe8fc8[0x79f81790,0x79fc3ef8] htb=0x79f81790 ssga=0x79f8102c 
    user=7d3988d0 session=7d3988d0 count=1 flags=[0000] savepoint=0x146e 
    LIBRARY OBJECT HANDLE: handle=62d064dc mtx=0x62d06590(0) cdp=0 
    name=SCOTT.EMPLOYEES


    From the output we can see that the Process 18 (pid)  is holding  anexclusive lock (mode=X) on the object we are trying to access. Using V$PROCESSand V$SESSION we can retrieve the sid, user, terminal, program,... for thisprocess.
     
    The actual statement that was launched by this session is also listed in thetracefile (statements and other library cache objects are preceded by 'name=').

     METHOD 2: EXAMINE THE X$KGLLK TABLE

    TheX$KGLLK table (accessible only as SYS/INTERNAL) contains all the library objectlocks (both held & requested) for all sessions and is more complete thanthe V$LOCK view although the column names don't always reveal their meaning.

    You can examine the locks requested (and held) by the waiting session bylooking up the session address (SADDR) in V$SESSION and doing the followingselect:

    select sid,saddr fromv$session where event= 'library cache lock';

    SID SADDR
    ---------- --------
    16 572ed244


    selectkgllkhdl Handle,kgllkreq Request, kglnaobj Object
    fromx$kgllk where kgllkses = '572ed244'
    andkgllkreq > 0;

    HANDLE   REQUEST  OBJECT
    -------- ----------------------------------------------------------------------
    62d064dc         2 EMPLOYEES


    This will show you the library cache lock requested by this session (KGLLKREQ> 0) where KGLNAOBJ contains the first 80 characters of the name of theobject.The value in KGLLKHDL corresponds with the 'handle address' of theobject in Method 1 Systemstate Analysis as shown above.

     If we now match the KGLLKHDL with the handles of other sessions inX$KGLLK that should give us the address of the blocking session.The sessionholding the lock will have KGLLKMOD > 0 as it is holding the lock.

    select kgllksessaddr,kgllkhdl handle,kgllkmod mod,kglnaobj object
    fromx$kgllk lock_a
    wherekgllkmod > 0
    andexists (select lock_b.kgllkhdl from x$kgllk lock_b
    wherekgllkses = '572ed244' /* blocked session */
    andlock_a.kgllkhdl = lock_b.kgllkhdl
    andkgllkreq > 0);

    SADDR    HANDLE   MOD
    --------  ------------------
    OBJECT
    ------------------------------------------------------------
    572eac94 62d064dc          3
    EMPLOYEES



    If we look a bit further we can then again match KGLLKSES with SADDR inv$session to find further information on the blocking session:

    selectsid,username,terminal,program from v$session where saddr = '572eac94'

    SID       USERNAME                 TERMINAL
    ---------------------------------------- ------------------------------
    PROGRAM
    ------------------------------------------------
    12         SCOTT                         pts/20
    sqlplus@goblin.forgotten.realms(TNS V1-V3)


    In the same way we can also find all the blocked sessions:

    selectsid,username,terminal,program from v$session
    wheresaddr in 
    (selectkgllkses from x$kgllk lock_a 
     wherekgllkreq > 0
     andexists (select lock_b.kgllkhdl from x$kgllk lock_b
                where kgllkses = '572eac94' /* blocking session */
                and lock_a.kgllkhdl = lock_b.kgllkhdl
                and kgllkreq = 0)
    );

    SID      USERNAME                      TERMINAL
    ---------- ------------------------------------------------------------
    PROGRAM
    ------------------------------------------------
    13        SCOTT                          pts/22
    sqlplus@goblin.forgotten.realms(TNS V1-V3)

    16        SCOTT                          pts/7
    sqlplus@goblin.forgotten.realms(TNS V1-V3)


    Related Documents

    Note:1020008.6 SCRIPT FULLY DECODED LOCKING SCRIPT
    Note:1054939.6 COMPILATION OF PACKAGE IS HANGING ONLIBRARY CACHE LOCK

    =================
    library cache pin
    =================
    原理
    ~~~~~
    An Oracle instance has alibrary cache that contains the description of  
    different types of objectse.g. cursors, indexes, tables, views, procedures,  
    ... Those objects cannot bechanged when they are used. They are locked by a  
    mechanism based on librarylocks and pins. A session that need to use an object  
    will first acquire a librarylock in a certain mode (null, shared or exclusive)  
    on the object, in order toprevent other sessions from accessing the same  
    object (e.g. exclusive lockwhen recompiling a package or view) or to maintain  
    the object definition for along time. Locking an object is sometimes referred 
    as the job to locate it inthe library cache and lock it in a certain mode. 
    If the session wants tomodify or examine the object, it must acquire after  
    the lock also a pin in acertain mode (again null, shared or exclusive).  

    Each SQL statement that wantto use/modify objects that are locked or pinned  
    and whose lock/pin mode isincompatible with the requested mode, will wait  
    on events like 'library cachepin' or 'library cache lock' until a timeout  
    occurs. The timeout normallyoccurs after 5 minutes and the SQL statement  
    then ends with an ORA-4021.If a deadlock is detected, an ORA-4020 is given  
    back. 


    Dealing with slow downsrelated to "mysterious" library cache pins  
    and load locks we should lookfor the reason of the database object  
    invalidations. They arelikely to be triggered by actions causing  
    changes to"LAST_DDL" attribute of database objects that have other 
    dependent ones. Typicallythey are the object maintenance operations -  
    ALTER, GRANT, REVOKE,replacing views, etc. This behavior is described 
    in Oracle Server ApplicationDeveloper's Guide as object dependency 
    maintenance. 

    After object invalidation,Oracle tries to recompile the object at the 
    time of the first access toit. It may be a problem in case when other 
    sessions have pinned theobject to the library cache. It is obvious that 
    it is more likely to occurwith more active users and with more complex 
    dependencies (eg. manycross-dependent packages or package bodies).  
    In some cases waiting forobject recompilation may even take hours  
    blocking all the sessionstrying to access it. 


    ORA-04021 timeout occurredwhile waiting to lock object %s%s%s%s%s". 
    Cause:  Whiletrying to lock a library object, a time-out occurred. 
    Action: Retry the operationlater. 

    ORA-04020 deadlock detectedwhile trying to lock object %s%s%s%s%s 
    Cause:  Whiletrying to lock a library object, a deadlock is detected. 
    Action: Retry the operationlater. 
    (see <Note.166924.1>) 

    2.   Which viewscan be used to detect library locking problems? 
    ---------------------------------------------------------------- 

    Different views can be usedto detect pin/locks: 

    DBA_KGLLOCK : one row foreach lock or pin of the instance 
    -KGLLKUSE  sessionaddress 
    -KGLLKHDL  Pin/Lockhandle 
    -KGLLKMOD/KGLLKREQ  Holding/requestedmode 
    0          no lock/pin held 
    1          null mode 
    2          share mode 
    3          exclusive mode 
    -KGLLKTYPE Pin/Lock 
    (created via the $ORACLE_HOME/rdbms/admin/catblock.sql) 

    V$ACCESS : one row for eachobject locked by any user 
    -SID      session sid 
    -OWNER    username 
    -OBJECT    objectname 
    -TYPE     object type 

    V$DB_OBJECT_CACHE : one rowfor each object in the library cache 
    -OWNER        object owner 
    -NAME         object name or cursor text 
    -TYPE         object type 
    -LOCKS        number of locks on this object 
    -PINS         number of pins on this object 

    DBA_DDL_LOCKS  :one row for each object that is locked (exception made of the cursors) 
    -SESSION_ID 
    -OWNER 
    -NAME 
    -TYPE 
    -MODE_HELD 
    -MODE_REQUESTED 

    V$SESSION_WAIT : each sessionwaiting on a library cache pin or lock is blocked by some other session 
    -p1 = object address 
    -p2 = lock/pin address 


    3.   How to findout why an ORA-4021 occurs? 
    -------------------------------------------- 

    When you execute thestatement that generates the ORA-4021, it is possible  
    during the delay of 5 minutesto detect the reason for the blocking situation.  
    Following query can be usedto find the blocking and waiting sessions: 

    FYI: You need to run thescript called "catblock.sql" first.  
    ===  This scriptcan be found in:  $ORACLE_HOME/rdbms/admin/catblock.sql  
      

    select /*+ ordered */w1.sid  waiting_session, 
            h1.sid  holding_session, 
           w.kgllktype lock_or_pin, 
           w.kgllkhdl address, 
           decode(h.kgllkmod,  0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive', 
              'Unknown') mode_held,  
           decode(w.kgllkreq,  0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive', 
              'Unknown') mode_requested 
      from dba_kgllockw, dba_kgllock h, v$session w1, v$session h1 
    where 
      (((h.kgllkmod !=0) and (h.kgllkmod != 1) 
         and((h.kgllkreq = 0) or (h.kgllkreq = 1))) 
       and 
        (((w.kgllkmod = 0) or (w.kgllkmod= 1)) 
         and((w.kgllkreq != 0) and (w.kgllkreq != 1)))) 
      and  w.kgllktype        =  h.kgllktype 
      and  w.kgllkhdl        =  h.kgllkhdl 
      and  w.kgllkuse    =   w1.saddr 
      and  h.kgllkuse    =   h1.saddr 


    The result looks like: 

    WAITING_SESSIONHOLDING_SESSION LOCK ADDRESS  MODE_HELD MODE_REQU 
    ------------------------------ ---- -------- --------- --------- 
                16             12 Pin  03FA2270 Share    Exclusive 

    The object that is locked canbe found with v$object_dependency and  
    should be the same as the onementioned in the ORA-4021 error message. 
    e.g. 
    select to_name fromv$object_dependency where to_address = '03FA2270'; 
    should give: 

    TO_NAME 
    ------------- 
    DBMS_PIPE 

    You can find which library objectsare used by each session via following  
    queries, e.g.  
    a. for the blocked session: 

    select distinct kglnaobj fromx$kgllk  where  
    kgllkuse in (select saddrfrom v$session where sid = 16); 

    b. for the blocking session 

    select distinct kglnaobj fromx$kgllk  where  
    kgllkuse in (select saddrfrom v$session where sid = 12); 

    One of those objects can bethe cursor or statement that each session is  
    executing/trying to execute. 

    You can also use the$ORACLE_HOME/rdbms/admin/utldtree.sql utility to find out  
    how the dependency tree lookslike and which objects are dependent on e.g.  
    DBMS_PIPE. One of thoseobjects will be the sql statement of the holding  
    session. A variant script onutldtree.sql stands in [NOTE:139594.1] and  
    gives which objects an objectdepends on. 




           Library cache pins are used to manage library cacheconcurrency. 
           Pinning an object causes the heaps to be loaded into memory(if not already loaded).
           PINS can be acquired in NULL, SHARE or EXCLUSIVE modes andcan be considered like a special form of lock. 
           A wait for a "library cache pin" implies some othersession holds that PIN in an incompatible mode. 
           
           P1 = Handle address 
           P2 = Pin address 
           P3 = Encoded Mode & Namespace 
           
           ·Handle address
           ~~~~~~~~~~~~~~~~                                                                                      
           Use P1RAW rather than P1                                                                                    
           This is the handle of the library cache object which thewaiting session wants to acquire a pin on.   

           
    查找library cache对象
    ~~~~~~~~~~~~~~  
           The actual object being waited on can be found using                                                        
             SELECT kglnaown "Owner", kglnaobj"Object"                                                                 
               FROM x$kglob                                                                                            
              WHERE kglhdadr='&1RAW'                                                                                  
             ;                                                                                                        
           ·Pin address
           ~~~~~~~~~~~~~
           Use P2RAW rather than P2                                                                                    
           This is the address of the PIN itself.                                                                       
           ·Encoded Mode & Namespace                                                                            
           ~~~~~~~~~~~~~~~~~~~~~~~~~
           In Oracle 7.0 - 8.1.7 inclusive the value is 10 * Mode +Namespace.                                            
           In Oracle 9.0 - 9.2 inclusive the value is 100 * Mode +Namespace.                                             
                                                                                                                      
           Where:                                                                                                     
                                                                                                                      
           Mode is the mode in which the pin is wanted. This is a numberthus:                                            
           o        2 - Share mode                                                                                      
           o        3 - Exclusive mode                                                                                  
                                                                                                                      
           Namespace is just the namespace number of the namespace inthe library cache in which the required object lives: 
           o        0 SQL Area                                                                                          
           o        1 Table / Procedure / Function /Package Header                                                       
           o        2 Package Body                                                                                      
           o        3 Trigger                                                                                           
           o        4 Index                                                                                            
            o       5 Cluster                                                                                           
           o        6 Object                                                                                            
           o        7 Pipe                                                                                             
           o        13 Java Source                                                                                      
           o        14 Java Resource                                                                                    
           o        32 Java Data        


    ====================
    library cache lock的成因和解决方法
    ====================
    两种原因
    ~~~~~~~~~
    * a DML operation that ishanging because the table which is accessed is currently  
       undergoingchanges (ALTER TABLE). This may take quite a long time depending on  
       the size of thetable and the type of the modification  
       (e.g. ALTERTABLE x MODIFY (col1 CHAR(200) on thousands of records).  

    * The compilation of packagewill hang on Library Cache Lock and Library Cache Pin  
      if some users areexecuting any Procedure/Function defined in the same package.  

    两种解决办法
    ~~~~~~~~~~~~~~~
    METHOD 1: SYSTEMSTATEANALYSIS 
    ------------------------------ 

    One way of finding thesession blocking you is to analyze the system state dump. 
    Using the systemstate eventone can create a tracefile containing detailed  
    information on every Oracleprocess. This information includes all the resources 
    held & requested by aspecific process. 

    Whilst an operation ishanging, open a new session and launch the following 
    statement: 

    ALTER SESSION SET EVENTS'IMMEDIATE TRACE NAME SYSTEMSTATE LEVEL 8'; 

    Oracle will now create asystemstate tracefile in your USER_DUMP_DEST directory. 
    Get the PID (ProcessID) ofthe 'hanging' session from the V$PROCESS by matching  
    PADDR from V$SESSION withADDR from V$PROCESS: 

    SELECT PID FROM V$PROCESSWHERE ADDR= 
           (SELECT PADDR FROM V$SESSION WHERE SID=sid_of_hanging_session); 

    The systemstate dump containsa separate section with information for each  
    process. Open the tracefileand do a search for 'PROCESS pid_from_select_stmt'. 
    In the process section lookup the wait event by doing a search on 'waiting for'. 

    Example output: 

    PROCESS 8: 
      ---------------------------------------- 
       SO: 50050b08,type: 1, owner: 0, flag: INIT/-/-/0x00 
       (process) Oraclepid=8, calls cur/top: 5007bf6c/5007bf6c, flag: (0) - 
                int error: 0, call error: 0, sess error: 0,txn error 0 
       (post info) lastpost received: 82 0 4 
                  last post received-location:kslpsr 
                  last process to post me: 5004ff081 2 
                  last post sent: 0 0 13 
                  last post sent-location: ksasnd 
                  last process posted by me:5004ff08 1 2 
        (latch info) wait_event=0 bits=0 
        Process Group: DEFAULT, pseudo proc: 50058ac4 
         O/Sinfo: user: daemon, term: pts/1, ospid: 15161 
         OSDpid info: 15161 
        ---------------------------------------- 
         SO:5005f294, type: 3, owner: 50050b08, flag: INIT/-/-/0x00 
        (session) trans: 0, creator: 50050b08, flag: (41) USR/-BSY/-/-/-/-/- 
                  DID: 0001-0008-00000002,short-term DID: 0000-0000-00000000 
                  txn branch: 0 
                  oct: 6, prv: 0, user: 41/LC 
         O/Sinfo: user: daemon, term: pts/1, ospid: 15160, machine: goblin.forgotten.realms 
                  program:
     sqlplus@goblin.forgotten.realms (TNS V1-V3) 
        application name: SQL*Plus, hash value=3669949024 
        waiting for 'library cache lock' blocking sess=0x0 seq=253wait_time=0  --等待事件,seq次数,
    !>>             handle address=5023ef9c, lockaddress=5019cad4, 10*mode+namespace=15 

    Using the 'handle address'you can look up the process that is keeping a lock 
    on your resource by doing asearch on the address within the same tracefile. 

    Example output:  

    PROCESS 9: 
      ---------------------------------------- 
       SO: 50050e08,type: 1, owner: 0, flag: INIT/-/-/0x00 
       (process) Oraclepid=9, calls cur/top: 5007bbac/5007bbfc, flag: (0) - 
                int error: 0, call error: 0, sess error: 0,txn error 0 
      
       <cut> .... 
       
           ---------------------------------------- 
            SO: 5019d5e4, type: 34, owner: 5015f65c, flag: INIT/-/-/0x00 
    !>>     LIBRARY OBJECT PIN: pin=5019d5e4 handle=5023ef9c mode=Xlock=0  --handle address
            user=5005fad4 session=5005fad4 count=1 mask=0511savepoint=118218 flags=[00] 
       
    From the output we can seethat the Oracle process with PID 9 has an exclusive 
    lock on the object we aretrying to access. Using V$PROCESS and V$SESSION we can 
    retrieve thesid,user,terminal,program,... for this process. The actual statement 
    that was launched by thissession is also listed in the tracefile (statements and 
    other library cache objectsare preceded by 'name='). 


    METHOD 2: EXAMINE THE X$KGLLKTABLE 
    ----------------------------------- 

    The X$KGLLK table (accessibleonly as SYS/INTERNAL) contains all the  
    library object locks (bothheld & requested) for all sessions and 
    is more complete than theV$LOCK view although the column names don't 
    always reveal their meaning. 

    You can examine the locksrequested (and held) by the waiting session  
    by looking up the sessionaddress (SADDR) in V$SESSION and doing the  
    following select: 

    select * from x$kgllk whereKGLLKSES = 'saddr_from_v$session' 

    This will show you all thelibrary locks held by this session where 
    KGLNAOBJ contains the first80 characters of the name of the object. 
    The value in KGLLKHDLcorresponds with the 'handle address' of the 
    object in METHOD 1. 

    You will see that at leastone lock for the session has KGLLKREQ > 0  
    which means this is a REQUESTfor a lock (thus, the session is waiting).  
    If we now match the KGLLKHDLwith the handles of other sessions in  
    X$KGLLK that should give usthe address of the blocking session since 
    KGLLKREQ=0 for this session,meaning it HAS the lock. 
      
    SELECT * FROM X$KGLLKLOCK_A  
    WHERE KGLLKREQ = 0 
       AND EXISTS(SELECT LOCK_B.KGLLKHDL FROM X$KGLLK LOCK_B 
                  WHERE KGLLKSES ='saddr_from_v$session' /* BLOCKED SESSION */ 
                  AND LOCK_A.KGLLKHDL =LOCK_B.KGLLKHDL 
                  AND KGLLKREQ > 0); 

    If we look a bit further wecan then again match KGLLKSES with SADDR  
    in v$session to find furtherinformation on the blocking session: 

    SELECTSID,USERNAME,TERMINAL,PROGRAM FROM V$SESSION 
    WHERE SADDR in  
      (SELECT KGLLKSESFROM X$KGLLK LOCK_A  
       WHERE KGLLKREQ =0 
         ANDEXISTS (SELECT LOCK_B.KGLLKHDL FROM X$KGLLK LOCK_B 
                    WHERE KGLLKSES ='saddr_from_v$session' /* BLOCKED SESSION */ 
                    AND LOCK_A.KGLLKHDL =LOCK_B.KGLLKHDL 
                    AND KGLLKREQ > 0) 
      ); 

    In the same way we can alsofind all the blocked sessions: 

    SELECTSID,USERNAME,TERMINAL,PROGRAM FROM V$SESSION 
    WHERE SADDR in  
      (SELECT KGLLKSESFROM X$KGLLK LOCK_A  
       WHERE KGLLKREQ> 0 
         ANDEXISTS (SELECT LOCK_B.KGLLKHDL FROM X$KGLLK LOCK_B 
                    WHERE KGLLKSES ='saddr_from_v$session' /* BLOCKING SESSION */ 
                    AND LOCK_A.KGLLKHDL =LOCK_B.KGLLKHDL 
                    AND KGLLKREQ = 0) 
      );
     

     

     

    ---本文是网络资料加metalink 等整理得来

  • 相关阅读:
    vue 仿IOS 滚轮选择器
    一道题目学ES6 API,合并对象id相同的两个数组对象
    Express中间件原理详解
    webpack原理与实战
    LS522 体积小低电压低成本的13.56MHz非接触式读写卡芯片,集成了在13.56MHz下所有类型的被动非接触式通信方式和协议,支持ISO14443A/B的多层应用( PIN对PIN MFRC522 )
    SP213EEA-L/TR +5V高性能RS232收发器
    多速率SDI集成接收器 SDI解码芯片 GS2971A-IBE3
    低电容3.3V TVS管 R CLAMP3304N.TCT
    高ESD耐压/TVS二极管 UCLAMP2804L.TCT
    高性能正电压稳压管SC4215HSETRT
  • 原文地址:https://www.cnblogs.com/hllnj2008/p/4788066.html
Copyright © 2011-2022 走看看