天天看點

關于oracle Scheduler的介紹——job

整理自君三思部落格:http://blog.itpub.net/7607759/viewspace-610951

所謂出于job而勝于job,說的就是Oracle 10g後的新特性Scheduler啦。在10g環境中,ORACLE建議使用Scheduler替換普通的job,來管理任務的執行。其實,将Scheduler描述成管理job的工具已經太過片面了,10G版本中新增的Scheduler絕不僅僅是建立任務這麼簡單。。。。

提示:ORACLE中管理Scheduler是通過DBMS_SCHEDULER包,本章也以此為切入點,通過詳細介紹DBMS_SCHEDULER包的使用,來示範如何使用Scheduler。似乎本末倒置了,沒關系,"三思筆記",俺的地盤俺做主。

  所謂JOBS,其實就是Scheduler管理的一個(或多個)任務的執行排程。

  通過DBMS_SCHEDULER包來建立Jobs,是使用其CREATE_JOB過程。在建立Job時,使用者可以指定要執行的任務,排程資訊(啥時候執行,執行周期,終止日期等)以及其它一些任務相關的屬性。CREATE_JOB過程調用還是比較簡單的,例如:

SQL> BEGIN

  2  DBMS_SCHEDULER.CREATE_JOB (

  3     job_name           =>  'INSERT_TEST_TBL',

  4     job_type           =>  'STORED_PROCEDURE',

  5     job_action         =>  ' P_ INSERT INTOTEST ',

  6     start_date         =>  sysdate,

  7     repeat_interval    =>  'FREQ=DAILY;INTERVAL=1');

  8  END;

  9  /

PL/SQL  過程已成功完成。

  事實上,有權限的話,使用者也可以建立其它SCHEMA下的JOB,隻需要在指定JOB_NAME時,按照schema.job_name的格式即可。注意喲,這種情況下建立的JOB,其CREATED與OWNER有可能并不相同的喲。

  當使用CREATE_JOB過程建立JOB時,可指定的參數值很多,隻不過多數情況下使用者僅指定部分參數即可滿足需求。

其中,上例中指定的參數,分别代表的含義如下:

JOB_NAME :指定任務的名稱,必選值,注意要確定指定的名稱唯一。

JOB_TYPE :任務執行的操作類型,必選值,有下列幾個可選值:

PLSQL_BLOCK :表示任務執行的是一個PL/SQL匿名塊。

STORED_PROCEDURE :表示任務執行的是ORACLE過程(含PL/SQL PROCEDURE和JAVA PROCEDURE),本例中正是指定這一參數值。

EXECUTABLE :表示任務執行的是一個外部程式,比如說作業系統指令。

CHAIN :表示任務執行的是一個CHAIN。

JOB_ACTION :任務執行的操作,必選值,應與JOB_TYPE類型中指定的參數相比對。

比如說對于PL/SQL匿名塊,此處就可以放置PL/SQL塊的具體代表,類似DECLARE .. BEGIN ..END這類;如果是ORACLE過程,那麼此處應該指定具體的過程名,注意由于任務執行,即使過程中有OUT之類參數,實際執行時也不會有輸出的。

START_DATE :指定任務初次執行的時間,本參數可為空,當為空時,表示任務立刻執行,效果等同于指定該參數值為SYSDATE。

REPEAT_INTERVAL :指定任務執行的頻率,比如多長時間會被觸發再次執行。本參數也可以為空,如果為空的話,就表示目前設定的任務隻執行一次。

REPEAT_INTERVAL參數需要好好說說,因為這一參數與标準JOB中的INTERVAL參數有很大差別,相比之下,REPEAT_INTERVAL參數的文法結構要複雜的多。其中最重要的是

FREQ和INTERVAL兩個關鍵字。

FREQ 關鍵字用來指定間隔的時間周期,可選參數有:YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, and SECONDLY,分别表示年、月、周、日、時、分、秒等機關。

INTERVAL 關鍵字用來指定間隔的頻繁,可指定的值的範圍從1-99。

例如:REPEAT_INTERVAL=>'FREQ=DAILY;INTERVAL=1';表示每天執行一次,如果将INTERVAL改為7就表示每7天執行一次,效果等同于FREQ=WEEKLY;INTERVAL=1。

一般來說,使用DBMS_SCHEDULER.CREATE_JOB建立一個JOB,至少需要指定上述參數中的前3項。除此之外,還可以在CREATE_JOB時,指定下列參數:

NUMBER_OF_ARGUMENTS :指定該JOB執行時需要附帶的參數的數量,預設值為0,注意當JOB_TYPE列值為PLSQL_BLOCK或CHAIN時,本參數必須設定為0,因為上述兩種情況下不支援附帶參數。

END_DATE :指定任務的過期時間,預設值為NULL。任務過期後,任務的STATE将自動被修改為COMPLETED,ENABLED被置為FALSE。如果該參數設定為空的話,表示該任務永不過期,将一直按照REPEAT_INTERVAL參數設定的周期重複執行,直到達到設定的MAX_RUNS或MAX_FAILURES值。

JOB_CLASS :指定任務關聯的CLASS,預設值為DEFAULT_JOB_CLASS。關于JOB CLASS的資訊就關注本系列的後續文章。

ENABLED :指定任務是否啟用,預設值為FALSE。FALSE狀态表示該任務并不會被執行,除非被使用者手動調用,或者使用者将該任務的狀态修改為TRUE。

AUTO_DROP :當該标志被置為TRUE時,ORACLE會在滿足條件時自動删除建立的任務

任務已過期;

任務最大運作次數已達MAX_RUNS的設定值;

任務未指定REPEAT_INTERVAL參數,僅運作一次;

該參數的預設值即為TRUE。使用者在執行CREATE_JOB過程時可以手動将該标志指定為FALSE,當參數值設定為FALSE時,即使滿足上述提到的條件任務也不會被自動删除,這種情況下,唯一能夠導緻任務被删除的情況,就是使用者主動調用DROP_JOB過程。

COMMENTS :設定任務的注釋資訊,預設值為NULL。

  上面的例子建立了一個新的JOB,不過這個JOB與普通JOB不同喲,此時查詢USER_JOBS視圖是查不到剛剛建立的JOB的資訊,因為這個JOB是SCHEDULER管理的JOB。要查詢SCHEDULER管理的JOS,應該通過USER_SCHEDULER_JOBS(當然ALL_SCHEDULER_JOBS和DBA_SCHEDULER_JOBS也可以),例如:

SQL> select job_name,job_type,job_action,to_char(start_date,'yyyy-mm-dd hh24:mi:ss'),repeat_interval,enabled,state from user_scheduler_jobs;

JOB_NAME             JOB_TYPE         JOB_ACTION                TO_CHAR(START_DATE, REPEAT_INTERVAL                ENABL STATE

-------------------- ---------------- ------------------------- ------------------- ------------------------------ ----- ---------------

INSERT_TEST_TBL      STORED_PROCEDURE P_INSERTINTOTEST          2009-07-27 13:46:50 FREQ=DAILY;INTERVAL=1          FALSE DISABLED

  

關于oracle Scheduler的介紹——job

不過,細心的盆友可能會發現,JOB雖然成功建立了,但卻并未執行,這是怎麼回事?其實原因很簡單,還記的前面介紹CREATE_JOB過程時提到的ENABLED參數嗎,當不顯式指定時,該參數的預設值為false,JOB自然不會運作了。如果遇到這類情形,如何修改呢?

  前面建立JOB時,由于未顯式的指定ENABLED參數,是以即使指定了START_DATE,不過預設情況下JOB不會自動執行。對于這種情況,DBMS_SCHEDULER包中提供了一個過程ENABLE,可以用來修改JOB的啟用狀态,調用方式非常簡單,例如:

SQL>exec dbms_scheduler.enable('INSER_TEST_TAB');

PL/SQL procedure successfully completed.

  DBMS_SCHEDULER.ENABLE 僅用來将JOB(其實不僅僅對JOB有效,對于CHAIN、PROGRAM等也有效)的啟用狀态置為TRUE。如果想将其啟用狀态置為FALSE?簡單,還有一個與該功能對應的過程:DBMS_SCHEDULER.DISABLE,例如:

SQL>exec dbms_scheduler.disable('INSER_TEST_TAB');

PL/SQL procedure successfully completed.

  這兩個過程僅用來重置對象的狀态,是以均可以無限次執行,即使執行時對象已經被置為要指定的狀态。

  由于JOB的屬性衆多,難免時不時的可能會遇到需要修改的情況,比如說前面建立JOB時不小心,指定要執行的過程名輸入錯誤(完全有可能,CREATE_JOB在建立時不會自動檢查指定的過程是否有效,從這方面考慮,SCHEDULER不如普通JOB嚴謹哪),這種情況下就必然涉及到對JOB的修改(或者說重定義),沒問題,DBMS_SCHEDULER包中專門提供了一個過程SET_ATTRIBUTE,可以用來修改任務的屬性值。

  例如,修改剛剛建立的JOB:INSERT_TEST_TBL執行的過程,執行語句如下:

SQL>exec dbms_scheduler.set_attribute('INSERT_TEST_TBL','JOB_ACTION','P_INSERT_INTOTEST2');

PL/SQL procedure successfully completed

  這樣就把 job_action         =>  ' P_ INSERT INTOTEST ',給改了

  SET_ATTRIBUTE 過程雖然僅有三個參數,不過能夠修改的屬性值可是不少,以下列舉幾個較常用到的:

LOGGING_LEVEL :指定對jobs執行情況記錄的日志資訊級别。

SCHEDULER 管理的JOB對任務的執行情況專門進行了記錄,同時使用者還可以選擇日志中記錄資訊的級别,有下列三種選擇:

DBMS_SCHEDULER.LOGGING_OFF :關閉日志記錄功能;

DBMS_SCHEDULER.LOGGING_RUNS :對任務的運作資訊進行記錄;

DBMS_SCHEDULER.LOGGING_FULL :記錄任務所有相關資訊,不僅有任務的運作情況,甚至連任務的建立、修改等也均将記入日志。

提示:檢視SCHEDULER管理的JOB,可以通過USER_SCHEDULER_JOB_LOG和USER_SCHEDULER_JOB_RUN_DETAILS兩個視圖中查詢

RESTARTABLE :指定jobs運作出錯後,是否能夠适時重新開機

建立任務時如未明确指定,本參數預設情況下設定為FALSE,如果設定為TRUE,就表示當任務運作時出錯,下次運作時間點到達時仍會啟動,并且如果運作仍然出錯,會繼續重新運作,不過如果連接配接出錯達到6次,該job就會停止。

MAX_FAILURES :指定jobs最大連續出錯次數

該參數值可指定的範圍從1-1000000,預設情況下該參數設定為NULL,表示無限制。達到指定出錯次數後,該job會被自動disable。

MAX_RUNS :指定jobs最大運作次數

該參數值可指定的範圍從1-1000000,預設情況下該參數設定為NULL,表示無限制(隻是運作次數無限制,實際job會否繼續運作,仍受制于end_date以及max_failures等參數的設定)。達到指定運作次數後,該job也将被自動disable,并且狀态會被置為COMPLETED。

JOB_TYPE :指定job執行的任務的類型

有四個可選值:¨PLSQL_BLOCK¨, ¨STORED_PROCEDURE¨, ¨EXECUTABLE¨, and ¨CHAIN¨。

JOB_ACTION :指定job執行的任務

這一參數所指定的值依賴于JOB_TYPE參數中的值,比如說JOB_TYPE設定為¨STORED_PROCEDURE¨,那麼本參數值中指定的一定是ORACLE中的過程名。

START_DATE :指定job初次啟動的時間

END_DATE :指定job停止運作的時間

  本參數又與AUTO_DROP相關聯,如果AUTO_DROP設定為TRUE的話,那麼一旦job到達停止運作的時間,該job就會被自動删除,否則的話job任何存在,不過狀态被修改為COMPLETED。

  除此之外,其它還包括MAX_RUN_DURATION,JOB_WEIGHT,INSTANCE_STICKINESS,STOP_ON_WINDOW_CLOSE,JOB_PRIORITY,SCHEDULE_LIMIT,PROGRAM_NAME,NUMBER_OF_ARGUMENTS,SCHEDULE_NAME,REPEAT_INTERVAL,JOB_CLASS,COMMENTS,AUTO_DROP,EVENT_SPEC,RAISE_EVENTS等等,這些參數所代表的意義此處不一一詳述,感興趣的朋友可以查閱相關官方文檔,或者等待本系列文章的外傳,黑黑。

  僅從這些可設定屬性就可以看出,Scheduler管理的job确實非常靈活,上述提到了這些參數,均可以使用DBMS_SCHEDULER.SET_ATTRIBUTE過程進行設定。

  另外需要注意一點,除了使用者手動建立的jobs之外,資料庫在運作過程中也有可能自動建立jobs。對于這類jobs除非必要,否則不建議進行修改。至于如何區分jobs是使用者建立,還是資料庫自動建立,可以通過*_SCHEDULER_JOBS視圖的SYSTEM列來确定,如果該列顯示為TRUE,則表示由系統建立

  雖然說jobs大多都應該是自動執行,不過經過前面的示例,大家想必也認識到了,并不是說建立了jobs它就會自動執行,是否能夠真正自動執行并不是由你的主觀意願就能直接決定,而是由jobs自身的多個相關屬性決定。

  關于jobs自動執行的話題相信看完前面的内容後,應該都知道如何設定,下面主要示範,如何手動調用jobs并執行,這其中,當然少不了DBMS_SCHEDULER包。例如,手動執行前面剛剛建立的job:INSERT_TEST_TBL:

SQL> exec dbms_scheduler.run_job('INSERT_TEST_TBL');

  Jobs 每執行一次,無論成功或失敗,均會在*_SCHEDULER_JOB_LOG中生成一條對應的記錄(前提是LOGGING_LEVEL屬性值未設定為DBMS_SCHEDULER.LOGGING_OFF),同時,使用者也可以通過*_SCHEDULER_JOB_RUN_DETAILS視圖查詢job執行的詳細資訊。

  停止job可以使用DMBS_SCHEDULER.STOP_JOB過程,例如:

SQL> exec dbms_scheduler.stop_job('INSER_TEST_TAB');

  注意,STOP_JOB過程不僅僅是更新job的狀态,而是停止目前正在執行的任務,如果你處理的任務目前未在運作的話,那麼執行STOP_JOB過程,會觸發ORA-27366錯誤。

  停止Jobs也會觸發一條任務的日志資訊,對于執行停止操作的job,其*_SCHEDULER_JOB_LOG視圖的OPERATION會記錄為¨STOPPED¨,ADDITIONAL_INFO列中記錄的資訊類似¨REASON="Stop job called by user: username"¨。

  删除建立的job就比較簡單了,直接執行DBMS_SCHEDULER.DROP_JOB過程即可,例如:

SQL> exec dbms_scheduler.drop_job('INSER_TEST_TAB');

  删除jobs并不是修改該job中某個字段的标記值,而是直接删除其在資料字典中的字義,是以被删除的job如果未來發現仍然需要,隻能重建,而無法通過其它方式快速恢複。不過,删除jobs的操作,并不會級聯删除這些job曾經執行過的日志資訊。