天天看點

Oracle kill session詳解

kill session 是DBA經常碰到的事情之一。如果kill掉了不該kill 的session,則具有破壞性,是以盡可能的避免這樣的錯誤發生。同時也應當注意,

如果kill 的session屬于Oracle 背景程序,則容易導緻資料庫執行個體當機。

  通常情況下,并不需要從作業系統級别殺掉Oracle會話程序,但并非總是如此,下面的描述中給出了在Oracle級别殺掉會話以及作業系統級别殺掉程序。

一、獲得需要kill session的資訊(使用V$SESSION 和 GV$SESSION視圖)

  SETLINESIZE 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      [email protected] (TNS V1-V3)                4C621950 INACTIVE

          1        160         17 27610      SYS       [email protected] (TNS V1-V3)                4C624174 ACTIVE

          1        144         42 27641      SCOTT     [email protected] (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環境下的killsession ,需要搞清楚需要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

   [email protected]> alter system kill session '146,23';

   System altered.

   [email protected]> alter system kill session '144,42';

   System altered.

   [email protected]> selectinst_id,saddr,sid,serial#,paddr,username,status,program from gv$session whereusernameis not null;

      INST_ID SADDR           SID    SERIAL# PADDR    USERNAME  STATUS   PROGRAM

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

            1 4C70BF04        144         42 4C6545A0 SCOTT      KILLED  [email protected] (TNS V1-V3)

            1 4C70E6B4        146         23 4C6545A0 TEST       KILLED  [email protected] (TNS V1-V3)

            1 4C71FC84        160         17 4C624174 SYS        ACTIVE  [email protected] (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

   [email protected]> select p.addr from v$process p where pid <> 1

     2  minus

     3  select s.paddr from v$sessions;

   ADDR

   --------

   4C621950

   4C624730                  

三、在作業系統級别殺掉會話

  尋找會話對應的作業系統的程序ID

   [email protected]> 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 fromgv$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 [email protected](TNSV1-V3)

            1 00000003DAFDA730       2734         15 00000003DBBEC268 MSS4USR            INACTIVE JDBC Thin Client

            2 00000003DAFD66F8       2731          1 00000003DBBE92F8                    ACTIVE  [email protected] (ARC0)

    上面的查詢中有一個SID為2731的位于節點2上。

    也可以通過下面的方式來獲得RAC的節點資訊,便于确定需要kill的session究竟位于哪一個節點。

     set linesize 160

      col HOST_NAME format a25

     SQL> select INSTANCE_NUMBER,INSTANCE_NAME,HOST_NAME,VERSION,STATUSfrom 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.使用下面查詢來生成killsession 的語句

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

   where sid in ('2731','2734','2720','2678','2685')

   order by inst_id;

    獲得下列killsession的語句,根據要求由于此次需要殺掉的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。