1. 程式人生 > 其它 >清理session的小插曲(二) (r6筆記第4天)

清理session的小插曲(二) (r6筆記第4天)

在上週巡檢系統的時候發現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的時候還是最好先標示一下繫結的作業系統程序,這樣就給事後的處理帶來很多的便捷。