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