如何安全快速的批量删除Oracle数据库外部会话session

在ORACLE数据库杀掉会话进程有三种方式:
1:ALTER SYSTEM KILL SESSION
关于KILL SESSION Clause ,官方文档描述alter system kill session实际上不是真正的杀死会话,它只是将会话标记为终止。等待PMON进程来清除会话。
可以使用如下方式来快速回滚事物、释放会话的相关锁、立即返回当前会话的控制权。

SQL> ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE
Specify IMMEDIATE to instruct Oracle Database to roll back ongoing transactions, release all session locks, recover the entire session state, and return control to you immediately.

2:ALTER SYSTEM DISCONNECT SESSION
ALTER SYSTEM DISCONNECT SESSION 杀掉专用服务器(DEDICATED SERVER)或共享服务器的连接会话,它等价于从操作系统杀掉进程。它有两个选项POST_TRANSACTION和IMMEDIATE, 其中POST_TRANSACTION表示等待事务完成后断开会话,IMMEDIATE表示中断会话,立即回滚事务。

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

3:KILL -9 SPID(Linux)或orakill ORACLE_SID spid(Windows)
可以使用下面SQL语句找到对应的操作系统进程SPID,然后杀掉。当然杀掉操作系统进程是一件危险的事情,尤其不要误杀。所以在执行前,一定要谨慎确认。

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';

在数据库如果要彻底杀掉一个会话,尤其是大事务会话,最好是使用两种方式:

  1. 使用ALTER SYSTEM DISCONNECT SESSION IMMEDIATE
  2. OS层操作,使用下面步骤:
    1:首先在操作系统级别Kill掉进程。
    2:在数据库内部KILL SESSION
    或者反过来亦可。这样可以快速终止进程,释放资源。

针对方法1,可以使用如下
#oracle中批处理删除外部连接session

SET LINESIZE 100
COLUMN spid FORMAT A10
COLUMN username FORMAT A10
COLUMN program FORMAT A45

declare cursor mycur is 
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' and s.username not like '%SYS%';

SYS@groupts>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' and s.username not like '%SYS%';   
INST_ID   SID     SERIAL# SPID      USERNAME   PROGRAM
 1        817      28719 20371      TEST_LY    sqlplus@GBACKUP (TNS V1-V3)

begin 
for cur in mycur 
loop 
execute immediate ( 'alter system kill session '''||cur.sid || ','|| cur.SERIAL# ||''' '); 
end loop; 
end; 
/

#根据计算机名批量删除会话,具体删除条件可以自行调整上面的查询语句

declare cursor mycur is 
select b.sid,b.serial# from v$session b where b.MACHINE = 'svctag-79bp23x' and b.STATUS = 'INACTIVE';
begin 
for cur in mycur 
loop 
execute immediate ( 'alter system kill session '''||cur.sid || ','|| cur.SERIAL# ||''' '); 
end loop; 
end; 
/

【Notes】

1.本文讲述了oracle数据库上执行shutdown immediate命令时执行时间过长的原因以及解决办法;
2.实际生产中推荐两种方法批量删除会话:
方法1:

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

方法2:

ps aux | grep "LOCAL=NO" | awk '{printf "%s\n",$2}'|xargs kill -9;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章