kill session的學問

oliseh發表於2015-11-17
終止會話有兩種方法:
1、alter system kill session 'sid,serial#' [ immediate ]
     在某個記憶體區域設定一個標記,表示這個session即將被kill,當session執行下一條命令時會檢查此標記,若存在則session立即終止,同時收到"ORA-00028: your session has been killed",session對應的server process也會立即終結,這可以解釋為何我們kill一個活動session的時候往往能夠成功,因為session在不斷的和Server進行互動,很容易檢測到即將被kill的標記。
     而對於非活動的session,相信大家都有下面的體驗:當我們實施kill session命令之後,v$session.status顯示狀態為killed,但等了很長時間session還在,最後不得不在OS裡kill掉server process才能將session真正kill掉,這是因為session處於非活動,無法及時檢測到記憶體裡的kill標記。
     alter system kill session的本質是session自己kill自己
     
2、alter system disconnect session 'sid,serial#' [immediate | post_transaction]
     其效果相當於直接kill掉OS的server process,相比kill session能夠更加直接、快速的終止session,這是一種主動kill的方式。用上post_transaction選項可以等待當前正在執行的transaction提交或者回滾後再終止session,最大程度維持了disconnect session命令之前發起的transaction的完整性,這一功能是kill session命令所不具備的


下面來看幾個例子加深印象,其中session 1 跑sql,session 2 發終止命令
=====================================================================
======================part 1 : alter system kill session 'sid,serial#' ====================
=====================================================================


<<<< 1、執行alter system kill session 'sid,serial#' 終止掉非活動的session >>>
---session 1:
SYS@tstdb1-SQL> select * from scott.t1116_1;


        RN
----------
        11
        22
         3
         4
         5


SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server from v$session s,v$process p where sid=(select sys_context('userenv','sid')  from dual) and s.paddr=p.addr;


       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER
---------- ---------- -------- ------------------------ ------------------------------------------------ ---------
       994         39 ACTIVE   7864770                  sqlplus@jq570322b (TNS V1-V3)                    DEDICATED


SYS@tstdb1-SQL> update scott.t1116_1 set rn=33 where rn=3;


1 row updated.


---session 2: kill session
***session 1會話處於INACTIVE狀態
select s.sid,s.serial#,s.status,p.spid,s.program,s.server,s.terminal from v$session s,v$process p where s.sid=994 and s.serial#=39 and s.paddr=p.addr(+);
       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER    TERMINAL
---------- ---------- -------- ------------------------ ------------------------------------------------ --------- ------------------------------
       994        39  INACTIVE                            sqlplus@jq570322b (TNS V1-V3)                    DEDICATED    pts/0
       
SYS@tstdb1-SQL> alter system kill session '994,39';   


System altered.


***下面的查詢結果裡spid為空值,SERVER變為了PSEUDO,原因是v$session.paddr值變了,其實server process在OS層面還存在的
select s.sid,s.serial#,s.status,p.spid,s.program,s.server,s.terminal from v$session s,v$process p where s.sid=994 and s.serial#=39 and s.paddr=p.addr(+);
       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER    TERMINAL
---------- ---------- -------- ------------------------ ------------------------------------------------ --------- ------------------------------
       994        39  KILLED                            sqlplus@jq570322b (TNS V1-V3)                    PSEUDO    pts/0


因為session 1處於INACTIVE狀態所以其無法檢測到kill標誌,只能從OS層面kill掉server process 
kill -9 7406220


SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server,s.terminal from v$session s,v$process p where s.sid=994 and s.serial#=39 and s.paddr=p.addr(+);


no rows selected         


<<<< 2、執行alter system kill session 'sid,serial#' 終止掉活動的session >>>
---session 1:
SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server from v$session s,v$process p where sid=(select sys_context('userenv','sid')  from dual) and s.paddr=p.addr;


       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER
---------- ---------- -------- ------------------------ ------------------------------------------------ ---------
       532        137 ACTIVE   6619488                  sqlplus@jq570322b (TNS V1-V3)                    DEDICATED


***這裡製造了一個百萬資料量的表
create table scott.t1116_2 tablespace ts1116 as select * from dba_objects;
insert into scott.t1116_2 select * from t1116_2;
。。。執行若干次


***表裡有250W的資料
SYS@tstdb1-SQL> select count(*) from scott.t1116_2;


  COUNT(*)
----------
   2562816
   
***執行迴圈update,執行大約1分鐘       
declare
begin
while ( true ) loop
update scott.t1116_2 set object_name=dbms_random.string('u',100),edition_name=dbms_random.string('u',30),SUBOBJECT_NAME=dbms_random.string('u',30);
end loop;
end;
/


---session 2: kill session 
SYS@tstdb1-SQL> set timing on
SYS@tstdb1-SQL> alter system kill session '532,137';    <---不加immediate,kill耗時8s返回


System altered.


Elapsed: 00:00:08.00


session 2的kill session命令結束後,session 1隨即顯示
---session 1:
declare
*
ERROR at line 1:
ORA-00028: your session has been killed
ORA-00028: your session has been killed
ORA-06512: at line 4


不加immediate的kill session命令要等transaction rollback完成後才會返回,命令返回意味著session已經真正被kill掉了


<<<< 3、執行alter system kill session 'sid,serial#' immediate 終止活動的session >>>
---session 1:
SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server from v$session s,v$process p where sid=(select sys_context('userenv','sid')  from dual) and s.paddr=p.addr;


       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER
---------- ---------- -------- ------------------------ ------------------------------------------------ ---------
       267       1295 ACTIVE   6423486                  sqlplus@jq570322b (TNS V1-V3)                    DEDICATED


***還是這張250W記錄的資料表
SYS@tstdb1-SQL> select count(*) from scott.t1116_2;


  COUNT(*)
----------
   2562816
   
***執行迴圈update,這次執行時間延長到2分鐘後再kill   
declare
begin
while ( true ) loop
update scott.t1116_2 set object_name=dbms_random.string('u',100),edition_name=dbms_random.string('u',30),SUBOBJECT_NAME=dbms_random.string('u',30);
end loop;
end;
/   


---session 2: 這次使用kill session ...  immediate
select s.sid,s.serial#,s.status,p.spid,s.program,s.server,s.terminal from v$session s,v$process p where s.sid=267 and s.serial#=1295 and s.paddr=p.addr(+);
       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER    TERMINAL
---------- ---------- -------- ------------------------ ------------------------------------------------ --------- ------------------------------
       267       1295 ACTIVE   6423486                  sqlplus@jq570322b (TNS V1-V3)                    DEDICATED pts/0


***可以看出kill session immediate後立即返回,得到的提示是"ORA-00031: session marked for kill"
SYS@tstdb1-SQL> set timing on
SYS@tstdb1-SQL> alter system kill session '267,1295' immediate;
alter system kill session '267,1295' immediate
*
ERROR at line 1:
ORA-00031: session marked for kill


Elapsed: 00:00:00.00


以上看出加了immediate的kill session命令是立即返回的,此時transaction rollback的動作還在後臺繼續執行,session何時被真正kill掉取決於rollback何時完成


---session 1:大約5秒後收到會話終止的訊息
ERROR:
ORA-03114: not connected to ORACLE


declare
*
ERROR at line 1:
ORA-00028: your session has been killed
ORA-00028: your session has been killed
ORA-06512: at line 4


這裡的5秒鐘並不是固定的,transaction rollback的速度有快又慢,以下兩種方法可以觀察rollback的進度
***當session 1 對應的Transaction所使用的undo塊數下降為0後,意味著會話被成功kill
SYS@tstdb1-SQL> select t.used_urec,t.used_ublk from v$transaction t,v$session s where s.sid=266 and s.serial#=1115 and s.saddr=t.ses_addr;


 USED_UREC  USED_UBLK
---------- ----------
   0      0
   
或者觀察v$fast_start_transactions,當undoblocksdone=undoblockstotal時表示事務回滾結束
select undoblocksdone,undoblockstotal,xid from v$fast_start_transactions where xid='002B0009000015E7'  <--- XID取自於v$transaction.xid


=====================================================================
===================part 2 : alter system disconnect session 'sid,serial#'==================
=====================================================================

<<<< 4、執行alter system disconnect session 'sid,serial#' 終止非活動的session >>>
---session 1:
SYS@tstdb1-SQL> update scott.t1116_1 set rn=2 where rn=22;


1 row updated.


SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server from v$session s,v$process p where sid=(select sys_context('userenv','sid')  from dual) and s.paddr=p.addr;
       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER
---------- ---------- -------- ------------------------ ------------------------------------------------ ---------
       469        895 ACTIVE   8455152                  sqlplus@jq570322b (TNS V1-V3)                    DEDICATED


---session 2:
SYS@tstdb1-SQL> alter system disconnect session '469,895' immediate;


System altered.


SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server,s.terminal from v$session s,v$process p where s.sid=267 and s.serial#=21 and s.paddr=p.addr(+);


no rows selected


---session 1: 因為server process被kill了,所以session 1 下一次發起SQL命令時會直接收到ORA-03135的報錯
SYS@tstdb1-SQL>
SYS@tstdb1-SQL>
SYS@tstdb1-SQL> select;
select
*
ERROR at line 1:
ORA-03135: connection lost contact
Process ID: 8455152
Session ID: 469 Serial number: 895


ERROR:
ORA-03114: not connected to ORACLE


<<<< 5、執行alter system disconnect session 'sid,serial#' 終止活動的session >>>
---session 1:
還是拿250W記錄的表來說事
SYS@tstdb1-SQL> select count(*) from scott.t1116_2;


  COUNT(*)
----------
   2562816


SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server from v$session s,v$process p where sid=(select sys_context('userenv','sid')  from dual) and s.paddr=p.addr;


       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER
---------- ---------- -------- ------------------------ ------------------------------------------------ ---------
       863        103 ACTIVE   6357528                  sqlplus@jq570322b (TNS V1-V3)                    DEDICATED


***執行以下過程2分鐘左右       
declare
begin
while ( true ) loop
update scott.t1116_2 set object_name=dbms_random.string('u',100),edition_name=dbms_random.string('u',30),SUBOBJECT_NAME=dbms_random.string('u',30);
end loop;
end;
/


---session 2:disconnect session 
SYS@tstdb1-SQL> alter system disconnect session '863,103' immediate;
alter system disconnect session '863,103' immediate
*
ERROR at line 1:
ORA-00031: session marked for kill




Elapsed: 00:00:00.00


***觀察used_ublk、used_urec逐漸下降,直到降為0後,session 1才退出
SYS@tstdb1-SQL> select t.used_urec,t.used_ublk,s.saddr,t.ses_addr,t.xid from v$transaction t,v$session s where s.sid=863 and s.serial#=103 and s.saddr(+)=t.ses_addr


 USED_UREC  USED_UBLK SADDR            SES_ADDR         XID
---------- ---------- ---------------- ---------------- ----------------
    279708       5940 07000001B67D7418 07000001B67D7418 002B001800001732


SYS@tstdb1-SQL> select t.used_urec,t.used_ublk,s.saddr,t.ses_addr,t.xid from v$transaction t,v$session s where s.sid=863 and s.serial#=103 and s.saddr(+)=t.ses_addr


 USED_UREC  USED_UBLK SADDR            SES_ADDR         XID
---------- ---------- ---------------- ---------------- ----------------
    246563       5237 07000001B67D7418 07000001B67D7418 002B001800001732


SYS@tstdb1-SQL> select t.used_urec,t.used_ublk,s.saddr,t.ses_addr,t.xid from v$transaction t,v$session s where s.sid=863 and s.serial#=103 and s.saddr(+)=t.ses_addr


 USED_UREC  USED_UBLK SADDR            SES_ADDR         XID
---------- ---------- ---------------- ---------------- ----------------
     77517       1644 07000001B67D7418 07000001B67D7418 002B001800001732


SYS@tstdb1-SQL> select t.used_urec,t.used_ublk,s.saddr,t.ses_addr,t.xid from v$transaction t,v$session s where s.sid=863 and s.serial#=103 and s.saddr(+)=t.ses_addr;


no rows selected


---session 1: 隨即收到"ORA-00028: your session has been killed"


ERROR:
ORA-03114: not connected to ORACLE




declare
*
ERROR at line 1:
ORA-00028: your session has been killed
ORA-00028: your session has been killed
ORA-06512: at line 4


---session 2: 與kill session命令有所不同的是v$fast_start_transactions裡沒有記錄下transaction rollback的過程,猜測可能是因為直接kill server process的緣故
SYS@tstdb1-SQL> select * from v$fast_start_transactions where xid='002B001800001732';


no rows selected


<<<< 6、執行alter system disconnect session 'sid,serial#' post_transaction終止非活動的session,session裡含有未提交的事務 >>>
---session 1:
SQL> select * from scott.t1116_1;


        RN
----------
         1
         2
         3
         4
         5


---session 1:
set linesize 140
select s.sid,s.serial#,s.status,p.spid,s.program,s.server from v$session s,v$process p where sid=(select sys_context('userenv','sid')  from dual) and s.paddr=p.addr;
       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER
---------- ---------- -------- ------------------------ ------------------------------------------------ ---------
       266        229 ACTIVE   3081100                  sqlplus@jq570322b (TNS V1-V3)                    DEDICATED


SYS@tstdb1-SQL> update scott.t1116_1 set rn=11 where rn=1;


1 row updated.


---session 2:
alter system disconnect session '266,229';
SYS@tstdb1-SQL> alter system disconnect session '266,229';
alter system disconnect session '266,229'
                                      *
ERROR at line 1:
ORA-02000: missing POST_TRANSACTION or IMMEDIATE keyword     <---必須指定POST_TRANSACTION或者IMMEDIATE


***加了post_transaction    
SYS@tstdb1-SQL> alter system disconnect session '266,229' post_transaction;


System altered.


---session 1: 沒有立即被kill掉,狀態還是ACTIVE
SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server from v$session s,v$process p where sid=(select sys_context('userenv','sid')  from dual) and s.paddr=p.addr;


       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER
---------- ---------- -------- ------------------------ ------------------------------------------------ ---------
       266        229 ACTIVE   3081100                  sqlplus@jq570322b (TNS V1-V3)                    DEDICATED


***server process健在
tstdb1@jq570322b:/home/tstdb1>ps -ef|grep 3081100 | grep -v grep
  tstdb1  3081100 12517530   0 10:51:17      -  0:00 oracletstdb1 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
    
***甚至可以繼續進行dml操作
SQL> update scott.t1116_1 set rn=22 where rn=2;


1 row updated.


SQL> select * from scott.t1116_1;
        RN
----------
        11
        22
         3
         4
         5
         
SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server from v$session s,v$process p where sid=(select sys_context('userenv','sid')  from dual) and s.paddr=p.addr;


       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER
---------- ---------- -------- ------------------------ ------------------------------------------------ ---------
       266        229 ACTIVE   3081100                  sqlplus@jq570322b (TNS V1-V3)                    DEDICATED
       
***執行commit
SQL> commit;


Commit complete.


---session 2:此時去查v$session 發現 sid=266 and serial#=229的session已經消失
SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server,s.terminal from v$session s,v$process p where s.sid=266 and s.serial#=229 and s.paddr=p.addr(+);


no rows selected


***server process在OS上也已經消失
ps -ef|grep 3081100 | grep -v grep |wc -l
       0


<<<< 7、執行alter system disconnect session 'sid,serial#' post_transaction終止非活動的session,session裡沒有未提交的事務 >>>
---session 1: 
SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,s.program,p.spid,s.server from v$session s,v$process p where sid=(select sys_context('userenv','sid')  from dual) and s.paddr=p.addr;


       SID    SERIAL# STATUS   PROGRAM                                          SPID                     SERVER
---------- ---------- -------- ------------------------------------------------ ------------------------ ---------
       664         51 ACTIVE   sqlplus@jq570322b (TNS V1-V3)                    7406272                  DEDICATED


---session 2: disconnect session
SYS@tstdb1-SQL> select * from v$transaction;  <----當前沒有任何活動事務


no rows selected


SYS@tstdb1-SQL> alter system disconnect session '664,51' post_transaction;


System altered.


***disconnect session後發現session還在,server process的spid已經變成空值了,SERVER從DEDICATED變成了PSEUDO
SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server,s.terminal from v$session s,v$process p where s.sid=664 and s.serial#=51 and s.paddr=p.addr(+);


       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER    TERMINAL
---------- ---------- -------- ------------------------ ------------------------------------------------ --------- ------------------------------
       664         51 KILLED                            sqlplus@jq570322b (TNS V1-V3)                    PSEUDO    pts/0                                          


其實server process在OS層面還存在:
ps -ef|grep 7406272|grep -v grep
  tstdb1  7406272  7078198   0 13:06:56      -  0:00 oracletstdb1 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))


至此大家發現與使用kill session命令的效果很像,此時有兩種方法快速終結這個session,我們採用第二種方法
(1) 只要在session 1裡發出任何有效的SQL命令都會收到"ORA-00028 your session has been killed"的錯誤,隨即session和對應的server process會分別從資料庫和OS級被終止
(2) OS裡強行將server process程式kill掉:
kill -9 7406272


---session 2:檢視session已經不存在:
SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server,s.terminal from v$session s,v$process p where s.sid=664 and s.serial#=51 and s.paddr=p.addr(+);


no rows selected


---session 1:  再次執行任何SQL命令時會被提示ORA-03135,表明session已被徹底幹掉
SYS@tstdb1-SQL> select ;
select
*
ERROR at line 1:
ORA-03135: connection lost contact
Process ID: 7406272
Session ID: 664 Serial number: 51




ERROR:
ORA-03114: not connected to ORACLE


<<<< 8、最後使用直接kill -9 server process命令的方法與disconnect session的作一個效果上的比較 >>>
---session 1:
SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server from v$session s,v$process p where sid=(select sys_context('userenv','sid')  from dual) and s.paddr=p.addr


       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER
---------- ---------- -------- ------------------------ ------------------------------------------------ ---------
       863        107 ACTIVE   11796678                 sqlplus@jq570322b (TNS V1-V3)                    DEDICATED


***持續更新擁有250W記錄的大表scott.t1116_2,持續時間約為2分鐘
declare
begin
while ( true ) loop
update scott.t1116_2 set object_name=dbms_random.string('u',100),edition_name=dbms_random.string('u',30),SUBOBJECT_NAME=dbms_random.string('u',30);
end loop;
end;
/


***直接kill掉server process
kill -9 11796678


---session 1: 立即收到ORA-03113
ERROR:
ORA-03114: not connected to ORACLE




declare
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 11796678
Session ID: 863 Serial number: 107


---session 2: 連續查詢幾次,v$session還顯示該session為ACTIVE
SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server,s.terminal from v$session s,v$process p where s.sid=863 and s.serial#=107 and s.paddr=p.addr(+)


       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER    TERMINAL
---------- ---------- -------- ------------------------ ------------------------------------------------ --------- ------------------------------
       863        107 ACTIVE   11796678                 sqlplus@jq570322b (TNS V1-V3)                    DEDICATED pts/0


SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server,s.terminal from v$session s,v$process p where s.sid=863 and s.serial#=107 and s.paddr=p.addr(+)


       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER    TERMINAL
---------- ---------- -------- ------------------------ ------------------------------------------------ --------- ------------------------------
       863        107 ACTIVE   11796678                 sqlplus@jq570322b (TNS V1-V3)                    DEDICATED pts/0


SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server,s.terminal from v$session s,v$process p where s.sid=863 and s.serial#=107 and s.paddr=p.addr(+)


       SID    SERIAL# STATUS   SPID                     PROGRAM                                          SERVER    TERMINAL
---------- ---------- -------- ------------------------ ------------------------------------------------ --------- ------------------------------
       863        107 ACTIVE   11796678                 sqlplus@jq570322b (TNS V1-V3)                    DEDICATED pts/0


過了大約30秒,v$session裡的session資訊消失
SYS@tstdb1-SQL> select s.sid,s.serial#,s.status,p.spid,s.program,s.server,s.terminal from v$session s,v$process p where s.sid=863 and s.serial#=107 and s.paddr=p.addr(+);


no rows selected


之後在v$fast_start_transactions裡發現Transaction正在rollback
SYS@tstdb1-SQL> select state,undoblocksdone,undoblockstotal from v$fast_start_transactions where xid='002700000000020C';


STATE            UNDOBLOCKSDONE UNDOBLOCKSTOTAL
---------------- -------------- ---------------
RECOVERING                 4747           10807


SYS@tstdb1-SQL> select state,undoblocksdone,undoblockstotal from v$fast_start_transactions where xid='002700000000020C'


STATE            UNDOBLOCKSDONE UNDOBLOCKSTOTAL
---------------- -------------- ---------------
RECOVERING                 5353           10807


SYS@tstdb1-SQL> select state,undoblocksdone,undoblockstotal from v$fast_start_transactions where xid='002700000000020C'


STATE            UNDOBLOCKSDONE UNDOBLOCKSTOTAL
---------------- -------------- ---------------
RECOVERING                 5856           10807


直到UNDOBLOCKSDONE=UNDOBLOCKSDONE,宣告rollback結束
SYS@tstdb1-SQL> select state,undoblocksdone,undoblockstotal from v$fast_start_transactions where xid='002700000000020C';


STATE            UNDOBLOCKSDONE UNDOBLOCKSDONE
---------------- -------------- ---------------
RECOVERED                 10807           10807


kill server process的命令是在OS層面發起的,server process被kill後之所以沒有立即開始事務的回滾,是因為OS層產生的操作需要一定時間才能反饋到DB,也即何時能被pmon程式檢測到,如果要縮短等待事件可以採用喚醒pmon程式的方法:
SYS@tstdb1-SQL> select s.program,p.pid from v$session s ,v$process p where s.program like '%PMON%' and p.addr=s.paddr;


PROGRAM                                                 PID
------------------------------------------------ ----------
oracle@jq570322b (PMON)                                   2


SYS@tstdb1-SQL> oradebug wakeup 2;


喚醒pmon程式後,transaction rollback就是立即開始,有興趣的童鞋可以嘗試一下


下面做一個總結
>>> alter system kill session:
        由於是session自己kill自己
        對於inactive的session,kill session後往往需要在OS級將其對應的server process 也kill掉;
        對於active的session,kill session後能夠乾淨的kill掉對應的session和server process,如果不想在前臺花太長時間等待transaction rollback結束,可以使用immediate選項快速返回命令列;


>>> alter system disconnect session:
post_transaction選項:
 (1) 會等待當前transaction結束後,終止掉session和對應的server process
 (2) 當沒有活動transaction時,效果等同於kill session

immediate選項:
 (1) 如果被disconnect的session正處於活動狀態,執行disconnect session命令的會話有可能收到"System altered"或者"ORA-00031: session marked for kill"的提示,如果是前者表示transaction已經回滾完成,更多遇到的是後者表示transaction還在後臺執行Rollback,只不過先返回到了命令列提示符,等到transaction rollback結束後被disconnect的session才會收到"ORA-00028: your session has been killed",disconnect session操作引起的transaction rollback只能透過v$transaction裡的used_ublk和used_urec欄位觀察其進展,v$fast_start_transactions檢視並沒有記錄;
 (2) 如果被disconnect的session處於非活動狀態,那麼會收到ORA-03135錯誤,而不像活動session那樣會收到ORA-00028錯誤
無論上面哪種情況Session和server process都能被終止掉,不需要像kill session那樣還要人工去kill server process


>>> 直接kill server process:
OS級直接kill掉server process後,需要等pmon程式檢測到這一操作後transaction才會進行rollback,被kill session的真實狀態會延時一段時間才能反應出來,減少延時可以採用oradebug wakeup來即時喚醒pmon


相比之下disconnect session的優勢非常明顯:快速清理、沒有殘留、使用post_transaction還能儘可能的不干擾正在執行的事務

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/53956/viewspace-1839893/,如需轉載,請註明出處,否則將追究法律責任。

相關文章