Oracle清除資料庫中長時間佔用資源的非活動的會話
首先我們瞭解下,會話有那些狀態:
1、active
此狀態的會話,表示正在執行,處於活動狀態。
2、killed
此狀態的會話,被標註為刪除,表示出現了錯誤,正在回滾,當然,也是佔用系統資源的。還有一點就是,killed的狀態一般會持續較長時間,而且用windows下的工具pl/sql developer來kill掉,是不管用的,要用命令:alter system kill session 'sid,serial#' ;
3、inactive
該狀態處於等待操作(即等待需要執行的SQL語句),通常當DML語句已經完成。 但連線沒有釋放,這個可能是程式中沒有釋放,如果是使用中介軟體來連線的話,也可能是中介軟體的配置或者是bug 導致。
4、SNIPED- Session inactive, waiting on the client
其它說明:
inactive對資料庫本身沒有什麼影響,但是如果程式沒有及時commit,那麼就會造成佔用過多會話。容易是DB 的session 達到極限值。
他們的做法是不處理inactive 狀態的session, 如果達到了session 的最大值, 就增加processes 和 sessions 引數。 如果kill inactive session 可能會到中介軟體有影響。
下面講怎麼清除長時間的會話數:
1、啟動資源計劃
alter system set resource_limit=true scope=spfile;
2、設定非活動回話十五分鐘斷開,釋放資源
alter profile default limit idle_time 15;
3. 清楚非活動的程序 (沒10分鐘傳送檢測包)
$ORACLE_HOME/network/admin 新增 SQLNET.EXPIRE_TIME=10;
SELECT SID, SERIAL#,MODULE, STATUS
FROM V$SESSION S
WHERE S.USERNAME ISNOTNULL
ANDUPPER(S.PROGRAM) IN ('TOAD.EXE', 'W3WP.EXE')
AND S.LAST_CALL_ET >= 60*60*2
AND S.STATUS = 'INACTIVE'
ORDERBY SID DESC;
如果是RAC環境,那麼最好使用下面SQL語句,使用全域性檢視GV$SESSION。
SELECT SID, SERIAL#, INST_ID, MODULE,STATUS
FROM gv$session S
WHERE S.USERNAME ISNOTNULL
ANDUPPER(S.PROGRAM) IN ('TOAD.EXE', 'W3WP.EXE')
AND S.LAST_CALL_ET >= 2 * 60*60
AND S.STATUS = 'INACTIVE'
ORDERBY INST_ID DESCCREATE OR REPLACE PROCEDURE SYS.DB_KILL_IDLE_CLIENTS AUTHID DEFINER AS job_no number; num_of_kills number := 0; BEGIN FOR REC IN (SELECT SID, SERIAL#, INST_ID, MODULE,STATUS FROM gv$session S WHERE S.USERNAME IS NOT NULL AND UPPER(S.PROGRAM) IN ('xxx', 'xxx.EXE') AND S.LAST_CALL_ET >= 2*60*60 AND S.STATUS= 'INACTIVE' ORDER BY INST_ID ASC ) LOOP --------------------------------------------------------------------------- -- kill inactive sessions immediately --------------------------------------------------------------------------- DBMS_OUTPUT.PUT('LOCAL SID ' || rec.sid || '(' || rec.module || ')'); execute immediate 'alter system kill session ''' || rec.sid || ', ' || rec.serial# || '''immediate' ; DBMS_OUTPUT.PUT_LINE('. killed locally ' || job_no); num_of_kills := num_of_kills + 1; END LOOP; DBMS_OUTPUT.PUT_LINE ('Number of killed xxxx system sessions: ' || num_of_kills); END DB_KILL_IDLE_CLIENTS; /
然後,我們可以在作業(JOB)或Schedule裡面定期呼叫該儲存過程,也可以通過後臺作業結合shell指令碼實現定期清理空閒會話的功能。例如如下所示。
建立killSession.sh指令碼,呼叫該儲存過程SYS.DB_KILL_IDLE_CLIENTS
#!/bin/bash
logfile=/home/oracle/cron/session/log/killSession.log
echo " " >> $logfile 2>&1
echo "START ----`date`" >> $logfile 2>&1
sqlplus /nolog <<STATS
connect / as sysdba
exec sys.db_kill_idle_clients;
exit;
STATS
echo "END ------`date`" >> $logfile 2>&1
最後在系統任務中增加:
在crontab裡面配置後臺作業,每隔15分鐘執行一次,清理哪些滿足條件的空閒會話。
0,15,30,45 * * * * /home/oracle/cron/session/bin/killSession.sh >/dev/null 2>&1