溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Oracle 徹底 kill session的示例分析

發(fā)布時(shí)間:2021-11-05 10:12:48 來源:億速云 閱讀:230 作者:柒染 欄目:建站服務(wù)器

這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)Oracle 徹底 kill session的示例分析,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

Oracle 徹底 kill session

 killsessionDBA經(jīng)常碰到的事情之一。如果kill掉了不該killsession,則具有破壞性,因此盡可能的避免這樣的錯誤發(fā)生。同時(shí)也應(yīng)當(dāng)注意,

如果killsession屬于Oracle后臺進(jìn)程,則容易導(dǎo)致數(shù)據(jù)庫實(shí)例宕機(jī)。

 通常情況下,并不需要從操作系統(tǒng)級別殺掉Oracle會話進(jìn)程,但并非總是如此,下面的描述中給出了在Oracle級別殺掉會話以及操作系統(tǒng)級別殺掉進(jìn)程。

 

 

一、獲得需要kill session的信息(使用V$SESSIONGV$SESSION視圖)

 

 SETLINESIZE180

 COLUMNspid FORMAT A10

 COLUMNusername FORMAT A10

 COLUMNprogram FORMAT A40

 

 SELECTs.inst_id,

        s.sid,

        s.serial#,

        p.spid,

        s.username,

        s.program,

        s.paddr,

        s.STATUS

 FROM  gv$session s

        JOINgv$process pONp.addr = s.paddrANDp.inst_id = s.inst_id

 WHERE s.type !='BACKGROUND';

 

    INST_ID       SID   SERIAL# SPID      USERNAME  PROGRAM                                      PADDR   STATUS

 ---------- ---------- ---------- ---------- ---------- --------------------------------------------- -------- --------

          1       146        2327573     TEST      sqlplus@oracle10g (TNS V1-V3)                4C621950INACTIVE

          1       160        1727610     SYS       sqlplus@oracle10g (TNS V1-V3)                4C624174 ACTIVE

          1       144        4227641     SCOTT     sqlplus@oracle10g (TNS V1-V3)                4C624730INACTIVE

        

二、使用ALTERSYSTEMKILLSESSION命令實(shí)現(xiàn)

 語法:

     SQL>ALTERSYSTEMKILLSESSION'sid,serial#';

     SQL>ALTERSYSTEMKILLSESSION'sid,serial#'IMMEDIATE;

    

   對于RAC環(huán)境下的killsession,需要搞清楚需要killsession位于哪個節(jié)點(diǎn),可以查詢GV$SESSION視圖獲得。

   killsession的時(shí)候僅僅是將會話殺掉。在有些時(shí)候,由于較大的事務(wù)或需要運(yùn)行較長的SQL語句將導(dǎo)致需要killsession并不能立即殺掉。對于這種情

   況將收到"marked for kill"提示(如下),一旦會話當(dāng)前事務(wù)或操作完成,該會話被立即殺掉。

   

   altersystemkillsession'4730,39171'

   *

   ERRORatline1:

   ORA-00031:sessionmarkedforkill

 

 

 在下面的操作中將殺掉會話146144

   sys@AUSTIN>altersystemkillsession'146,23';

   

   Systemaltered.

   

   sys@AUSTIN>altersystemkillsession'144,42';

   

   Systemaltered.

   

   sys@AUSTIN>selectinst_id,saddr,sid,serial#,paddr,username,status,programfromgv$sessionwhereusernameisnotnull;

   

      INST_ID SADDR          SID   SERIAL# PADDR   USERNAME  STATUS  PROGRAM

   ---------- -------- ---------- ---------- -------- ---------- -------- ---------------------------------------------

            14C70BF04       144        424C6545A0SCOTT     KILLED  sqlplus@oracle10g (TNS V1-V3)

            14C70E6B4       146        234C6545A0TEST      KILLED  sqlplus@oracle10g (TNS V1-V3)

            14C71FC84       160        174C624174SYS       ACTIVE  sqlplus@oracle10g (TNS V1-V3)

                 

    注意:在查詢中可以看到被殺掉的會話的PADDR地址發(fā)生了變化,參照查詢結(jié)果中的紅色字體。如果多個sessionkill掉,則多個sessionPADDR

    被改為相同的進(jìn)程地址。

 

 通過下面的語句來找回被kill掉的ADDR先前的地址

   SELECTs.username,s.status,

   x.ADDR,x.KSLLAPSC,x.KSLLAPSN,x.KSLLASPO,x.KSLLID1R,x.KSLLRTYP,

   decode(bitand(x.ksuprflg,2),0,null,1)

   FROMx$ksupr x,v$session s

   WHEREs.paddr(+)=x.addr

   andbitand(ksspaflg,1)!=0;      

   

   USERNAME  STATUS  ADDR      KSLLAPSC  KSLLAPSN KSLLASPO      KSLLID1RKSD

   ---------- -------- -------- ---------- ---------- ------------ ---------- -- -

              ACTIVE  4C623BB8        99         427468              275EV1

              ACTIVE  4C623040         9        2427444                0   1

              ACTIVE  4C622A84       101         427480              274EV1

              ACTIVE  4C6224C8         1        4827450                0   1

              ACTIVE  4C621F0C         1        4827450                0   1

              ACTIVE  4C6235FC         2         427468                0   1

   SYS       ACTIVE  4C624174         2        1527442                0

              ACTIVE  4C62081C         1        4827440                0   1

              ACTIVE  4C621394         1        4827440                0   1

              ACTIVE  4C620DD8        11        2427476                0   1

              ACTIVE  4C61F6E8        15         427610                0   1

              ACTIVE  4C620260       222        2427450                0   1

              ACTIVE  4C61FCA4         7        2527573                0   1

              ACTIVE  4C61F12C         6        2527573                0   1

              ACTIVE  4C61EB70         4        2427458                0   1

              ACTIVE  4C61E5B4         1        4827440                0   1

              ACTIVE  4C61DFF8         2        2427444                0   1

                       4C624730         0         0                      0

                       4C621950         0         0                      0

                       4C61DA3C         0         0                      0

                   

 

 或者根據(jù)下面的語句來獲得發(fā)生變化的addr

   sys@AUSTIN>selectp.addrfromv$process pwherepid <>1

     2 minus

     3 selects.paddrfromv$session s;

   

   ADDR

   --------

   4C621950

   4C624730                   

 

三、在操作系統(tǒng)級別殺掉會話

 尋找會話對應(yīng)的操作系統(tǒng)的進(jìn)程ID

   sys@AUSTIN>selectSPIDfrom v$processwhereADDRin('4C621950','4C624730') ;        

   

   SPID

   ----------

   27573

   27641

   

 使用kill命令來殺掉操作系統(tǒng)級別進(jìn)程ID

   killsession-927573

   

   killsession-927641

 

四、獲得當(dāng)前會話的SID

 SQL>selectuserenv('sid')fromdual;

 

 USERENV('SID')

 --------------

            627

 

五、多個會話需要kill的處理辦法

 1.根據(jù)給定的SID(用戶名)查找需要?dú)⒌魰挼男畔?,包括位于哪一個實(shí)例

   setlinesize160

   col program format a35

   col username format a18

   selectinst_id,saddr,sid,serial#,paddr,username,status,programfromgv$session

   wheresidin('2731','2734','2720','2678','2685')

   andusername='CTICUST'

   orderbyinst_id;

   

      INST_ID SADDR                  SID   SERIAL# PADDR           USERNAME          STATUS  PROGRAM

   ---------- ---------------- ---------- ---------- ---------------- ------------------ -------- ---------------------------

            100000003DAF8F870      2678      826500000003DBC6CA08 MSS4USR           INACTIVE JDBC Thin Client

            100000003DAF98E48      2685        8300000003DBC08510 MSS4USR           ACTIVE  JDBC Thin Client

            100000003DAFC7B80      2720         500000003DBBEDA20 MSS4USR           INACTIVE JDBC Thin Client

            100000003DAFD66F8      2731         300000003DBBE9AE0SYS               ACTIVE racgimon@svdg0028(TNS V1-V3)

            100000003DAFDA730      2734        1500000003DBBEC268 MSS4USR           INACTIVE JDBC Thin Client

            200000003DAFD66F8      2731         100000003DBBE92F8                   ACTIVE  oracle@svdg0029 (ARC0)

   

   上面的查詢中有一個SID2731的位于節(jié)點(diǎn)2上。

   也可以通過下面的方式來獲得RAC的節(jié)點(diǎn)信息,便于確定需要killsession究竟位于哪一個節(jié)點(diǎn)。

   

     setlinesize160

     col HOST_NAME format a25

     SQL>selectINSTANCE_NUMBER,INSTANCE_NAME,HOST_NAME,VERSION,STATUSfromgv$instanceorderby1;

 

     INSTANCE_NUMBER INSTANCE_NAME   HOST_NAME                VERSION          STATUS

     --------------- ---------------- ------------------------- ----------------- ------------

                   1O02WMT1A        svd0051                 10.2.0.4.0       OPEN

                   2O02WMT1B        svd0052                 10.2.0.4.0       OPEN

                   3O02WMT1C        svd0053                 10.2.0.4.0       OPEN

                   

 2.使用下面查詢來生成killsession的語句

   select'alter system kill session '''||sid||','||SERIAL# ||''''||';' from gv$session

   wheresidin('2731','2734','2720','2678','2685')

   orderbyinst_id;

     

   獲得下列kill session的語句,根據(jù)要求由于此次需要?dú)⒌舻?span lang="EN-US">session全部位于節(jié)點(diǎn)1,因此登錄到節(jié)點(diǎn)節(jié)點(diǎn)1執(zhí)行下面的語句  

        

   altersystemkillsession'2678,8265';

   

   altersystemkillsession'2685,83';

   

   altersystemkillsession'2720,5'

   

   altersystemkillsession'2731,3';

    

   altersystemkillsession'2734,15';

    

   altersystemkillsession'2731,1';   --命令不需要執(zhí)行,session位于節(jié)點(diǎn)2。


★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

與Kill Session相關(guān)的其他幾篇文章

原文地址:http://www.eygle.com/archives/2004/06/kill_session.html

Oracle中Kill session的研究

作者:eygle | </SCRIPT. class=English target="_blank" href="http://translate.google.com/translate?langpair=zh-CN%7Cen&hl=zh-CN&ie=UTF8&u=http%3A//www.eygle.com/archives/2004/06/kill_session.html" English Version 【轉(zhuǎn)載時(shí)請以超鏈接形式標(biāo)明文章出處和作者信息及本聲明】
鏈接:http://www.eygle.com/archives/2004/06/kill_session.html

itpub link:

http://www.itpub.net/235873.html

我們知道,在Oracle數(shù)據(jù)庫中,可以通過kill session的方式來終止一個進(jìn)程,其基本語法結(jié)構(gòu)為:

alter system kill session 'sid,serial#' ;

被kill掉的session,狀態(tài)會被標(biāo)記為killed,Oracle會在該用戶下一次touch時(shí)清除該進(jìn)程.


我們發(fā)現(xiàn)當(dāng)一個session被kill掉以后,該session的paddr被修改,如果有多個session被kill,那么多個session
的paddr都被更改為相同的進(jìn)程地址:

SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null;

SADDR           SID    SERIAL# PADDR    USERNAME                       STATUS
-------- ---------- ---------- -------- ------------------------------ --------
542E0E6C         11        314 542B70E8 EYGLE                          INACTIVE
542E5044         18        662 542B6D38 SYS                            ACTIVE


SQL> alter system kill session '11,314';

System altered.

SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null;

SADDR           SID    SERIAL# PADDR    USERNAME                       STATUS
-------- ---------- ---------- -------- ------------------------------ --------
542E0E6C         11        314 542D6BD4 EYGLE                          KILLED
542E5044         18        662 542B6D38 SYS                            ACTIVE

SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null;

SADDR           SID    SERIAL# PADDR    USERNAME                       STATUS
-------- ---------- ---------- -------- ------------------------------ --------
542E0E6C         11        314 542D6BD4 EYGLE                          KILLED
542E2AA4         14        397 542B7498 EQSP                           INACTIVE
542E5044         18        662 542B6D38 SYS                            ACTIVE

SQL> alter system kill session '14,397';

System altered.

SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null;

SADDR           SID    SERIAL# PADDR    USERNAME                       STATUS
-------- ---------- ---------- -------- ------------------------------ --------
542E0E6C         11        314 542D6BD4 EYGLE                          KILLED
542E2AA4         14        397 542D6BD4 EQSP                           KILLED
542E5044         18        662 542B6D38 SYS                            ACTIVE

在這種情況下,很多時(shí)候,資源是無法釋放的,我們需要查詢spid,在操作系統(tǒng)級來kill這些進(jìn)程.

但是由于此時(shí)v$session.paddr已經(jīng)改變,我們無法通過v$session和v$process關(guān)聯(lián)來獲得spid

那還可以怎么辦呢?

我們來看一下下面的查詢:

  SQL> SELECT s.username,s.status,
  2  x.ADDR,x.KSLLAPSC,x.KSLLAPSN,x.KSLLASPO,x.KSLLID1R,x.KSLLRTYP,
  3  decode(bitand (x.ksuprflg,2),0,null,1)
  4  FROM x$ksupr x,v$session s
  5  WHERE s.paddr(+)=x.addr
  6  and bitand(ksspaflg,1)!=0;


USERNAME                       STATUS   ADDR       KSLLAPSC   KSLLAPSN KSLLASPO       KSLLID1R KS D
------------------------------ -------- -------- ---------- ---------- ------------ ---------- -- -
                                        542B44A8          0          0                       0
                               ACTIVE   542B4858          1         14 24069                 0    1
                               ACTIVE   542B4C08         26         16 15901                 0    1
                               ACTIVE   542B4FB8          7         46 24083                 0    1
                               ACTIVE   542B5368         12         15 24081                 0    1
                               ACTIVE   542B5718         15         46 24083                 0    1
                               ACTIVE   542B5AC8         79          4 15923                 0    1
                               ACTIVE   542B5E78         50         16 24085                 0    1
                               ACTIVE   542B6228        754         15 24081                 0    1
                               ACTIVE   542B65D8          1         14 24069                 0    1
                               ACTIVE   542B6988          2         30 14571                 0    1

USERNAME                       STATUS   ADDR       KSLLAPSC   KSLLAPSN KSLLASPO       KSLLID1R KS D
------------------------------ -------- -------- ---------- ---------- ------------ ---------- -- -
SYS                            ACTIVE   542B6D38          2          8 24071                 0                                        542B70E8          1         15 24081               195 EV
                                        542B7498          1         15 24081               195 EVSYS                            INACTIVE 542B7848          0          0                       0
SYS                            INACTIVE 542B7BF8          1         15 24081               195 EV

16 rows selected.

我們注意,紅字標(biāo)出的部分就是被Kill掉的進(jìn)程的進(jìn)程地址.

簡化一點(diǎn),其實(shí)就是如下概念:

SQL> select p.addr from v$process p where pid <> 1
  2  minus
  3  select s.paddr from v$session s;

Ok,現(xiàn)在我們獲得了進(jìn)程地址,就可以在v$process中找到spid,然后可以使用Kill或者orakill在系統(tǒng)級來殺掉這些進(jìn)程.

實(shí)際上,我猜測:

當(dāng)在Oracle中kill session以后, Oracle只是簡單的把相關(guān)session的paddr 指向同一個虛擬地址.

此時(shí)v$process和v$session失去關(guān)聯(lián),進(jìn)程就此中斷.

然后Oracle就等待PMON去清除這些Session.所以通常等待一個被標(biāo)記為Killed的Session退出需要花費(fèi)很長的時(shí)間.

如果此時(shí)被Kill的process,重新嘗試執(zhí)行任務(wù),那么馬上會收到進(jìn)程中斷的提示,process退出,此時(shí)Oracle會立即啟動PMON
來清除該session.這被作為一次異常中斷處理.


-The End-
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

原文地址:http://space.itpub.net/22578826/viewspace-702988

Oracle HowTo:如何快速殺死占用過多資源(CPU,內(nèi)存)的數(shù)據(jù)庫進(jìn)程

很多時(shí)候由于異?;虺绦蝈e誤會導(dǎo)致個別進(jìn)程占用大量系統(tǒng)資源,需要結(jié)束這些進(jìn)程,通??梢允褂靡韵旅頚ill進(jìn)程:
alter system kill session 'sid,serial#';

但是此命令釋放資源極為緩慢,為了更快速的釋放資源,通常我們使用如下步驟來Kill進(jìn)程:
1.首先在操作系統(tǒng)級kill進(jìn)程
2.在數(shù)據(jù)庫內(nèi)部kill session
這樣通常可以快速中止進(jìn)程,釋放資源。

今天就遇到這樣一個案例,其他朋友在數(shù)據(jù)庫里kill session,可是長時(shí)間仍無效果:
[oracle@danaly ~]$ sqlplus "/ as sysdba"

SQL*Plus: Release 10.2.0.1.0 - Production on Thu Oct 27 11:09:50 2005

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining Scoring Engine options

SQL> select sid,username,status from v$session;

       SID USERNAME                       STATUS
---------- ------------------------------ --------
....
       154 SCOTT                          KILLED
...

30 rows selected.

那按照我前面提到的步驟,首先查詢得到該session對應(yīng)的OS進(jìn)程號:
SQL> select 'kill -9 '||spid from v$process where addr = (select paddr from v$session where sid=&sid);
Enter value for sid: 154
old   1: select 'kill -9 '||spid from v$process where addr = (select paddr from v$session where sid=&sid)
new   1: select 'kill -9 '||spid from v$process where addr = (select paddr from v$session where sid=154)

'KILL-9'||SPID
--------------------
kill -9 22702

SQL> !

在操作系統(tǒng)級kill該進(jìn)程:
[oracle@danaly ~]$ ps -ef|grep 22702
oracle   22702     1  0 Oct25 ?        00:00:02 oracledanaly (LOCAL=NO)
oracle   12082 12063  0 11:12 pts/1    00:00:00 grep 22702
[oracle@danaly ~]$ kill -9 22702
[oracle@danaly ~]$ ps -ef|grep 22702
oracle   12088 12063  0 11:12 pts/1    00:00:00 grep 22702
[oracle@danaly ~]$ exit
exit

SQL> select sid,username,status from v$session;

       SID USERNAME                       STATUS
---------- ------------------------------ --------
...
       154 SCOTT                          KILLED
...

30 rows selected.

SQL> select sid,serial#,username from v$session where sid=154;

       SID    SERIAL# USERNAME
---------- ---------- ------------------------------
       154      56090 SCOTT

再次在數(shù)據(jù)庫中kill該session,并指定immediate選項(xiàng):
SQL> alter system kill session '154,56090' immediate;

System altered.

SQL> select sid,serial#,username from v$session where sid=154;

no rows selected

此時(shí)該進(jìn)程被迅速清除。

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

原文地址:http://space.itpub.net/17203031/viewspace-683786


Kill會話過程分析


在實(shí)際開發(fā)中,我們常常需要將用戶的會話強(qiáng)制斷開。比如:事務(wù)執(zhí)行超時(shí)、代碼出現(xiàn)死循環(huán)、死鎖或者無意中將數(shù)據(jù)表鎖住。這個使用kill session是很實(shí)用的方法。那么,kill session的時(shí)候,系統(tǒng)究竟發(fā)生了什么呢?

基礎(chǔ)知識

用戶連接到數(shù)據(jù)庫,涉及到幾個對象。首先是監(jiān)聽器,我們常常使用的本地命名服務(wù)(tnsname.ora),實(shí)際上連接的就是監(jiān)聽器。但是,對于我們連接過程來說,與監(jiān)聽器打交道的時(shí)間還是很短暫的(詳細(xì)可以見筆者其他討論監(jiān)聽器和連接的文章)。其次是Server Process,是客戶端應(yīng)用在數(shù)據(jù)庫服務(wù)器上的操作代表。所有對于數(shù)據(jù)庫實(shí)例、數(shù)據(jù)文件和SGA的操作,實(shí)際執(zhí)行都是Server Process來進(jìn)行的。最后就是以PMON為代表的后臺進(jìn)程(影子進(jìn)程),他們負(fù)責(zé)管理實(shí)例的方方面面,保證各方面職能正確實(shí)現(xiàn)。

另一個邏輯層次上,用戶會話session是一個重要概念。在特定的情況下,我們可以說用戶與數(shù)據(jù)庫的交互,就是在一個持續(xù)的session中完成。在一個session中,用戶可以執(zhí)行多個事務(wù),可以處在閑置狀態(tài)(Inactive)。

在任何情況下,如果我們強(qiáng)制性的斷開連接,放開session(主動)。PMON后臺進(jìn)程會主動的做回收處理工作(在繁忙的時(shí)候存在延時(shí))?;厥瞻ㄇ謇頃捫畔ⅲ貪L未提交事務(wù),釋放Server Process資源(專用模式下)。

在一些時(shí)候,我們可以借助alter system kill session ‘sid, serial#’;來手工強(qiáng)制斷開用戶連接。那么,Oracle進(jìn)行kill的時(shí)候,究竟發(fā)生了什么呢?讓我一起來研究。

實(shí)驗(yàn)環(huán)境構(gòu)建

Connected to Oracle Database11gEnterpriseEdition Release11.2.0.1.0

Connected as SYS

//查看組件版本:使用SYS登錄

SQL> select * from v$version;

BANNER

--------------------------------------------------------------------------------

Oracle Database11gEnterpriseEdition Release11.2.0.1.0 - Production

PL/SQL Release11.2.0.1.0 - Production

CORE       11.2.0.1.0  Production

TNS for Linux: Version11.2.0.1.0 - Production

NLSRTL Version11.2.0.1.0 - Production

首先,為了簡便,筆者啟動了PL/SQL Developer,并且打開一個Command窗口。之后,啟動一個sqlplus窗口,觀察這個窗口對應(yīng)的會話情況。

在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         


可以發(fā)現(xiàn),會話中多了三個session。兩個用戶名SYS的會話是PL/SQL Developer開啟的(原理見之前博客內(nèi)容)。另一個SCOTT用戶開啟的sqlplusw.exe是我們的實(shí)驗(yàn)對象,發(fā)現(xiàn)其sid=1,Serial#=64。會話對應(yīng)的Server Process物理地址為38BC6C94。


之后,我們查找的對應(yīng)的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對應(yīng)的Server Process,進(jìn)程編號為5803(PID為Oracle相關(guān)進(jìn)程的內(nèi)部編號,SPID表示的是操作系統(tǒng)級別)。

最后,我們查看操作系統(tǒng)級別進(jìn)程信息。

[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

實(shí)驗(yàn)kill會話。

在觀察PL/SQL Developer里,將SCOTT會話斷開。

SQL> alter system kill session '1,64';

System altered

Kill操作執(zhí)行完成,沒有報(bào)錯。那么,這個會話信息真的被刪除了嗎?我們重新檢查v$session。

//發(fā)現(xiàn),會話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

“怪事”發(fā)生了,我們kill掉了會話。但是會話信息還存在,與剛才的結(jié)果區(qū)別是兩個:其一為會話的狀態(tài)變?yōu)榱薑ILLED狀態(tài),表示已經(jīng)被kill。其二是對應(yīng)Server Process的地址被修改,該到了38058594的位置上。

而查看v$process進(jìn)程視圖,發(fā)現(xiàn)原來為其服務(wù)的Server Process信息仍然存在!那么,是真的存在嗎?我們查看操作系統(tǒng)層面:

[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確實(shí)存在。那么這個新Server Process地址38058594是什么呢?

SQL> select addr,pid,spid,username,serial#,program from v$process where addr='38058594';

ADDR           PID SPID                    USERNAME     SERIAL# PROGRAM

-------- ---------- ------------------------ ---------- ---------- -------------------------

綜合上述:在kill的時(shí)候,Oracle做了兩件事。一件是將會話的狀態(tài)修改了KILLED,相當(dāng)于打了一個標(biāo)記。第二件是通過將會話對應(yīng)的Server Process地址修改為一個虛擬地址,切斷會話信息與Server Process的映射關(guān)聯(lián)。此外,Server Process并沒有回收。

等待一會之后,發(fā)現(xiàn)依然如此!沒有PMON主動的回收動作。

那么,如果此時(shí)被kill掉的會話發(fā)起一個操作,如何?

在sqlplus上:

SQL> select * from emp;

select * from emp

*

第1行出現(xiàn)錯誤:

ORA-00028:您的會話己被終止

被斷開的會話拒絕操作,告知說會話已經(jīng)被終止。

此時(shí),系統(tǒng)還能查看到這個會話信息嗎?

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

結(jié)論:當(dāng)我們在原有窗口執(zhí)行操作,嘗試會話通信時(shí),被拒絕。通過視圖查詢,發(fā)現(xiàn)原有被kill的會話信息被回收。但是Server Process還存在在視圖上,但不與任何會話對應(yīng)。

那操作系統(tǒng)層面上:

[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還存在,沒有回收。

注意:當(dāng)我們關(guān)閉掉sqlplusw窗口之后,也就是我們關(guān)掉客戶端的時(shí)候,我們再次查詢發(fā)現(xiàn):

[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自然也應(yīng)當(dāng)沒有對應(yīng)記錄存在了。

SQL> select addr,pid,spid,username,serial#,program from v$process where addr='38BC6C94';

ADDR           PID SPID                    USERNAME     SERIAL# PROGRAM

-------- ---------- ------------------------ ---------- ---------- -------------------------

38BC6C94        255956                    oracle            26 oracle@oracle11g(J000)

誒,為什么有記錄呢?仔細(xì)看看:SPID已經(jīng)發(fā)生變化,不是5803,而是5956,是一個新啟動的進(jìn)程。只是使用了剛剛被釋放的地址。

結(jié)論:駐留在數(shù)據(jù)庫服務(wù)器的Server Process會一直存在,直到客戶端應(yīng)用斷開連接,不在于Server Process通信。注意,這時(shí)如何客戶端重新連接conn,客戶端是重新與監(jiān)聽器溝通,獲取一個新的Server Process重定向,不會找過去的那個舊Server Process。一旦重新登錄,舊的Server Process就會被回收釋放掉。

綜上所述:在kill研究中,我們搞清楚了幾個方面問題:

1、alter system kill session:只是將session標(biāo)記為可以回收,切斷會話與Server Process的映射關(guān)系。沒有進(jìn)行資源釋放回收工作;

2、一旦嘗試連接,PMON會主動開始清理被kill的會話,同時(shí)Oracle拒絕連接操作;

3、Server Process是一個忠實(shí)于客戶端的進(jìn)程,只要客戶端還在啟動,維持著兩個之間的聯(lián)系。Server Process是不會被回收的。直到客戶端主動停止與Server Process的通信,Server Process釋放;

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★


原文地址:http://space.itpub.net/17203031/viewspace-684039

Kill會話過程分析(二)


本文為筆者“Kill會話過程分析”(http://space.itpub.net/17203031/viewspace-683786)的續(xù)篇。做一些更深入的分析。

我們知道,當(dāng)需要強(qiáng)制斷開一個會話的時(shí)候,可以通過SQL命令alter system kill session ‘sid, serial#’;強(qiáng)制的將會話斷開。其中,SID為會話的編號,Serial為會話的系列號。這兩個值是唯一標(biāo)志Oracle一個會話。而會話的相關(guān)信息,可以通過查詢v$session視圖來獲取到。

根據(jù)前文我們的分析,認(rèn)為alter system kill session命令是存在一些不足的。

首先,kill session命令是在會話層面的強(qiáng)制斷開。本質(zhì)上相當(dāng)于進(jìn)行了一個標(biāo)志,切斷了Server Process與會話之間的映射關(guān)系。會話所占有的資源是不會直接被回收;

其次,kill session命令在一些特殊場合,應(yīng)對效果不佳。比如在Oracle Job里面運(yùn)行的時(shí)候,是不能定位到相應(yīng)的會話對象的。

最后,一些緊急的時(shí)候,kill session還存在一些適應(yīng)性較差的情況。比如當(dāng)前根本無法登陸SQL命令窗口;

那么,比kill session更有效直接的做法是什么呢?針對Server Process的kill操作,也就是OS操作系統(tǒng)級別的kill。當(dāng)我們不能夠使用alter system kill session或者使用其無效的時(shí)候,可以考慮使用這種方法。

首先,我們研究一些Linux環(huán)境。選擇是專用連接模式。

在沒有連接的時(shí)候,我們查看連接情況。

[oracle@oracle11g~]$ ps -ef | grepwilson| grep -v grep

oracle   5583    1 0 02:52 ?       00:00:00 ora_pmon_wilson

oracle   5585    1 0 02:52 ?       00:00:00 ora_vktm_wilson

……(篇幅原因,有省略部分)

oracle   5672    1 0 02:52 ?       00:00:00 ora_q001_wilson

oracle   5700    1 0 02:57 ?       00:00:00 ora_smco_wilson

oracle   5702    1 0 02:57 ?       00:00:00 ora_w000_wilson

在沒有連接的時(shí)候,進(jìn)程列表中只能看到實(shí)例多個background process的運(yùn)行情況。此時(shí),我們連入一個客戶端。查看進(jìn)程情況:(為省略篇幅,設(shè)置篩選條件)

[oracle@oracle11g~]$ ps -ef | grep LOCAL | grep -v grep;

oracle   5777    1 1 03:09 ?       00:00:00oraclewilson (LOCAL=NO)

[oracle@oracle11g~]$

連入了一個客戶端,在專用模式下有一個Server Process與之關(guān)聯(lián)。這里對各列含義略作說明。

第一列表示執(zhí)行用戶Owner,第二列是PID,表示進(jìn)程的系統(tǒng)唯一編號。第三列表示該進(jìn)程的父進(jìn)程PPID編號,就是該進(jìn)程是由哪個進(jìn)程啟動的。之后有兩個時(shí)間值,分別為進(jìn)程啟動到現(xiàn)在時(shí)間與占用CPU時(shí)間。最后一列一般為啟動命令行。

其中,我們比較關(guān)注的就是PID。PID唯一的標(biāo)識,如果強(qiáng)制終止這個進(jìn)程,我們就可以強(qiáng)制的結(jié)束會話(皮之不存,毛將焉附)。同時(shí),在OS層面的強(qiáng)制終止,進(jìn)程會話對應(yīng)的資源可以直接回收。

在Unix/Linux平臺下,可以使用kill -9 PID,實(shí)現(xiàn)刪除。

[oracle@oracle11g~]$ kill -9 5777//終止

[oracle@oracle11g~]$ ps -ef | grep LOCAL | grep -v grep;//確認(rèn)

[oracle@oracle11g~]$

使用后,操作系統(tǒng)進(jìn)程樹上的Server Process被清除。此時(shí),連接的客戶端如果發(fā)起請求。

//之前建立的連接

SQL> conn scott/tiger@wilson

已連接。

//kill之后,嘗試連接

SQL> select count(*) from emp;

select count(*) from emp

                      *

第1行出現(xiàn)錯誤:

ORA-03113:通信通道的文件結(jié)束//報(bào)錯!

使用kill -9命令,還可以對background process進(jìn)程進(jìn)行管理,對一些問題進(jìn)程進(jìn)行殺死重建,也是我們經(jīng)常使用的手段。

結(jié)論:在Linux平臺上,當(dāng)需要在操作系統(tǒng)級別進(jìn)行kill的時(shí)候,可以使用kill -9命令。

接下來,我們在Windows平臺上,就有一些問題了。由于體系結(jié)構(gòu)的不同,Oracle在Windows下實(shí)現(xiàn)的實(shí)例結(jié)構(gòu),并不是多進(jìn)程架構(gòu)方式,而采用的是多線程模式。Unix/Linux下的background process和Server Process,成為了一個ORACLE.exe進(jìn)程里的線程。那么,這種情況下,我們?nèi)绾翁幚恚?/p>

為了應(yīng)對這種情況,Oracle提供了一個為orakill.exe的命令。這個命令本質(zhì)上和alter system kill session的功能相同,但是不需要登錄連接數(shù)據(jù)庫。只需要輸入線程編號和SID就可以。

這樣,問題轉(zhuǎn)化為我們?nèi)绻@取到一個線程的線程編號。在Windows平臺上,有很多查看線程的工具。如Qslice.exe、QuickSlice.exe以及Pstat。

語法:orakill <sid> <thread>;

其中,sid為Oracle的sid號。Thread為會話對應(yīng)的線程的編號。我們可以通過v$session和v$process的信息獲取。

SQL> select b.username, a.spid, b.username, b.sid, b.osuser, b.action

 2 from v$process a, v$session b

 3 where a.ADDR=b.PADDR and b.username='SYS';

USERNAME SPID        USERNAME  SID OSUSER                        ACTION

--------- ------------ ---------- ------------------------------ --------------------------------

SYS      1464        SYS       152 WWW-0E6111DFF74\Administrator Command Window - New

SYS      632         SYS       141 WWW-0E6111DFF74\Administrator Main session

注意下v$process的SPID列。在Linux/Unix環(huán)境下,這個列的SPID表示Process的編號。在Windows環(huán)境下,這列就表示在ORACLE.exe進(jìn)程下的線程編號。

我們嘗試刪除命令窗口線程(SPID=1464)。

C:\>orakill orcl 1464

Kill of thread id1464 ininstance orcl successfully signalled.

命令窗口再次嘗試連接時(shí)。

SQL> select count(*) from dba_objects;

Warning: connection was lost and re-established

說明:連接被切斷。

此外,orakill命令也可以在SQL命令提示中使用。

SQL> host orakill orcl 3140

Kill of thread id3140 ininstance orcl successfully signalled.

SQL>

結(jié)論:在Windows平臺上,可以使用orakill工具進(jìn)行session和server的殺死工作。

最后,筆者還要強(qiáng)調(diào)一下。無論是kill session還是kill -9操作,都是一種危險(xiǎn)的操作,特別是在生產(chǎn)環(huán)境下。原因在于,后臺進(jìn)程特別是核心后臺進(jìn)程(PMON,SMON,DBWN,LGWR)如果被誤刪除,相當(dāng)于實(shí)例死掉,是一件重大事故。在沒有確認(rèn)需要、沒有專業(yè)人員許可的情況下,盡可能的選取破壞性小的方案進(jìn)行處理。

上述就是小編為大家分享的Oracle 徹底 kill session的示例分析了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI