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
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.
killed处于此状态的会话,被标注为删除,表示出现了错误,正在回滚。
当然,也是占用系统资源的。还有一点就是,killed的状态一般会持续较长时间,而且用windows下的工具pl/sql developer来kill掉,是不管用的,要用命令:alter system kill session 'sid,serial#' ;
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 也是一个危险的操作,所以在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>
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。
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 错进程的几率。
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 发现了一个被标记为killed的sessin,那么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 再次连接标记为killed的session 时,具体的操作过程顺序如下:
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 等了很长时间还没有被清理掉,那么只能在OS级别来kill 进程。 注意这里不能kill DB 的进程,否则会导致DB crash。
之前整理的Blog就是一个示例,参考:
Oracle 存储过程 无法编译 解决方法
http://blog.csdn.net/tianlesoftware/article/details/7412555
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
/
可以使用如下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
(1)在Unix 平台下
kill -9 <spid>
(2)Windows 平台
c:\> orakill <SID> <spid>
where <SID> = the Oracle instance name (ORACLE_SID)
<spid> = the thread id of the thread to kill
-------------------------------------------------------------------------------------------------------
版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!
Skype: tianlesoftware
Email: [email protected]
Blog: http://www.tianlesoftware.com
Weibo: http://weibo.com/tianlesoftware
Twitter: http://twitter.com/tianlesoftware
Facebook: http://www.facebook.com/tianlesoftware
Linkedin: http://cn.linkedin.com/in/tianlesoftware
-------加群需要在备注说明Oracle表空间和数据文件的关系,否则拒绝申请----
DBA1 群:62697716(满); DBA2 群:62697977(满) DBA3 群:62697850(满)
DBA 超级群:63306533(满); DBA4 群:83829929 DBA5群: 142216823
DBA6 群:158654907 DBA7 群:172855474 DBA总群:104207940