清理session的小插曲(二)

jeanron100發表於2015-07-21
在上週巡檢系統的時候發現session列表中顯示有一個session的狀態為“KILLED",當時沒有太在意,等到週一回來做檢查的時候,發現那個session的狀態還是為KILLED.
這肯定是個問題,我們來看看這個session的情況。從v$session裡可以看出這個session最早是在7月8日初始化的。

SQL>  select sid,serial#,status,logon_time ,paddr from v$session where status='KILLED';
       SID    SERIAL# STATUS           LOGON_TIME          PADDR
---------- ---------- ---------------- ------------------- ----------------
       979      64731 KILLED           2015-07-08 17:51:23 000000174114A1D8
檢視一些客戶端的明細資訊,可以看到,是透過sqlplus直接連過來的,從客戶端資訊來看是一個監控客戶端。
USERNAME             PROGRAM                                            OSUSER               MACHINE              STATUS                  SID
-------------------- -------------------------------------------------- -------------------- -------------------- ---------------- ----------
MIN_BG      sqlplus@xxxxxx (TNS V1-V3)                     xxxxx                   xxxxxxxxxx           KILLED                  979
這個時候嘗試去看看這個session在killed的時候正在執行什麼sql語句。沒有任何資訊。       
select sql_id from v$session where paddr='000000174114A1D8' and sql_id is not null 

好了問題的情況就是這樣,之前也分享過幾篇關於kill session的博文,比如http://blog.itpub.net/23718752/viewspace-1485804/
那個問題是透過檢視作業系統程式來檢視對應的session資訊。
這個問題不太一樣,因為我們只知道session的資訊,需要找到繫結的作業系統程式。
有一個思路可以參考,我們根據作業系統程式的初始化時間來檢視7月8日的資料相關程式。發現只有2個。這對我們分析問題的範圍來說就更小了。
$ ps -ef|grep Jul08
oracle     781     1  0 Jul08 ?        00:00:00 oracletlbb3dbi (LOCAL=NO)
oracle   12172 10679  0 10:29 pts/0    00:00:00 grep Jul08
oracle   36470     1  0 Jul08 ?        00:00:00 oracletlbb3dbi (LOCAL=NO)
所以這兩個程式中應該有一個就是需要清理的程式。
我們看看781這個程式。可以看到v$session裡的paddr和v$process裡的addr還是完全對應的,證明這個session是沒有問題的。
$ ksh showpid.sh 781
*******************************************
Process has found, pid: 781  ,  addr: 00000017310538B8    
####### Process Information from OS level as below ########
oracle     781     1  0 Jul08 ?        00:00:00 oraclexxxxx (LOCAL=NO)
oracle    5781     1  0 Jun29 ?        00:00:30 oraclexxxxx (LOCAL=NO)
oracle   12210 10679  0 10:29 pts/0    00:00:00 ksh showpid.sh 781
##############################################
       SID    SERIAL# USERNAME        OSUSER          MACHINE              PROCESS         TERMINAL        TYPE
---------- ---------- --------------- --------------- -------------------- --------------- --------------- --------------------
LOGIN_TIME
--------------------------------------
      1409      27981 MIN_BG xxxxx xxxxxxxx           20646           pts/26          USER
2015-07-08 14:58:29
PREV_SQL_ID                    SQL_TEXT
------------------------------ ------------------------------------------------------------
548447mzsjars                  select * from v$version
那麼問題就到了第二個session,透過地址對映找不到對應的程式。
$ ksh showpid.sh 36470
*******************************************
Process has found, pid: 36470  ,  addr: 00000017410A2318    
####### Process Information from OS level as below ########
oracle   12251 10679  0 10:29 pts/0    00:00:00 ksh showpid.sh 36470
oracle   36470     1  0 Jul08 ?        00:00:00 oraclexxxxxx (LOCAL=NO)
##############################################
no rows selected
no rows selected

我們手工來理一下這個問題。首先我們知道作業系統級程式,程式號為36470,對應的地址資訊為:
SQL> select addr from v$process where spid=36470;
ADDR
----------------
00000017410A2318
我們根據這個地址資訊在v$session沒有任何收穫,所以從v$session對映v$process還是從v$process對映v$session都是斷開的鏈條。
SQL> select sid,serial#,username from v$session where paddr='00000017410A2318';
no rows selected
可以基本斷定36470這個程式就是存在問題的程式。
簡單和同事進行了確認,然後在作業系統級清理了這個程式。
kill -9 36470
隔了一會,再次檢視session,原來顯示KILLED狀態的session就自動消失了。
$ ps -ef|grep Jul08
oracle     781     1  0 Jul08 ?        00:00:00 oraclexxxxxx (LOCAL=NO)
oracle   15481 10679  0 10:39 pts/0    00:00:00 grep Jul08
透過這個案例可以看出,我們在清理這種程式的時候還是省了不少事情,從作業系統程式的初始化時間縮小了問題分析的範圍。然後也是逐個排查,正向反向進行印證,可以基本斷定這個存在問題的程式。
所以作為問題總結,還是建議在刪除session的時候還是最好先標示一下繫結的作業系統程式,這樣就給事後的處理帶來很多的便捷。

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

相關文章