在Oracle中,如何定時清理INACTIVE狀態的會話?

  • 2019 年 10 月 10 日
  • 筆記

今天小麥苗給大家分享的是在Oracle中,如何定時清理INACTIVE狀態的會話?

在Oracle中,如何定時清理INACTIVE狀態的會話?

一般情況下,少量的INACTVIE會話對資料庫並沒有什麼影響,但是,如果由於程式設計等某些原因導致資料庫出現大量的會話長時間處於INACTIVE狀態,那麼將會導致大量的系統資源被消耗,造成會話數超過系統SESSION的最大值,出現ORA-00018:maximum number of sessions exceeded錯誤。此時就需要清理那些長時間處於INACTIVE狀態的會話。人為定期檢查、殺掉這類會話肯定不太現實,要定期清理那些長時間處於INACTIVE的會話,可以使用如下幾種辦法:

1. sqlnet.ora文件里加上sqlnet.expire_time,單位為分鐘數。

2. 設置用戶profile的IDLE_TIME參數,需要設置resource_limit為true,然後再設置IDLE_TIME參數,單位為分鐘:

alter system set resource_limit=true; alter profile default limit idle_time 10;

方法2需要和方法1結合使用。

3. 直接KILL掉INACTIVE的會話。V$SESSION視圖中的LAST_CALL_ET欄位表示用戶最後一條語句執行完畢後到sysdate的時間,單位為秒。每次用戶執行一個新的語句後,該欄位複位為0,重新開始記數。可以通過該欄位來獲得一個連接用戶最後一次操作資料庫後的空閑時間。推薦使用這種方法來釋放INACTIVE狀態的會話。具體程式碼如下所示:

set sqlblanklines on    CREATE OR REPLACE PROCEDURE P_kill_session_LHR AS            -----------------------------------------------------------------------------------            -- Created on 2013-06-25 12:05:07 by lhr            --Changed on 2015-08-05 12:05:07 by lhr            -- function:  殺掉10個小時之前的會話 ,告警日誌中會記錄被殺掉的會話資訊            -----------------------------------------------------------------------------------            BEGIN                -- IF to_char(SYSDATE, 'HH24') >= '20' OR            --     TO_CHAR(SYSDATE, 'HH24') <= '08' THEN                FOR cur IN (SELECT A.USERNAME,                               A.LOGON_TIME,                               A.STATUS,                               A.SID,                               A.SERIAL#,                               A.MACHINE,                               A.OSUSER,                           'ALTER SYSTEM  DISCONNECT SESSION ''' || a.SID || ',' ||                           a.serial# || ',@' || a.INST_ID || ''' IMMEDIATE' kill_session                        FROM   gv$session A                        WHERE  A.STATUS IN ('INACTIVE')                        AND    A.USERNAME IS NOT NULL                        AND    A.LAST_CALL_ET >= 60 * 60 * 10) LOOP                    BEGIN                        EXECUTE IMMEDIATE cur.kill_session;                EXCEPTION                    WHEN OTHERS THEN                        NULL;                END;                END LOOP;                -- END IF;            EXCEPTION            WHEN OTHERS THEN                NULL;        END P_kill_session_LHR;    /                BEGIN        --DBMS_SCHEDULER.drop_job('JOB_P_kill_session_LHR');        DBMS_SCHEDULER.CREATE_JOB(JOB_NAME        => 'JOB_P_kill_session_LHR',                                  JOB_TYPE        => 'STORED_PROCEDURE',                                  JOB_ACTION      => 'P_kill_session_LHR',                                  repeat_interval => 'FREQ=MINUTELY;INTERVAL=60',                                  ENABLED         => TRUE,                                  START_DATE      => SYSDATE,                                  COMMENTS        => '刪除--每60分鐘檢查一次');    END;    /  

DB筆試面試歷史連接

http://mp.weixin.qq.com/s/Vm5PqNcDcITkOr9cQg6T7w