联系:手机/微信(+86 17813235971) QQ(107644445)
作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]
在很多使用,因为各种原因,我们需要定时批量的kill一部分session,用来释放数据库部分资源,这里是因为bug导致temp不能正常释放,也可能是因为bug导致pga不释放,还有可能是因为太多inactive占用资源等等.我这里提供了两种方法来实现该功能
存储过程实现kill session
--创建记录表 CREATE TABLE kill_session_record ( kill_time DATE, kill_statement VARCHAR2 (1000) ) / --创建kill session存储过程 CREATE OR REPLACE PROCEDURE kill_inactive_session IS CURSOR c IS SELECT sid, serial# FROM v$session s WHERE s.status = 'INACTIVE' AND s.username = 'XIFENFEI'; k_sid NUMBER; k_serial NUMBER; BEGIN OPEN c; FETCH c INTO k_sid, k_serial; WHILE c%FOUND LOOP BEGIN EXECUTE IMMEDIATE 'ALTER SYSTEM DISCONNECT SESSION ''' || k_sid || ',' || k_serial || ''' IMMEDIATE'; INSERT INTO kill_session_record (kill_time, kill_statement) VALUES ( SYSDATE, 'ALTER SYSTEM DISCONNECT SESSION ''' || k_sid || ',' || k_serial || ''' IMMEDIATE'); EXCEPTION WHEN OTHERS THEN INSERT INTO kill_session_record (kill_time, kill_statement) VALUES ( SYSDATE, 'Failure:ALTER SYSTEM DISCONNECT SESSION ''' || k_sid || ',' || k_serial || ''' IMMEDIATE'); COMMIT; END; FETCH c INTO k_sid, k_serial; END LOOP; COMMIT; CLOSE c; END; / --设置job定时运行 DECLARE job NUMBER; BEGIN sys.DBMS_JOB.submit (job, what => 'kill_inactive_session;', next_date => SYSDATE, interval => 'TRUNC(SYSDATE + 1) +7/24'); COMMIT; DBMS_OUTPUT.put_line (job); END; /
如果是10GR2之前版本,需要把ALTER SYSTEM DISCONNECT SESSION 换成ALTER SYSTEM KILL SESSION
shell kill session
--shell脚本 # more kill_inactive_session.sh #!/bin/sh tmpfile0=/tmp/.kill_inactive_0 tmpfile1=/tmp/.kill_inactive_1 tmpfile2=/tmp/.kill_inactive_2 sqlplus / as sysdba <<EOF spool $tmpfile1 select 'kill time:'||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') execute_time from dual; select p.spid,s.sid,s.serial# from v\$process p,v\$session s where s.paddr=p.addr and username='XIFENFEI' and s.status='INACTIVE'; spool off EOF cat $tmpfile1>>$tmpfile0 grep "^[0123456789]" $tmpfile1 |awk '{print $1}'>$tmpfile2 for x in `cat $tmpfile2` do kill -9 $x done rm $tmpfile1 $tmpfile2 --contab 调度 00 07 * * * /u01/script/kill_inactive_session.sh
两个脚本都可以在where中加一些限制条件,来实现你需要kill的会话.数据库级别kill相对系统级别来说更加温和点,建议优先考虑数据库级别kill session.如果要求立即释放资源,可能需要考虑系统级别.两中kill方式对于未提交且是inactive session都会被kill掉,然后回滚事务.
建议在数据库中操作的方法,要记录下来OS上的spid,否则如果出现session不在了,但是spid还在的情况,还要再处理很麻烦不说,也起不到作用啊…………
“ 换成ALTER SYSTEM KILL SESSION”,这个需要增加spid的内容