為什麼 dbms_scheduler max_run_duration 不引發事件 JOB_OVER_MAX_DUR?
從這個問題和這個例子開始,我嘗試創建一個基於事件的
dbms_scheduler
作業,它等待JOB_OVER_MAX_DUR
從作業引發的事件,這超出了他們的max_run_duration
.不幸的是,我無法讓該範例適用
JOB_OVER_MAX_DUR
於 Oracle 10gR2中某個特定 box 上的事件。我試過的是:
-- create log table create table job_output (a timestamp with time zone, b varchar2(1000)); -- add an event queue subscriber for this user's messages exec dbms_scheduler.add_event_queue_subscriber('myagent') -- create a sniper procedure create or replace procedure sniper_proc (message IN sys.scheduler$_event_info) as begin -- insert into job_output values (systimestamp,'sniper job started for ' ||message.event_type||' from ' ||'"'||message.object_owner||'"."'||message.object_name ||'"'); commit; end; / -- create a sniper program begin dbms_scheduler.create_program ( program_name => 'sniper_prog', program_action=> 'sniper_proc', program_type => 'stored_procedure', number_of_arguments => 1, enabled => FALSE) ; -- dbms_scheduler.define_metadata_argument ('sniper_prog','event_message',1); dbms_scheduler.enable('sniper_prog'); end; / -- create a general purpose sniper job to log any job that has -- raised an event begin dbms_scheduler.create_job('sniper_job', program_name=>'sniper_prog', event_condition => 'tab.user_data.event_type = ''JOB_OVER_MAX_DUR'' OR tab.user_data.event_type = ''JOB_SUCCEEDED''', queue_spec =>'sys.scheduler$_event_queue,myagent', enabled=>true); end; / -- create job to test the sniper job begin dbms_scheduler.create_job ( 'first_job', job_action => 'insert into job_output values(systimestamp, ''first job begins''); commit; dbms_lock.sleep(120); insert into job_output values(systimestamp, ''first job ends'');', job_type => 'plsql_block', enabled => false ) ; -- set max runtime dbms_scheduler.set_attribute ( 'first_job' , 'max_run_duration' , interval '60' second); -- set all events to be raised (for debugging) dbms_scheduler.set_attribute( name => 'first_job', attribute => 'raise_events', value => dbms_scheduler.job_all_events); -- start the job dbms_scheduler.enable('first_job'); end; /
由於某種原因,該事件
JOB_OVER_MAX_DUR
要麼沒有被引發,要麼 sniper_job 沒有收到它。只JOB_SUCCEEDED
收到。我的日誌表如下所示:
SELECT * FROM job_output ORDER BY 1 DESC; 25.07.2012 10:39:11,475879 +02:00 sniper job started for JOB_SUCCEEDED from "SCOTT"."FIRST_JOB" 25.07.2012 10:39:10,155557 +02:00 first job ends 25.07.2012 10:37:10,142660 +02:00 first job begins
所以沒有
JOB_OVER_MAX_DUR
收到任何事件。任何想法我做錯了什麼或我必須檢查/設置哪些初始化參數或如何調試這些事件?
**編輯:**我很感興趣為什麼這在 10g 中不起作用。此範例在 11g 中執行良好,但在 10g 中執行良好,我看不出任何原因。
**編輯 2:**該範例在不同的 10g 盒子上執行良好,但在預期的盒子上卻不是。我已經檢查了所有的
%scheduler%
字典視圖,但沒有一個提供有關已引發哪些事件的詳細資訊。任何想法/提示如何調試調度程序事件?在這種情況下,我擁有 DBA 權限和 OS 伺服器級別的調試權限。
添加多個屬性時,請嘗試:
DBMS_SCHEDULER.set_attribute( name => 'first_job', attribute => 'raise_events', value => DBMS_SCHEDULER.job_succeeded + DBMS_SCHEDULER.some_attribute);
事件類型 (11gr2) 的有效值在此處。根據文件,job_over_max_dur 已經為 11gr2 啟用。
現在,對於 10g 或11gr1,我在調度程序引發的事件類型列表中看不到 job_over_max_dur 。但是您在之前的文章中提到您將很快遷移到 11gr2,所以我假設您已經有一個測試盒設置,您可以使用 11gr2 進行測試。如果您真的想在 AQ 上陷入困境,您可以做更多的自定義事件,但等到 11gr2 之前可能會更容易。
編輯
要添加更多資訊,首先您可以查看一些基本的調度程序內容以查看正在執行的內容(或已調度、已停止或任何狀態):
select * from dba_scheduler_jobs where owner = 'SOME_OWNER' and job_name = 'SOME_JOB';
您可以查看是否設置了 max_run_duration 列,並且“raise_events”列將顯示每個作業要引發的事件類型列表。您應該在此處看到“JOB_OVER_MAX_DUR”類型。
如果您想測試您的數據庫環境是否正確處理 JOB_OVER_MAX_DUR,那麼您可以設置一個快速測試:
BEGIN -- setup simple scheduler job --DBMS_SCHEDULER.DROP_JOB('EVENT_RAISING_JOB',false); DBMS_SCHEDULER.create_job ( job_name => 'EVENT_RAISING_JOB', job_type => 'PLSQL_BLOCK', job_action => 'BEGIN dbms_lock.sleep(70); END;', start_date => SYSTIMESTAMP, end_date => SYSTIMESTAMP + 2, -- 2 day repeat_interval => 'freq=daily; byhour=1', enabled => TRUE); DBMS_SCHEDULER.set_attribute(name=>'event_raising_job', attribute=>'max_run_duration', value=>interval '60' second); DBMS_SCHEDULER.set_attribute(name => 'event_raising_job', attribute => 'raise_events',value => DBMS_SCHEDULER.job_all_events ); END; -- setup email notification exec dbms_scheduler.add_job_email_notification( job_name=>'EVENT_RAISING_JOB',recipients=>'someuser@somedomain.com', events=>'job_all_events'); -- launch job exec dbms_scheduler.run_job('EVENT_RAISING_JOB',false);
您應該收到 3 封電子郵件表明該工作:STARTED、SUCCEEDED 和 JOB_OVER_MAX_DUR
JOB_OVER_MAX_DUR 事件直到 11.2 才在文件中列出,即使 MAX_RUN_DURATION 在更早的版本中可用。
此外:
DBMS_SCHEDULER.JOB_ALL_EVENTS
在 11.2 上不包括JOB_OVER_MAX_DUR
(儘管名稱)。- 設置
RAISE_EVENTS
屬性既不會設置也不會刪除JOB_OVER_MAX_DUR
事件。似乎可以設置標誌的唯一方法是設置
MAX_RUN_DURATION
為非空值。相反,刪除它的唯一方法是將其設置MAX_RUN_DURATION
為 null。至於為什麼在 10.2 中甚至從未引發該事件,我懷疑該事件最初可能只是針對電子郵件通知實現的,而不是其他事件偵聽器。這似乎與我在 Oracle Support 上發現的一個錯誤有關(錯誤 #8792892);這意味著在工作鏈中使用事件的類似問題直到 11.2 才修復。