2012年3月8日 星期四

oracle kill Session 後依舊占用資源

最近公司的 oracle 生意太好常常滿線,但實際上線的人數跟資料庫上所查詢
到的人數是有落差的。也就是說資料庫所查詢到的人數遠大於實際上線的
人數。會造成這樣的現象是有些 session 沒正常結束或是程式執行到一半當機
等其他原因導致應用程式已經結束執行,但是連線到 oracle 的 session 還是
繼續存在。它也不會自己離開,時間一久越積越多這樣的 session 在資料庫裏面 。
占用到系統資源,以至於造成可用的連線數愈來越少。
如何查詢久佔資源的 sessions ?
以這次公司所發生的 oralce 系統為例 :
SQL 語法 :
select SID, OSUSER, USERNAME, MACHINE, STATUS, LOGON_TIME
from V$SESION;
執行結果 , 如下 :
其中有個 seesion SID 239 跟下面一個 session SID 240 相比已經快一個多月
還在系統上。很明顯這個就是(失聯)可以 kill 的 session。

刪除 session 指令 :
alter system kill session 'SID,SERIAL#' ;
or
alter system disconnect session 'SID,SERIAL#';
PS : 另外可以在最後加上參數 immediate 表立刻刪除。
       不過好像沒什麼實際用途
圖例 :


這時 session 的 STATUS 會變成 KILLED 的狀態 

如下圖 :
這狀態會一直持續到非常久,等到天荒地老也等不到它斷線。重啟資料庫
會是最快的方式。但資料庫是又不是可以隨時可以讓你要關就關要開就開。
但是這些 session 它又占住資源讓後面要使用資料庫的新 session 因滿線無法
再進入。
這時可以利用下列方式把狀態為 KILLED 的 session 徹底的刪除 。

指令 :
在 windows 作業系統上可以使用 orakill 指令
在 UNIX 作業系統可以用 kill 指令
WINDOWS : orakill SID SPID ( SID 為oracle 的 SID)
UNIX : kill -9 SPID

下面以 WINDOIWS 指令為例 :
A : 首先要先找出 sesssion 的 SPID,這樣才可以利用 orakill 來下指令。
當執行了 alter system kill session 的指令後,session 的狀態欄位( STATUS)
會變成 KILLED,其 session 會被移置另一個的地方,這時要用 V$PROCESS
這個 view 來查詢 session 的 addr。
下列指令會列出所有狀態是 KILLED 之 session 的 addr 資料。

指令 :
select p.addr from v$process p where pid<>1
minus
select s.paddr from v$session s
執行結果如下圖:


然後利用下列指令去找出 session 的 SPID 值

指令 :
select addr, pid, spid from v$process where addr='xxxxx'

執行結果如下圖 :
這時候就知道 session 的 SPID 值。這時就可以利用 orakill 直接把連線給宰了。
如下圖 :
PS : SID 指的是 oracle 的 SID 值
這時再去查詢 stataus 是 KILLED 的 session 就有顯著的下降。

執行 orakill 前









執行 orakill 後