日常運維之TX鎖處理(二)

jason_yehua發表於2022-11-30

想必大家都遇到過在資料庫層面發起“alter system kill session  ”(資料庫層殺掉會話,不加immediate  關鍵字)時,經常出現資源無法及時釋放、會話一直處於killed  狀態的情況。如果這個會話是鎖的源頭,那麼除了等待PMON  (程式監視器)來清理之外,沒有更好的辦法了,而在作業系統層面殺掉程式的方式,基本上是百試百靈。使用系統命令“kill -9  ”殺死程式,系統向該process  程式發出sigkill  sigkill  訊號直接傳送給init  程式,終止process  程式。這種方式直接終止了Oracle  會話中對應的操作程式,資源也可以直接釋放。

”的過程,以及為何“alter system kill session  ”殺掉會話之後,查不到處於killed  狀態的會話所對應的系統程式spid 

alter system kill session    (不加immediate  關鍵字)殺掉會話可針對兩種場景進行討論:一是會話狀態是active  ,二是會話狀態是inactive  。使用此命令殺掉處於active  狀態的會話時,過程可以簡單概括如下:會話在收到kill  訊號後進行回滾,此過程不可被中斷,直至過程完成,該會話會接收到 ORA-00028: your session has been killed  ”資訊  PMON  清理會話,釋放資源。如果分鐘過後,上述動作未完成,則該會話被標記為killed  狀態,若會話擁有的資源未釋放 PMON  程式清理會話。  使用此命令殺掉處於inactive  狀態的會話時,過程可以簡單概括如下:會話在收到kill  訊號後被標記為killed  狀態,會話擁有的資源未釋放,等待PMON  程式清理會話。如果會話再次發出查詢訊號,會話就會接收到“ORA-00028: your session has been killed  ”資訊,PMON  清理會話,釋放資源。

接下來模擬不加immediate  引數,殺掉會話後狀態被標記為killed  ,作業系統查不到程式的實驗,過程如下:

SQL> select username,sid,serial#,paddr,server,status from v$session where username = 'SCOTT';

 

USERNAME     SID    SERIAL#  PADDR            SERVER    STATUS

---------- ----- ---------- ---------------- --------- --------

SCOTT         17       6733  00000000A34C7040 DEDICATED INACTIVE

SCOTT        158       9177  00000000A34D4998 DEDICATED INACTIVE

 

SQL> select b.sid,b.serial#,c.spid,b.status from v$session b,v$process c where b.paddr = c.addr and b.sid in (17,158);

   SID    SERIAL# SPID      STATUS

---- ---------- --------- --------

   17       6733 23883     INACTIVE

   158       9177 24120     INACTIVE

手動殺掉這兩個會話的命令如下:

SQL>  alter system kill session '17,6733';

SQL>  alter system kill session '158,9177';

再次查詢這兩個會話的狀態,命令及結果如下:

SQL> select username,sid,serial#,paddr,server,status from v$session where username = 'SCOTT';

USERNAME    SID    SERIAL#  PADDR            SERVER    STATUS

---------- ---- ---------- ---------------- --------- --------

SCOTT        17       6733  00000000A3551F18 PSEUDO     KILLED

SCOTT       158       9177  00000000A3551F18 PSEUDO     KILLED

從程式碼中我們可以發現,當兩個會話的狀態為killed  時,會話的paddr  指向同一地址00000000A3551F18  (虛擬地址),此地址在作業系統層面並無對應的spid  ,這就是當會話的狀態變為killed  之後,使用以下語句查不到spid  的原因,查詢示例程式碼如下所示:

SQL>  select b.sid,b.serial#,c.spid,b.status from v$session b,v$process c where b.paddr = c.addr and b.sid in (17,158);

no rows selected

此時我們就可以使用前文的查詢語句,查殺並清理會話,  命令及結果如下:

SQL> select 'alter system kill session ''' || c.sid || '' || ',' || c.serial# || ''' immediate;' kill_session from v$session c where status='KILLED';

KILL_SESSION

-----------------------------------------------

alter system kill session '17,6733' immediate;

alter system kill session '158,9177' immediate;

因此,在查殺會話時,可以考慮直接使用“alter system kill session 'sid,serial#' immediate  ”命令快速清理會話。需要注意的是,在查殺會話之前一定要再三確認資訊,千萬不要誤殺了系統核心程式。



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

相關文章