Kill會話過程分析
在實際開發中,我們常常需要將使用者的會話強制斷開。比如:事務執行超時、程式碼出現死迴圈、死鎖或者無意中將資料表鎖住。這個使用kill session是很實用的方法。那麼,kill session的時候,系統究竟發生了什麼呢?
基礎知識
使用者連線到資料庫,涉及到幾個物件。首先是監聽器,我們常常使用的本地命名服務(tnsname.ora),實際上連線的就是監聽器。但是,對於我們連線過程來說,與監聽器打交道的時間還是很短暫的(詳細可以見筆者其他討論監聽器和連線的文章)。其次是Server Process,是客戶端應用在資料庫伺服器上的操作代表。所有對於資料庫例項、資料檔案和SGA的操作,實際執行都是Server Process來進行的。最後就是以PMON為代表的後臺程式(影子程式),他們負責管理例項的方方面面,保證各方面職能正確實現。
另一個邏輯層次上,使用者會話session是一個重要概念。在特定的情況下,我們可以說使用者與資料庫的互動,就是在一個持續的session中完成。在一個session中,使用者可以執行多個事務,可以處在閒置狀態(Inactive)。
在任何情況下,如果我們強制性的斷開連線,放開session(主動)。PMON後臺程式會主動的做回收處理工作(在繁忙的時候存在延時)。回收包括清理會話資訊,回滾未提交事務,釋放Server Process資源(專用模式下)。
在一些時候,我們可以藉助alter system kill session ‘sid, serial#’; 來手工強制斷開使用者連線。那麼,Oracle進行kill的時候,究竟發生了什麼呢?讓我一起來研究。
實驗環境構建
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
Connected as SYS
//檢視元件版本:使用SYS登入
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
首先,為了簡便,筆者啟動了PL/SQL Developer,並且開啟一個Command視窗。之後,啟動一個sqlplus視窗,觀察這個視窗對應的會話情況。
在sqlplus視窗中。
SQL> conn scott/tiger@wilson
已連線。
觀察會話情況,查詢v$session。
SQL> select saddr, sid, serial#, paddr, username, program,action,status from v$session where username in ('SYS','SCOTT');
SADDR SID SERIAL# PADDR USERNAME PROGRAM ACTION STATUS
-------- ----- ---------- -------- ---------- --------------- --------------- --------
382F0074 1 64 38BC6C94 SCOTT sqlplusw.exe INACTIVE
382B30C0 24 80 38BC61BC SYS plsqldev.exe Main session INACTIVE
3829B2F4 33 10 38BC8244 SYS plsqldev.exe Command Window ACTIVE
- New
可以發現,會話中多了三個session。兩個使用者名稱SYS的會話是PL/SQL Developer開啟的(原理見之前部落格內容)。另一個SCOTT使用者開啟的sqlplusw.exe是我們的實驗物件,發現其sid=1,Serial#=64。會話對應的Server Process實體地址為38BC6C94。
之後,我們查詢的對應的server Process資訊,從v$process。
SQL> select addr,pid,spid,username,serial#,program from v$process where addr='38BC6C94';
ADDR PID SPID USERNAME SERIAL# PROGRAM
-------- ---------- ------------------------ ---------- ---------- -------------------------
38BC6C94 25 5803 oracle 23 oracle@oracle11g
我們可以看出,Scott使用者會話SID=1對應的Server Process,程式編號為5803(PID為Oracle相關程式的內部編號,SPID表示的是作業系統級別)。
最後,我們檢視作業系統級別程式資訊。
[oracle@oracle11g ~]$ ps -ef | grep LOCAL
oracle 5780 1 0 05:47 ? 00:00:03 oraclewilson (LOCAL=NO)
oracle 5788 1 0 05:48 ? 00:00:00 oraclewilson (LOCAL=NO)
oracle 5803 1 0 05:50 ? 00:00:00 oraclewilson (LOCAL=NO) //對於的那個Server Process
實驗kill會話。
在觀察PL/SQL Developer裡,將SCOTT會話斷開。
SQL> alter system kill session '1,64';
System altered
Kill操作執行完成,沒有報錯。那麼,這個會話資訊真的被刪除了嗎?我們重新檢查v$session。
//發現,會話SCOTT(SID=1, Serial#=64 資訊還存在)
SQL> select saddr, sid, serial#, paddr, username, program,action,status from v$session where username in ('SCOTT');
SADDR SID SERIAL# PADDR USERNAME PROGRAM ACTION STATUS
-------- ----- ---------- -------- ---------- ------------------------- --------------- --------
382F0074 1 64 38058594 SCOTT sqlplusw.exe KILLED
//按照原來的Server Process地址查詢Server Process資訊還存在;
SQL> select addr,pid,spid,username,serial#,program from v$process where addr='38BC6C94';
ADDR PID SPID USERNAME SERIAL# PROGRAM
-------- ---------- ------------------------ ---------- ---------- -------------------------
38BC6C94 25 5803 oracle 23 oracle@oracle11g
“怪事”發生了,我們kill掉了會話。但是會話資訊還存在,與剛才的結果區別是兩個:其一為會話的狀態變為了KILLED狀態,表示已經被kill。其二是對應Server Process的地址被修改,該到了38058594的位置上。
而檢視v$process程式檢視,發現原來為其服務的Server Process資訊仍然存在!那麼,是真的存在嗎?我們檢視作業系統層面:
[oracle@oracle11g ~]$ ps -ef | grep LOCAL
oracle 5780 1 0 05:47 ? 00:00:03 oraclewilson (LOCAL=NO)
oracle 5788 1 0 05:48 ? 00:00:00 oraclewilson (LOCAL=NO)
oracle 5803 1 0 05:50 ? 00:00:00 oraclewilson (LOCAL=NO)
看來Server Process確實存在。那麼這個新Server Process地址38058594是什麼呢?
SQL> select addr,pid,spid,username,serial#,program from v$process where addr='38058594';
ADDR PID SPID USERNAME SERIAL# PROGRAM
-------- ---------- ------------------------ ---------- ---------- -------------------------
綜合上述:在kill的時候,Oracle做了兩件事。一件是將會話的狀態修改了KILLED,相當於打了一個標記。第二件是透過將會話對應的Server Process地址修改為一個虛擬地址,切斷會話資訊與Server Process的對映關聯。此外,Server Process並沒有回收。
等待一會之後,發現依然如此!沒有PMON主動的回收動作。
那麼,如果此時被kill掉的會話發起一個操作,如何?
在sqlplus上:
SQL> select * from emp;
select * from emp
*
第 1 行出現錯誤:
ORA-00028: 您的會話己被終止
被斷開的會話拒絕操作,告知說會話已經被終止。
此時,系統還能檢視到這個會話資訊嗎?
SQL> select saddr, sid, serial#, paddr, username, program,action,status from v$session where username in ('SCOTT');
SADDR SID SERIAL# PADDR USERNAME PROGRAM ACTION STATUS
-------- ----- ---------- -------- ---------- ------------------------- --------------- --------
SQL> select addr,pid,spid,username,serial#,program from v$process where addr='38BC6C94';
ADDR PID SPID USERNAME SERIAL# PROGRAM
-------- ---------- ------------------------ ---------- ---------- -------------------------
38BC6C94 25 5803 oracle 23 oracle@oracle11g
結論:當我們在原有視窗執行操作,嘗試會話通訊時,被拒絕。透過檢視查詢,發現原有被kill的會話資訊被回收。但是Server Process還存在在檢視上,但不與任何會話對應。
那作業系統層面上:
[oracle@oracle11g ~]$ ps -ef | grep LOCAL
oracle 5780 1 0 05:47 ? 00:00:03 oraclewilson (LOCAL=NO)
oracle 5788 1 0 05:48 ? 00:00:00 oraclewilson (LOCAL=NO)
oracle 5803 1 0 05:50 ? 00:00:00 oraclewilson (LOCAL=NO)
該Server Process還存在,沒有回收。
注意:當我們關閉掉sqlplusw視窗之後,也就是我們關掉客戶端的時候,我們再次查詢發現:
[oracle@oracle11g ~]$ ps -ef | grep LOCAL
oracle 5780 1 0 05:47 ? 00:00:03 oraclewilson (LOCAL=NO)
oracle 5788 1 0 05:48 ? 00:00:00 oraclewilson (LOCAL=NO)
Server Process被回收,v$process自然也應當沒有對應記錄存在了。
SQL> select addr,pid,spid,username,serial#,program from v$process where addr='38BC6C94';
ADDR PID SPID USERNAME SERIAL# PROGRAM
-------- ---------- ------------------------ ---------- ---------- -------------------------
38BC6C94 25 5956 oracle 26 oracle@oracle11g (J000)
誒,為什麼有記錄呢?仔細看看:SPID已經發生變化,不是5803,而是5956,是一個新啟動的程式。只是使用了剛剛被釋放的地址。
結論:駐留在資料庫伺服器的Server Process會一直存在,直到客戶端應用斷開連線,不在於Server Process通訊。注意,這時如何客戶端重新連線conn,客戶端是重新與監聽器溝通,獲取一個新的Server Process重定向,不會找過去的那個舊Server Process。一旦重新登入,舊的Server Process就會被回收釋放掉。
綜上所述:在kill研究中,我們搞清楚了幾個方面問題:
1、 alter system kill session:只是將session標記為可以回收,切斷會話與Server Process的對映關係。沒有進行資源釋放回收工作;
2、 一旦嘗試連線,PMON會主動開始清理被kill的會話,同時Oracle拒絕連線操作;
3、 Server Process是一個忠實於客戶端的程式,只要客戶端還在啟動,維持著兩個之間的聯絡。Server Process是不會被回收的。直到客戶端主動停止與Server Process的通訊,Server Process釋放;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-683786/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Kill會話過程分析(二)會話
- 【會話】Oracle kill session系列會話OracleSession
- HTTPS會話過程整理HTTP會話
- MySQL kill會話不起作用?MySql會話
- MySQL: kill 會話的實現原理MySql會話
- Oracle kill會話--sed修改檔案Oracle會話
- oracledebug hanganalyze分析會話等待及儲存過程hangOracle會話儲存過程
- ORACLE快速徹底Kill掉的會話Oracle會話
- kill執行時間較長的會話會話
- 批量kill殺死某些會話session的plsql會話SessionSQL
- ssl會話建立的過程(原理)是什麼?會話
- 更改SERVICE_NAME導致大量會話被KILL會話
- Kill session 和orakill 殺會話及程式總結Session會話
- ORA-00031: 標記要刪去的會話,但會話kill不掉解決辦法會話
- 遭遇cursor:pin x等待事件定位阻塞會話診斷過程事件會話
- hanganalyze分析會話阻塞會話
- 網路螞蟻--會話命令--全過程監控--詳錄 (轉)會話
- 大話Oracle中的kill sessionOracleSession
- Web會話安全分析工具ProxyStrikeWeb會話
- oracle如何徹底kill掉會話及os作業系統資源Oracle會話作業系統
- HDFS寫過程分析
- 資料庫會話數量過多,定期清理inactive會話資料庫會話
- Windows啟動過程(MBR引導過程分析)Windows
- SQLServer會話KILL不掉,一直處於KILLED/ROLLBACK狀態情形淺析SQLServer會話
- 使用 Tinx 過載 Laravel Tinker 會話Laravel會話
- 資料需求分析過程
- 頁面渲染:過程分析
- ORACLE 死鎖分析過程Oracle
- Spark計算過程分析Spark
- Service啟動過程分析
- Activity啟動過程分析
- sql執行過程分析SQL
- 資料分析過程六步曲—誰說菜鳥不會資料分析
- 解決超過會話數問題會話
- -t【Oracle-故障管理】-Trace跟蹤會話和會話執行慢故障分析Oracle會話
- ORA-00031:session marked for kill(標記要終止的會話)解決方法Session會話
- 【DSL】Elasticsearch之Analyze(分析過程)Elasticsearch
- Liferay 啟動過程分析