常用定位library cache lock的方法

hunterjoy發表於2010-09-17

今天上午又碰到客戶提出的問題,查詢機上顯示有很多library cache bin和library cache lock的等待事件,而且重新整理DJ_NSRXX表(主要的業務大表)時就提示唯一性約束錯誤。

在網上搜了不少帖子參考,以下這個帖子不錯

來自:http://www.itpub.net/thread-915008-1-4.html

謝謝PUBER的貢獻

 

我的常用定位library cache lock的方法,希望對大家有用

經常看到PUB上有兄弟說什麼LIBRARY CACHE LOCK和PIN的錯誤不知道該如何處理,而且定位不到問題出在哪裡,我來說幾句吧,以我工作上的經驗,希望能對大家有用
   一般來說,這類錯誤是因為在包或過程被頻繁呼叫的過程中,DDL語句引起的,那我們該怎麼處理呢?其實我們可以這樣來操作來查原因,老闆要的一般都是為什麼產生這個故障和誰操作導致的這個故障,特別是故障處理好後,這個問題就要回答老闆了。

1、預先在資料庫中建立DDL級的觸發器,我認為這個是必要的,因為這個對生產影響不大,但是卻可以讓我們監控到不少有用的資訊.,比如記錄在abc表中,可以記錄登陸使用者,操作語句,操作時間等等資訊。

  2、在資料庫中出現大量的libriary cache lock 的等待事件的時候,系統出現嚴重的問題了,我們可以立即從這個時間點左右著手,比如12日21日中午12點到12點半之間出問題,如下語句
select * from dba_objects where
last_ddl_time>to_date('20071221 12:00:00','yyyymmdd hh24:mi:ss')
AND last_ddl_time<=to_date('200712 12:30:00','yyyymmdd hh24:mi:ss')
and (object_type like '%PACK%' or object_type like 'FUNCTION' OR object_type='PROCEDURE')
AND STATUS='INVALID'
order by last_ddl_time desc

其實透過這個基本上就發現是什麼問題了,基本上就只會有一兩個物件比如包BBB失效

3、然後找包關聯的物件,是否在我們的觸發器記錄的表中有記錄,接著執行如下語句(切記,這個記錄DDL動作的語句發揮作用了)

select * from abc where ddl_time>to_date('20071221 12:00:00','yyyymmdd hh24:mi:ss')
AND ddl_time<=to_date('200712 12:30:00','yyyymmdd hh24:mi:ss')
and schema_object in (SELECT referenced_name FROM DBA_DEPENDENCIES WHERE NAME='BBB' )
ORDER BY DDL_time desc
(請注意,這個BBB就是上面我查出來的,舉例說比如失效的包)

這樣查出來的,絕對就是引起這次事故的罪魁禍首的動作了。(ddl_time和 schema_object 是abc表的欄位,記錄了登陸者操作DDL的時間和物件)


以上方式是我在工作中經常採用的,很好用,一般不會有問題。


當然我上面並沒有說明解決問題的方法,解決問題的方法是如下。但是有的時候發現問題原因,追究問題原因是非常非常重要的,可以避免下次再發生,當然透過DUMP systemstate等方式,比較複雜,我的這個思路操作起來應該比較簡便,很明瞭。另外,建立DDL級的觸發器,個人認為是必須的!所以上面的方法我想說出來,希望對大家有用!


解決問題的方法步驟

  1、檢視具體產生library cache lock 的物件,比如不哪些包和儲存過程
Note: X$KGLOB--[K]ernel [G]eneric [L]ibrary Cache Manager [OB]ject

SELECT KGLNAOWN,KGLNAOBJ
    FROM x$kglob
   WHERE kglhdadr in( select P1RAW from v$session_wait where event like 'library cache%');

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

2、  檢視具體是那些使用者做了這個操作導致 library cache lock
  select sid, program ,machine from v$session where paddr in (
       SELECT s.paddr
        FROM x$kglpn p, v$session s
       WHERE p.kglpnuse=s.saddr(+) AND p.kglpnmod <> 0
   and kglpnhdl in ( select p1raw  from v$session_wait where event  in ('library cache pin','library cache lock' ,'library cache load lock')  )        );


3、、以下語句用來殺掉會話(前面檢視,然後到這步是決定是否要殺掉程式解決這個問題)
select 'kill -9 '||spid from v$process where addr in (
       SELECT s.paddr
        FROM x$kglpn p, v$session s
       WHERE p.kglpnuse=s.saddr --AND p.kglpnmod <> 0
   and kglpnhdl in ( select p1raw  from v$session_wait where event  in (' library cache pin','library cache lock' )  )        );



附:DDL觸發器的語句

CREATE OR REPLACE TRIGGER tr_trace_ddl
AFTER ddl
ON database
DECLARE
  SQL_TEXT   ORA_NAME_LIST_T;
  STATE_SQL  VARCHAR2(4000); --DDL$TRACE.DDL_SQL%TYPE;
  V_ERR_INFO VARCHAR2(200);
BEGIN
  FOR I IN 1 .. ORA_SQL_TXT(SQL_TEXT) LOOP
    STATE_SQL := STATE_SQL || SQL_TEXT(I);
  END LOOP;

  INSERT INTO SYSTEM.ABC
    (LOGIN_USER,
     AUDSID,
     IPADDRESS,
     SCHEMA_USER,
     SCHEMA_OBJECT,
     DDL_TIME,
     DDL_SQL)
  VALUES
    (ORA_LOGIN_USER,
     USERENV('SESSIONID'),
     SYS_CONTEXT('userenv', 'ip_address'),
     ORA_DICT_OBJ_OWNER,
     ORA_DICT_OBJ_NAME,
     SYSDATE,
     STATE_SQL);
EXCEPTION
  WHEN OTHERS THEN
    V_ERR_INFO := SUBSTRB(SQLERRM, 1, 198);
END TR_TRACE_DDL;
參考:
WAITEVENT: "library cache pin" Reference Note [ID 34579.1]
HOW TO FIND THE SESSION HOLDING A LIBRARY CACHE LOCK [ID 122793.1]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/543979/viewspace-674268/,如需轉載,請註明出處,否則將追究法律責任。

相關文章