Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9250751
  • 博文数量: 1669
  • 博客积分: 16831
  • 博客等级: 上将
  • 技术积分: 12594
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-25 07:23
个人简介

柔中带刚,刚中带柔,淫荡中富含柔和,刚猛中荡漾风骚,无坚不摧,无孔不入!

文章分类

全部博文(1669)

文章存档

2023年(4)

2022年(1)

2021年(10)

2020年(24)

2019年(4)

2018年(19)

2017年(66)

2016年(60)

2015年(49)

2014年(201)

2013年(221)

2012年(638)

2011年(372)

分类: Oracle

2012-04-01 10:15:04

Oracle kill sessin 说明
分类: Oracle 高级知识 183人阅读 评论(0) 举报

 

一.Session 状态说明

Oracle session 有如下几种状态

ACTIVE - Sessioncurrently executing SQL

INACTIVE 

KILLED - Sessionmarked to be killed

CACHED - Sessiontemporarily cached for use by Oracle*XA

SNIPED - Sessioninactive, waiting on the client

 

在之前的blog里有说明,参考:

Oraclesession active 和inactive 状态 说明

http://blog.csdn.net/tianlesoftware/article/details/6539297

 

1.1 Active 状态

active 处于此状态的会话,表示正在执行,处于活动状态。

            官方文档说明:

            Anysession that is connected to the database and is waiting for an event that doesnot belong to the Idle wait class is considered as an active session.

 

1.2 Killed 状态

killed处于此状态的会话,被标注为删除,表示出现了错误,正在回滚。

            当然,也是占用系统资源的。还有一点就是,killed的状态一般会持续较长时间,而且用windows下的工具pl/sql developer来kill掉,是不管用的,要用命令:alter system kill session 'sid,serial#' ;

 

1.3 Inactive 状态

inactive 处于此状态的会话表示不是正在执行的,该状态处于等待操作(即等待需要执行的SQL语句),通常当DML语句已经完成。 但连接没有释放,这个可能是程序中没有释放,如果是使用中间件来连接的话,也可能是中间件的配置或者是bug 导致。

 

            inactive对数据库本身没有什么影响,但是如果程序没有及时commit,那么就会造成占用过多会话。容易使DB 的session 达到极限值。

       一般不处理inactive 状态的session, 如果达到了session 的最大值, 就增加processes 和 sessions 参数。 对于Inactive 状态的session,可以设置过期时间,具体的2个参数是:

(1)sqlnet.ora文件中设置expire_time 参数

(2)用户profile的idle_time 参数

 

. Kill session 说明 2.1 查看session 类型

       Kill session 也是一个危险的操作,所以在kill之前要先确认session 的类型,如果我们kill 掉错误的后台进程的session,那么可能就会导致实例crash。

 

       可以通过gv$session 和 gv$process 或者v$session 和 v$process 来确认session 类型。

 

SET LINESIZE 100

COLUMN spid FORMAT A10

COLUMN username FORMAT A10

COLUMN program FORMAT A45

 

SELECT s.inst_id,

      s.sid,

      s.serial#,

      p.spid,

      s.username,

      s.program

FROM  gv$session s

      JOIN gv$process p ON p.addr = s.paddr AND p.inst_id = s.inst_id

WHERE s.type != 'BACKGROUND';

 

 

示例:

SQL> SET LINESIZE 100

SQL> COLUMN spid FORMAT A10

SQL> COLUMN username FORMAT A10

SQL> COLUMN program FORMAT A45

SQL> SELECT s.inst_id,

 2         s.sid,

 3         s.serial#,

 4         p.spid,

 5         s.username,

 6         s.program

 7  FROM   gv$session s

 8         JOIN gv$process p ONp.addr = s.paddr AND p.inst_id = s.inst_id

 9  WHERE  s.type != 'BACKGROUND';

 

  INST_ID        SID    SERIAL# SPID       USERNAME   PROGRAM

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

        1        133         22 4816       SYS        sqlplus.exe

        1         21          6 3176       SYS        Toad.exe

        1         19         35 3248       SYS        Toad.exe

 

SQL>

 

 

2.2 ALTER SYSTEM KILL SESSION 说明

Kill session 的基本语法如下:

SQL> ALTER SYSTEM KILL SESSION 'sid,serial#';

 

在RAC 环境下,我们还可以在语法中指定INST_ID. 这个值可以从gv$session 中获取:

SQL> ALTERSYSTEM KILL SESSION 'sid,serial#,@inst_id';

 

Kill session 命令实际不会kill session。 该命令仅要求session 自己kill 自己。 在以前情况下,比如等待远程数据库的反应或者回滚事务,那么session 就不会立即kill 自己,其必须等待当前的操作结束才能执行。 在这种情况下,session 就会被标记为killed 状态。 它会尽快被kill。

 

       我们可以在kill 命令中添加immediate,语法如下:

SQL> ALTERSYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;

 

       这个命令不会影响性能,但它会立即返回到当前的session,处理kill操作,而不是等待其他的信息完成。

 

       如果session 一直处于killed 状态,那么可以考虑在操作系统级别kill掉相关的进程。不过在操作之前,要先确认session 是否在执行rollback 操作。 可以使用如下SQL 来确认。

 

SET LINESIZE 200

COLUMN username FORMAT A15

 

SELECT s.username,

      s.sid,

      s.serial#,

      t.used_ublk,

      t.used_urec,

      rs.segment_name,

      r.rssize,

      r.status

FROM  v$transaction t,

      v$session s,

      v$rollstat r,

      dba_rollback_segs rs

WHERE s.saddr = t.ses_addr

AND   t.xidusn = r.usn

AND   rs.segment_id = t.xidusn

ORDER BY t.used_ublk DESC;

 

如果有我们的session,那么就要等rollback 先完成,然后才能在操作系统级别kill session。

 

2.3 ALTER SYSTEM DISCONNECT SESSION 说明

  Alter system disconnect session 是一个可选的kill session 的方法。 与kill session 命令不同,disconnect session 命令会kill 掉 dedicated server process, 该命令等同于在操作系统级别kill 掉server process。

 

具体语法如下:

SQL> ALTER SYSTEM DISCONNECT SESSION'sid,serial#' POST_TRANSACTION;

SQL> ALTER SYSTEM DISCONNECT SESSION'sid,serial#' IMMEDIATE;

 

POST_TRANSACTION 选项会等待事务完成之后在断开连接。

IMMEDIATE 选项会立即断开连接,然后事务会进行recover操作。

 

2个选项也可以一起使用,但是必须指定其中一个,否则就会报错:

SQL> alter system disconnect session'30,7';

alter system disconnect session '30,7'

                                     *

ERROR at line 1:

ORA-02000: missing POST_TRANSACTION orIMMEDIATE keyword

SQL>

 

SQL> alter system disconnect session'15,12' post_transaction immediate;

System altered.

      

使用alter system disconnectsession 命令就不需要切换到系统来kill session,也从而减少了kill 错进程的几率。

 

2.4 PMON 进程清理KILLEDsession

MOS 上的几篇相关文章:

ALTER SYSTEM KILL Session Marked for KilledForever [ID 1020720.102]

Removing Sessions in Killed Status on Unix[ID 274216.1]

ALTER SYSTEM KILL SESSION does not ReleaseLocks Killing a Thread on Windows NT [ID 100859.1]

 

在之前说过,如果我们使用alter system kill session 命令,是要求session 自己kill 自己,这个过程可能需要等待远程事务的回应或者回滚事务,在这个状态会被标记为killed,并且可能需要等待很长时间,等这些操作完成之后才会kill掉。

 

Killing thesession will not clear the locks.  Thesession on the remote database will remain idle waiting for input until thenetwork read times out. Only then the kill session is processed, and locks arereleased.

 

 

要释放这些状态为killed的session,可以重启DB,也可以直接在OS 级别kill 进程, windows 下使用ORAKILL 命令,UNIX 直接使用kill 命令。

 

       对于这些状态为KILLED的session,PMON 进程也会清理它,MOS的解释如下:

 

It does notexplicitly indicate what happens to the session while it is in the KILLEDPSEUDO state.  What's happening is thatPMON periodically checks to see if any sessions have been killed.

       PMON 会定期的检查是否有session 被标记为killed

 

If it finds one,it attempts to rollback the transaction for that session (that was in progresswhen it was killed).  The reason this cantake a long time is because PMON may have more than one transaction to rollbackat a time (if other sessions have been killed, or if processes have died etc).

--如果PMON 发现了一个被标记为killedsessin,那么PMON 会尝试rollback这个事务。这个操作可能需要很长时间,因为PMON 进程可以一次回滚多个事务。

 

Thus, it maytake a while to finally cleanup the killed session and have it disappear fromthe session monitor.  The system i/omonitor correctly shows the reads and writes being performed by PMON in orderto rollback the session's transaction.

--PMON可能需要很长的时间来清理killed session,从session Monitor就看不到。但是从systemI/O上可以显示PMON 产生的读写。

      

PMON will notdelete the session object itself until the client connected to that sessionnotices that it has been killed. Therefore, the sequence of events is:

   --PMON 不会删除session 对象直到client 再次连接标记为killedsession 时,具体的操作过程顺序如下:

1) alter system kill session is issued -the STATUS of the session object in V$SESSION becomes KILLED, its serverbecomes PSEUDO.

      

2) PMON cleans up the *resources* allocatedto the session

  (i.e., rolls back its transaction, releases its locks, etc).

      

3) the entry in V$SESSION remains thereuntil the client of that session (the client is the process associated with theOSUSER,MACHINE,PROCESS columns in the V$SESSION view) tries to do anotherrequest.

      

4) the client attempts another SQLstatement and gets back ORA-28.

      

5) PMON can now remove the entry from V$SESSION.

  This behavior is necessary because the client still has pointers to thesession object even though the session has been killed.  Therefore, the object cannot be deleted untilthe client is no longer pointing at it.

 

. 在操作系统级别清理killed session 进程

如果标记为KILLED的session 等了很长时间还没有被清理掉,那么只能在OS级别来kill 进程。 注意这里不能kill DB 的进程,否则会导致DB crash。

 

之前整理的Blog就是一个示例,参考:

Oracle 存储过程 无法编译 解决方法

http://blog.csdn.net/tianlesoftware/article/details/7412555

 

3.1 查看seesion的具体信息:

 

SELECT sid, serial#, username,process,machine, terminal, program,

osuser, logon_time, last_call_et

FROM v$session

WHERE username IS NOT NULL

AND status != 'ACTIVE'

ORDER BY last_call_et

/

 

3.2  查看SPID

可以使用如下SQL:

select spid,osuser, s.program

from v$session s,v$process p

where s.paddr=p.addr and s.sid=958;

 

或者:

SELECT s.sid, s.serial#, p.spid

FROM v$session s,v$process p

WHERE s.paddr = p.addr

 

3.3 kill 进程

(1)在Unix 平台下

kill -9

 

(2)Windows 平台

c:\> orakill

 

where   = the Oracle instance name (ORACLE_SID)

      = the thread id of the thread to kill

 

 

 

 

 

 

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

版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

Skype: tianlesoftware

Email:  

Blog:    

Weibo:

Twitter:

Facebook:

Linkedin:

 

 

阅读(1339) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~