oracle 定期清理inactive會話
轉載於http://www.cnblogs.com/kerrycode/p/3636992.html
ORACLE資料庫會話有ACTIVE、INACTIVE、KILLED、 CACHED、SNIPED五種狀態。INACTIVE狀態的會話表示此會話處於非活動、空閒、等待狀態。例如PL/SQL Developer連線到資料庫,執行一條SQL語句後,如果不繼續執行SQL語句,那麼此會話就處於INACTIVE狀態。一般情況下,少量的INACTVIE會話對資料庫並沒有什麼影響,如果由於程式設計等某些原因導致資料庫出現大量的會話長時間處於INACTIVE狀態,那麼將會導致大量的系統資源被消耗,造成會話數超過系統session的最大值,出現ORA-00018:maximum number of sessions exceeded錯誤。
有時候需要清理那些長時間處於INACTIVE狀態的會話。人為定期檢查、殺掉這類會話肯定不太現實,要定期清理那些長時間處於INACTIVE的會話,只能透過作業來實現;另外需要注意,Kill掉這些會話需要需要謹慎,稍不注意,就有可能誤殺了一些正常的會話。那麼我們該如何定義這類會話呢?下面是我結合業務規則定義的:
1: 會話的Status必須為INACTIVE,如果會話狀態為ACTIVE、KILLED、CACHED、SNIPED狀態,不做考慮。
2: 會話必須已經長時間處於INACTIVE狀態。例如,處於INACTIVE狀態超過了兩小時的會話程式,才考慮Kill。這個視具體業務或需求決定,有可能超過半小時就可以殺掉會話程式。至於如何計算處於INACTIVE會話狀態的時間,這個可以 透過V$SESSION的LAST_CALL_ET欄位來判別,需要查詢處於INACTIVE狀態兩小時或以上的會話,就可以透過查詢條件S.LAST_CALL_ET >= 60*60*2實現,當然最好寫成 S.LAST_CALL_ET >= 7200
3: 連線到會話的程式。比如,某個特定的應用程式產生的INACTIVE會話才要清理。例如, Toad工具、PL/SQL Developer工具。關於PROGRAM這個需要根據當前專案的具體情況設定,下面僅僅使用TOAD.EXE、W3WP.EXE舉例說明。
1: SELECT SID, SERIAL#,MODULE, STATUS
2: FROM V$SESSION S
3: WHERE S.USERNAME IS NOT NULL
4: AND UPPER(S.PROGRAM) IN ('TOAD.EXE', 'W3WP.EXE')
5: AND S.LAST_CALL_ET >= 60*60*2
6: AND S.STATUS = 'INACTIVE'
7: ORDER BY SID DESC;
如果是RAC環境,那麼最好使用下面SQL語句,使用全域性檢視GV$SESSION。
1: SELECT SID, SERIAL#, INST_ID, MODULE,STATUS
2: FROM gv$session S
3: WHERE S.USERNAME IS NOT NULL
4: AND UPPER(S.PROGRAM) IN ('TOAD.EXE', 'W3WP.EXE')
5: AND S.LAST_CALL_ET >= 2 * 60*60
6: AND S.STATUS = 'INACTIVE'
7: ORDER BY INST_ID DESC
接下來建立儲存過程SYS.DB_KILL_IDLE_CLIENTS. 方便呼叫該功能執行kill inactive 會話。注意:xxx部分用實際業務的PROGRAM來替代。
1:
2: CREATE OR REPLACE PROCEDURE SYS.DB_KILL_IDLE_CLIENTS AUTHID DEFINER AS
3: job_no number;
4: num_of_kills number := 0;
5: BEGIN
6:
7: FOR REC IN
8: (SELECT SID, SERIAL#, INST_ID, MODULE,STATUS
9: FROM gv$session S
10: WHERE S.USERNAME IS NOT NULL
11: AND UPPER(S.PROGRAM) IN ('xxx', 'xxx.EXE')
12: AND S.LAST_CALL_ET >= 2*60*60
13: AND S.STATUS= 'INACTIVE'
14: ORDER BY INST_ID ASC
15: ) LOOP
16: ---------------------------------------------------------------------------
17: -- kill inactive sessions immediately
18: ---------------------------------------------------------------------------
19: DBMS_OUTPUT.PUT('LOCAL SID ' || rec.sid || '(' || rec.module || ')');
20: execute immediate 'alter system kill session ''' || rec.sid || ', ' ||
21: rec.serial# || '''immediate' ;
22:
23: DBMS_OUTPUT.PUT_LINE('. killed locally ' || job_no);
24: num_of_kills := num_of_kills + 1;
25: END LOOP;
26: DBMS_OUTPUT.PUT_LINE ('Number of killed xxxx system sessions: ' || num_of_kills);
27: END DB_KILL_IDLE_CLIENTS;
28: /
另外,由於kill session是直接將session kill掉,有可能出現導致事物回滾的現象,其實我們可以使用disconnect session完成當前事務並終止session。這種方式比alter system kill session跟安全可靠。
1: CREATE OR REPLACE PROCEDURE SYS.DB_KILL_IDLE_CLIENTS AUTHID DEFINER AS
2: job_no number;
3: num_of_kills number := 0;
4: BEGIN
5:
6: FOR REC IN
7: (SELECT SID, SERIAL#, INST_ID, MODULE,STATUS
8: FROM gv$session S
9: WHERE S.USERNAME IS NOT NULL
10: AND UPPER(S.PROGRAM) IN ('xxxx', 'xxxx')
11: AND S.LAST_CALL_ET >= 2*60*60
12: AND S.STATUS<>'KILLED'
13: ORDER BY INST_ID ASC
14: ) LOOP
15: ---------------------------------------------------------------------------
16: -- kill inactive sessions immediately
17: ---------------------------------------------------------------------------
18: DBMS_OUTPUT.PUT('LOCAL SID ' || rec.sid || '(' || rec.module || ')');
19: execute immediate 'alter system disconnect session ''' || rec.sid || ', ' ||
20: rec.serial# || '''immediate' ;
21:
22: DBMS_OUTPUT.PUT_LINE('. killed locally ' || job_no);
23: num_of_kills := num_of_kills + 1;
24: END LOOP;
25: DBMS_OUTPUT.PUT_LINE ('Number of killed system sessions: ' || num_of_kills);
26: END DB_KILL_IDLE_CLIENTS;
27: /
然後,我們可以在作業(JOB)或Schedule裡面定期呼叫該儲存過程,也可以透過後臺作業結合shell指令碼實現定期清理空閒會話的功能。例如如下所示。
建立killSession.sh指令碼,呼叫該儲存過程SYS.DB_KILL_IDLE_CLIENTS
1: #!/bin/bash
2:
3:
4:
5: logfile=/home/oracle/cron/session/log/killSession.log
6:
7: echo " " >> $logfile 2>&1
8: echo "START ----`date`" >> $logfile 2>&1
9: sqlplus /nolog <<STATS
10: connect / as sysdba
11: exec sys.db_kill_idle_clients;
12: exit;
13: STATS
14:
15: echo "END ------`date`" >> $logfile 2>&1
在crontab裡面配置後臺作業,每隔15分鐘執行一次,清理哪些滿足條件的空閒會話。
0,15,30,45 * * * * /home/oracle/cron/session/bin/killSession.sh >/dev/null 2>&1
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25462274/viewspace-1979035/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 資料庫會話數量過多,定期清理inactive會話資料庫會話
- 在Oracle中,如何定時清理INACTIVE狀態的會話?Oracle會話
- Oracle:select 或 inactive 會話語句產生鎖?Oracle會話
- 自動清理Dead Connections And INACTIVE SessionsSession
- Oracle 會話(Session)Oracle會話Session
- oracle鎖會話Oracle會話
- ELK日誌定期清理 ES索引資料索引
- 如何定期清理DNS快取?清理DNS快取有什麼用?DNS快取
- ?ORACLE會話超時Oracle會話
- Oracle跟蹤會話Oracle會話
- oracle 會話,連線Oracle會話
- oracle的會話如何自殺?Oracle會話
- Oracle阻塞會話查詢Oracle會話
- oracle session(會話) 跟蹤OracleSession會話
- 【會話】Oracle kill session系列會話OracleSession
- oracle遭遇大量SNIPED會話Oracle會話
- 雲伺服器mysql定期清理bin-log檔案伺服器MySql
- 建立定期清理listener,trace檔案的shell指令碼指令碼
- oracle中會話的狀態Oracle會話
- 配置計劃任務定期清理資料庫trc檔案資料庫
- oracle定期清空回收過程Oracle
- oracle 定期表及索引分析Oracle索引
- oracle實用sql(7)--單個會話或會話間statistics對比OracleSQL會話
- Oracle會話超時退出設定Oracle會話
- oracle 10046當前會話Oracle會話
- Oracle kill會話--sed修改檔案Oracle會話
- oracle會話監控shell指令碼Oracle會話指令碼
- oracle碎片清理Oracle
- 過期資料的定期清理機制來提高系統穩定性
- Check_oracle_health 之阻塞會話數Oracle會話
- ORACLE快速徹底Kill掉的會話Oracle會話
- Oracle 查詢當前會話標識Oracle會話
- 修改oracle會話時間表達方式Oracle會話
- -t【Oracle-故障管理】-Trace跟蹤會話和會話執行慢故障分析Oracle會話
- 【Oracle】How To Automate Cleanup Of Dead Connections And INACTIVEOracle
- Oracle:審計清理Oracle
- 輕鬆搞定對容器例項日誌設定定期清理和回捲
- Oracle查詢當前會話的sidOracle會話