kill session 是DBA經常碰到的事情之一。如果kill 掉了不該kill 的session,則具有破壞性,因此儘可能的避免這樣的錯誤發生。同時也應當注意,
如果kill 的session屬於Oracle 後台進程,則容易導致資料庫執行個體宕機。
通常情況下,並不需要從作業系統層級殺掉Oracle會話進程,但並非總是如此,下面的描述中給出了在Oracle層級殺掉會話以及作業系統層級殺掉進程。
一、獲得需要kill session的資訊(使用V$SESSION 和 GV$SESSION視圖)
SET LINESIZE 180
COLUMN spid FORMAT A10
COLUMN username FORMAT A10
COLUMN program FORMAT A40
SELECT s.inst_id,
s.sid,
s.serial#,
p.spid,
s.username,
s.program,
s.paddr,
s.STATUS
FROM gv$session s
JOIN gv$process p ON p.addr = s.paddr AND p.inst_id = s.inst_id
WHERE s.type != 'BACKGROUND';
INST_ID SID SERIAL# SPID USERNAME PROGRAM PADDR STATUS
---------- ---------- ---------- ---------- ---------- --------------------------------------------- -------- --------
1 146 23 27573 TEST sqlplus@oracle10g (TNS V1-V3) 4C621950 INACTIVE
1 160 17 27610 SYS sqlplus@oracle10g (TNS V1-V3) 4C624174 ACTIVE
1 144 42 27641 SCOTT sqlplus@oracle10g (TNS V1-V3) 4C624730 INACTIVE
二、使用ALTER SYSTEM KILL SESSION 命令實現
文法:
SQL> ALTER SYSTEM KILL SESSION 'sid,serial#';
SQL> ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
對於RAC環境下的kill session ,需要搞清楚需要kill 的session 位於哪個節點,可以查詢GV$SESSION視圖獲得。
kill session 的時候僅僅是將會話殺掉。在有些時候,由於較大的事務或需要運行較長的SQL語句將導致需要kill的session並不能立即殺掉。對於這種情
況將收到 "marked for kill"提示(如下),一旦會話當前事務或操作完成,該會話被立即殺掉。
alter system kill session '4730,39171'
*
ERROR at line 1:
ORA-00031: session marked for kill
在下面的操作中將殺掉會話146,144
sys@AUSTIN> alter system kill session '146,23';
System altered.
sys@AUSTIN> alter system kill session '144,42';
System altered.
sys@AUSTIN> select inst_id,saddr,sid,serial#,paddr,username,status,program from gv$session where username is not null;
INST_ID SADDR SID SERIAL# PADDR USERNAME STATUS PROGRAM
---------- -------- ---------- ---------- -------- ---------- -------- ---------------------------------------------
1 4C70BF04 144 42 4C6545A0 SCOTT KILLED sqlplus@oracle10g (TNS V1-V3)
1 4C70E6B4 146 23 4C6545A0 TEST KILLED sqlplus@oracle10g (TNS V1-V3)
1 4C71FC84 160 17 4C624174 SYS ACTIVE sqlplus@oracle10g (TNS V1-V3)
注意:在查詢中可以看到被殺掉的會話的PADDR地址發生了變化,參照查詢結果中的紅色字型。如果多個session被kill 掉,則多個session的PADDR
被改為相同的進程地址。
通過下面的語句來找回被kill 掉的ADDR先前的地址
SELECT s.username,s.status,
x.ADDR,x.KSLLAPSC,x.KSLLAPSN,x.KSLLASPO,x.KSLLID1R,x.KSLLRTYP,
decode(bitand (x.ksuprflg,2),0,null,1)
FROM x$ksupr x,v$session s
WHERE s.paddr(+)=x.addr
and bitand(ksspaflg,1)!=0;
USERNAME STATUS ADDR KSLLAPSC KSLLAPSN KSLLASPO KSLLID1R KS D
---------- -------- -------- ---------- ---------- ------------ ---------- -- -
ACTIVE 4C623BB8 99 4 27468 275 EV 1
ACTIVE 4C623040 9 24 27444 0 1
ACTIVE 4C622A84 101 4 27480 274 EV 1
ACTIVE 4C6224C8 1 48 27450 0 1
ACTIVE 4C621F0C 1 48 27450 0 1
ACTIVE 4C6235FC 2 4 27468 0 1
SYS ACTIVE 4C624174 2 15 27442 0
ACTIVE 4C62081C 1 48 27440 0 1
ACTIVE 4C621394 1 48 27440 0 1
ACTIVE 4C620DD8 11 24 27476 0 1
ACTIVE 4C61F6E8 15 4 27610 0 1
ACTIVE 4C620260 222 24 27450 0 1
ACTIVE 4C61FCA4 7 25 27573 0 1
ACTIVE 4C61F12C 6 25 27573 0 1
ACTIVE 4C61EB70 4 24 27458 0 1
ACTIVE 4C61E5B4 1 48 27440 0 1
ACTIVE 4C61DFF8 2 24 27444 0 1
4C624730 0 0 0
4C621950 0 0 0
4C61DA3C 0 0 0
或者根據下面的語句來獲得發生變化的addr
sys@AUSTIN> select p.addr from v$process p where pid <> 1
2 minus
3 select s.paddr from v$session s;
ADDR
--------
4C621950
4C624730
三、在作業系統層級殺掉會話
尋找會話對應的作業系統的進程ID
sys@AUSTIN> select SPID from v$process where ADDR in ('4C621950','4C624730') ;
SPID
----------
27573
27641
使用kill 命令來殺掉作業系統層級進程ID
kill session -9 27573
kill session -9 27641
四、獲得當前會話的SID
SQL> select userenv('sid') from dual;
USERENV('SID')
--------------
627
五、多個會話需要kill 的處理辦法
1.根據給定的SID(使用者名稱)尋找需要殺掉會話的資訊,包括位於哪一個執行個體
set linesize 160
col program format a35
col username format a18
select inst_id,saddr,sid,serial#,paddr,username,status,program from gv$session
where sid in ('2731','2734','2720','2678','2685')
and username='CTICUST'
order by inst_id;
INST_ID SADDR SID SERIAL# PADDR USERNAME STATUS PROGRAM
---------- ---------------- ---------- ---------- ---------------- ------------------ -------- ---------------------------
1 00000003DAF8F870 2678 8265 00000003DBC6CA08 MSS4USR INACTIVE JDBC Thin Client
1 00000003DAF98E48 2685 83 00000003DBC08510 MSS4USR ACTIVE JDBC Thin Client
1 00000003DAFC7B80 2720 5 00000003DBBEDA20 MSS4USR INACTIVE JDBC Thin Client
1 00000003DAFD66F8 2731 3 00000003DBBE9AE0 SYS ACTIVE racgimon@svdg0028(TNS V1-V3)
1 00000003DAFDA730 2734 15 00000003DBBEC268 MSS4USR INACTIVE JDBC Thin Client
2 00000003DAFD66F8 2731 1 00000003DBBE92F8 ACTIVE oracle@svdg0029 (ARC0)
上面的查詢中有一個SID為2731的位於節點2上。
也可以通過下面的方式來獲得RAC的節點資訊,便於確定需要kill 的session究竟位於哪一個節點。
set linesize 160
col HOST_NAME format a25
SQL> select INSTANCE_NUMBER,INSTANCE_NAME,HOST_NAME,VERSION,STATUS from gv$instance order by 1;
INSTANCE_NUMBER INSTANCE_NAME HOST_NAME VERSION STATUS
--------------- ---------------- ------------------------- ----------------- ------------
1 O02WMT1A svd0051 10.2.0.4.0 OPEN
2 O02WMT1B svd0052 10.2.0.4.0 OPEN
3 O02WMT1C svd0053 10.2.0.4.0 OPEN
2.使用下面查詢來產生kill session 的語句
select 'alter system kill session '''|| sid ||',' ||SERIAL# ||''''||';' from gv$session
where sid in ('2731','2734','2720','2678','2685')
order by inst_id;
獲得下列kill session的語句,根據要求由於此次需要殺掉的session全部位於節點1,因此登入到節點節點1執行下面的語句
alter system kill session '2678,8265';
alter system kill session '2685,83';
alter system kill session '2720,5';
alter system kill session '2731,3';
alter system kill session '2734,15';
alter system kill session '2731,1'; --此條命令不需要執行,該session位於節點2。
oracle視頻教程請關注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html