在Oracle資料庫實現自動斷開空閒連線

2021-08-27 14:26:05 字數 3373 閱讀 5048

在實際的資料庫應用中,我們經常遇到這樣乙個問題,連線到oracle資料庫的使用者在作了一次操作後,再也沒有後續操作,但卻長時間沒有和資料庫斷開連線。對於乙個小型的應用系統來講,本身的連線數目就有限,這好像沒有什麼嚴重的後果,但如果對於乙個大型的資料庫應用。如稅務、工商等,如果資料庫的連線數目很多,對於資料庫伺服器來講,多乙個連線就要多消耗乙份資源,如果大量使用者連線進入資料庫系統但卻不進行任何的操作,這無形之中就白白造成了伺服器系統資源的浪費,同時造成伺服器負載的提高,對於那些確實在工作的使用者來講,就不能最大限度的利用伺服器的資源,嚴重情況下可能造成系統效能的急劇下降。

一、識別系統中超過一定空閒時間的連線

要實現後台任務自動對超過一定時間空閒連線的處理,首先第一步工作就是要從所有與資料庫伺服器的連線中識別出那些連線需要處理,也就是需要獲得與伺服器連線的每個使用者的登陸時間及其最後一次操作後的空閒時間。在oracle系統中,有乙個動態效能檢視v$session,該檢視儲存著系統當前連線的各種動態資訊。其中,有兩個欄位logon_time和last_call_et可以得到上面的兩個答案。

logon_time是乙個日期型(date)字段,為使用者登陸時間;

last_call_et是乙個數字型(number)字段,其含義是使用者最後一條語句執行完畢後的時間,單位為秒。每次使用者執行乙個新的語句後,該欄位復位為0,重新開始記數。我們可以通過該字段來獲得乙個連線使用者最後一次運算元據庫後的空閒時間。

下面的sql查詢語句可以得到與當前資料庫連線的所有使用者的一些基本情況,如使用者名稱、狀態、連線機器的名稱,作業系統中使用者的名稱,unix系統的程序號,在unix作業系統級斷開連線的語句,oracle資料庫系統斷開連線的語句,登陸時間以及最後一次操作到現在的空閒時間等等。

select s.username 使用者名稱, s.status狀態,s.machine 機器名稱,osuser 作業系統使用者名稱,spidunix程序號:

'kill -9 '||spid unix級斷開連線,

'alter system kill session ' ||''''||s.sid||',

'||s.serial# || ''';' oracle級斷開連線,

to_char (logon_time, 'dd/mm/yyyy hh24:mi:ss') 登陸時間,

last_call_et 空閒時間秒,

to_char (trunc (last_call_et / 3600, 0))||' '||' hrs '||

to_char (

trunc ((last_call_et - trunc

(last_call_et / 3600, 0) * 3600) / 60, 0)

) ||' mins' 空閒時間小時分鐘,

module 模組

from v$session s, v$process p

where type = 'user'

and p.addr = s.paddr

and status != 'killed'

-- and substr (machine, 1, 19) not in ('機器名')

and last_call_et > 60 * 60 * 1

-- 空閒時間超過1小時的連線

order by last_call_et desc;

在上面的查詢中,我們可以通過substr(machine, 1, 19) not in('機器名')這個條件來遮蔽一些機器,這些機器可能需要執行一些耗費很長時間的sql語句或其他一些特殊情況的機器。遮蔽這些機器的原因就是在後面的後台自動識別及處理任務中對這些機器不作處理。

二、識別及斷開空閒使用者的儲存過程

上面的查詢語句可以得到系統中所有的連線使用者的一些基本情況,但是又如何來實現系統自動判斷空閒超過一定時間的連線並將其自動斷開呢?oracle系統提供了一種稱之為後台任務(job)自動處理的機制。我們可以編寫乙個後台任務來定時執行,從而判斷是否存在這樣的使用者連線,如果存在,則通過後台任務將其自動斷開。

首先建立乙個儲存過程來完成空閒一定時間使用者的識別和斷開工作,然後新增乙個後台任務來定時(根據空閒時間長短來確定)執行該過程,即可實現自動斷開系統中空閒超過一定時間使用者的需求。

儲存過程p_monitor見下,其中引數an_nimutes為使用者輸入引數,用來確定識別和斷開多長空閒時間連線的使用者,單位為分鐘,預設為60分鐘,也就是1小時。需要注意一點的是,該儲存過程,需要以sys使用者身份執行。相應,呼叫該儲存過程的後台任務也需要以sys身份來新增。

create or replace procedure p_monitor(

an_minutes number default 60)

as v_str varchar2(100);

cursor c_users(v_minutes number) is  select s.username,

s.status, s.machine, 'alter system kill session '

||''''||s.sid||','||s.serial# ||'''' operates

from v$session s, v$process p

where type = 'user'

and p.addr = s.paddr

and status != 'killed'

-- and substr (machine, 1, 19) not in ('需要遮蔽不被處理的機器名')

and last_call_et > v_minutes*60

order by last_call_et desc;

begin

for t_users in c_users(an_minutes) loop

v_str := t_users.operates;

execute immediate v_str;

end loop;

end;

/

三、後台任務的定時執行

最後,我們為系統新增乙個定時任務,定時呼叫上面建立的儲存過程,即可完成系統自動識別和處理空閒使用者的工作。

下面是乙個實際呼叫的例子,在sys使用者下,首先新增乙個任務,該任務每隔半小時執行一次,每次均呼叫p_monitor儲存過程,找出系統中空閒時間超過1小時的連線,然後自動斷開。

declare

jobno number;

begin

dbms_job.submit(

job => jobno,

what => 'p_monitor(60);',

next_date => sysdate,

interval => ' sysdate + 30/1440); -- 每半小時執行一次

end;

/

在Oracle資料庫實現自動斷開空閒連線

在實際的資料庫應用中,我們經常遇到這樣乙個問題,連線到oracle資料庫的使用者在作了一次操作後,再也沒有後續操作,但卻長時間沒有和資料庫斷開連線。對於乙個小型的應用系統來講,本身的連線數目就有限,這好像沒有什麼嚴重的後果,但如果對於乙個大型的資料庫應用。如稅務 工商等,如果資料庫的連線數目很多,對...

在Oracle資料庫實現自動斷開後再連線

在實際的資料庫應用中,我們經常遇到這樣乙個問題,連線到oracle資料庫的使用者在作了一次操作後,再也沒有後續操作,但卻長時間沒有和資料庫斷開連線。對於乙個小型的應用系統來講,本身的連線數目就有限,這好像沒有什麼嚴重的後果,但如果對於乙個大型的資料庫應用。如稅務 工商等,如果資料庫的連線數目很多,對...

在 Oracle 資料庫中實現 MapReduce

在程式設計師開發並行程式時,map reduce模式正變得流行起來。這些map reduce程式通常來並行處理大量資料。本文來演示如何在oracle資料庫上,通過使用parallel pipelined table函式及並行操作,來實現map reduce程式。譯者注 table 是oracle中乙...