調度例行任務

利用新的任務調度程序解放 DBA 的時間。

例行任務是單調和令人厭煩的。如果你以手動方式執行這些例行任務,則你不得不緊張地一次又一次地重複執行相同的任務,並且還存在一種風險,就是某一天你可能會忽略、錯過其一個步驟,或者犯其它錯誤。Oracle數據庫10g新的內置任務調度程序爲你提供了調度例行任務的強大功能。利用這一調度程序,你可以規定要完成的工作、指定什麼時候完成該工作,並監測該工作的完成情況,以便能糾正任何問題。你甚至可以控制分配給您所調度的任務的數據庫資源和優先級,以確保首先完成最重要的工作,而不會對其它系統的活動產生不可抵抗的影響。

體系結構

你可以通過 DBMS_SCHEDULER 包或者通過Oracle企業管理器10g的數據庫控制功能來訪問這一新的調度程序。圖1給出了與任務的創建和執行具有最直接關係的調度程序組件。一項任務將一個程序和一個調度表結合在一起。該程序定義將要運行的內容。例如,一個程序可以是一個 PL/SQL 塊、一個存儲過程,或者一個操作系統腳本。而調度表則定義什麼時候運行該程序。對於一個一次性任務,調度表中僅包含一個起始時間。對於一個重複性任務,你可以指定一個起始時間,一個重複運行調度表,還可以根據需要指定結束時間。每次運行一項任務都被看作是一個任務實例。在開始使用該程序調度程序時必須掌握的三個核心組件就是任務、調度表和程序。

圖1所示,任務類將調度系統與資源管理系統連接起來,使你可以控制如何將數據庫資源分配給正在運行的任務。利用任務類將一個任務下達到資源使用者組,該組是一個共享 CPU 時間、並行操作和其它資源分配的會話期組。然後,你可以利用資源計劃來控制將這些資源分配給這個使用者組或其它使用者組。圖2 顯示出調度程序窗口如何控制不同資源計劃在何時被激活。圖2 還顯示一個窗口組,它將類似的窗口組合成一個單一的實體。窗口和窗口組使你可以在很好地控制如何將數據庫資源分配給不同的任務類。

圖1:調度程序核心組件

圖2:調度程序資源管理

開始

要創建並運行任務,你需要至少具有CREATE JOB 系統權限。如果你是一位 DBA,那麼你將通過授予DBA 角色的SCHEDULER_ADMIN角色而具有 CREATE JOB權限和所有其它調度程序權限。你可以將 CREATE JOB 權限授予數據庫用戶,允許他們在其自己的模式中創建和運行他們自己的任務。例如,下面的語句將 CREATE JOB 授予用戶 gennick:

GRANT CREATE JOB TO gennick;

與你應用DBMS_JOB時的情況不同,你不需要設置一個初始化參數,以啓動一個任務協調程序後臺進程。如果你使用該新的調度程序創建任務,則你的實例會在需要時自動啓動一個任務協調程序後臺進程。

如果你計劃使用資源計劃和使用者組來控制數據庫資源的分配,則將你實例的RESOURCE_LIMIT 參數設置爲TRUE。可以通過 ALTER SYSTEM完成該項設置,如下所示:

ALTER SYSTEM SET RESOURCE_LIMIT = TRUE;

最後,如果您將CREATE JOB 權限授予了一個非DBA用戶,而且你希望該用戶能夠使用數據庫控制的圖形用戶界面來調度任務,那麼你還需要授予該用戶 SELECT ANY DICTIONARY 系統權限。

你還可以使用 DBMS_SCHEDULER 包。通過SQL*Plus 調用DBMS_SCHEDULER使你完全可以通過命令行訪問該調度程序。DBMS_SCHEDULER 還提供了將調度程序功能內嵌於用戶應用程序中的能力。

創建你的第一個任務

要創建一個重複性任務,你首先需要定義程序和調度表。假定你需要在每隔一天的下午6:00加載一個外部表。首先創建一個調度程序,它提供一個 PL/SQL 塊以執行該加載。代碼清單1中的PL/SQL 塊發出一個對DBMS_SCHEDULER.CREATE_PROGRAM的調用,作爲程序操作所提供的 PL/SQL 塊包含有一個簡單的INSERT...SELECT FROM 語句,用於從該外部表中載入新的客戶。

接着,創建一個調度表,根據該調度表運行該程序。代碼清單2 給出一個對DBMS_SCHEDULER.CREATE_SCHEDULE的調用,用於創建我的 PERIODICLOADS調度表。註釋和調度表名稱參數相當簡單。註釋可以是提醒你爲什麼要創建該調度表的任意文本。schedule_ name 參數指明該調度表的所有者和名稱。與程序和任務相類似,調度程序也是模式對象,它們的名稱必須符合與表、索引等相同的命名規則。

start_date爲一個TIMESTAMP WITH TIME ZONE 值,它指明該調度表什麼時候被激活。此調度表在(美國東部時間)2004年3月22日星期一開始時被激活。

此調度程序引入了一個功能強大的日曆語法,你可以用此語法調度重複性任務。此語法具有三個組件: 頻度、間隔和時刻。你還有一個選項:基於一個PL/SQL表達式定義重複間隔(如果你對一個任務定義了一個內嵌調度程序),但是我相信你可能找到一種日曆語法,它能滿足除最不常用的調度表以外的所有調度表的需要。以下語句是我的PERIODICLOADS 調度表中repeat_interval參數中的日曆語法:

 

FREQ=DAILY;INTERVAL=2;BYHOUR=18;
BYMINUTE=0;BYSECOND=0

 

FREQ=DAILY 根據PERIODICLOADS 調度表規定,任何任務相繼運行之間的重複時間間隔以天或者24小時爲單位計算。INTERVAL=2 指明單位的數目,在此例中爲2天。三個 BY 數值-BYHOUR=18, BYMINUTE=0, and BYSECOND=0-指明任務運行的時刻,以24小時製表示。代碼清單2中的PERIODICLOADS 調度表將給出以下任務運行時間:

 

  • 第一次運行是在2004年3月22日星期一,下午6:00。
  • 第二次運行是在2004年3月22日星期一的兩天之後,即3月24日星期三的下午6:00。
  • 第三次運行是在2004年3月22日星期一的兩天之後再過兩天,即3月26日星期五下午6:00。

 

該日曆語法的一個非常好的特色就是它消除了使用DBMS_JOB時可能會發生的調度表時間偏移。一個任務實例的起始時間不會影響下一個任務實例的起始時間。相反,調度表的重複時間間隔總是根據調度表的start_date重新進行計算。

該日曆算法的通用性很好。 你不僅可以爲每個 BY 關鍵字指定一個單一取值,而且還可以指定一個取值列表。例如,如果你希望總在星期一、星期三和星期五進行週期性加載,那麼你可以指定重複時間間隔如下:

 

FREQ=WEEKLY;INTERVAL=1;
BYDAY=MON,WED,FRI;BYHOUR=18;BYMINUTE=0;
BYSECOND=0

 

此調度表將每週重複一次 (INTERVAL=1);它將在每週的星期一、星期三和星期五啓動任務 (BYDAY=MON,WED,FRI);並且這些任務將在這些天的每個下午6:00 p.m (BYHOUR=18; BYMINUTE=0;BYSECOND=0) 運行。

在你已經定義了程序和調度表之後,下一個步驟就是將這兩個對象以一個任務的形式連接在一起。代碼清單3顯示一個對DBMS_SCHEDULER.CREATE_JOB的調用,它創建一個名爲 LOADNEWCUSTOMERS的任務。此任務將根據PERIODICLOADS調度表運行LOADCUSTOMERS程序。

將調度表、程序和任務分離可以實際減少你的工作量。你可以在任何時間基於PERIODICLOADS調度表創建一個新的任務,而且此新任務將在與剛創建的LOADNEWCUSTOMERS任務相同的時刻和以相同的時間間隔運行。

代碼清單2 中定義的調度表給出以下任務開始運行的時間:

2004年3月22日星期一,下午6:00。
2004年3月24日星期三,下午6:00。
2004年3月26日星期五,下午6:00。

當你將一個任務連接到此調度表時,該任務將在你將兩者連接在一起的日期和時間之後的下一個調度時間運行。例如,如果你在2004年3月23日星期二創建一個如代碼清單3 所示的任務,此任務將在3月24日星期三的下午6:00第一次運行。如果你擁有按照同一調度表運行的幾個相關任務,並且你需要修改該調度表,那麼對整個相關任務集只需修改一次。

限定任務的起始時間

這一新的調度程序的一個非常好的特性是能夠將一個任務的啓始時間限定在正常啓動時間之後的一個特定時期。例如,假定你有一個安排在每天晚上6:00運行的任務。由於系統加載或其它原因,此任務實際上可能要等到6:12纔能有開始運行的機會。即使是延遲了12分鐘,你是否仍然希望開始運行該任務?

採用這一調度程序,你可以回答希望在延後多長時間後你仍然願意開始運行一個任務的問題。你可以通過設置該任務的schedule_limit屬性值(以分爲單位)來完成這一工作。以下語句指明我的LOADNEWCUSTOMERS任務必須在其預定開始運行的時間之後的10分鐘內開始運行:

 

sys.dbms_scheduler.set_attribute(
   name =>'GENNICK.LOADNEWCUSTOMERS',
   attribute => 'schedule_limit', 
   value => 10);

 

如果這一任務被延後到超過其開始運行的時間10分鐘才能運行,則將取消(跳過)此任務的執行。 默認的 schedule_limit屬性爲空,則意味着沒有任何限制。當使用數據庫控制時,你可以利用"編輯任務"頁面的"選項"選項卡設置這一屬性。

創建資源窗口

作爲一個DBA,你可以創建資源計劃,以將資源分配給不同的使用者組。利用調度程序窗口,你可以使這些資源計劃自動生效。代碼清單4 給出了創建一個夜間批處理窗口的代碼,這個窗口在每晚6:00開始運行,一直運行到第二天早晨8:00。請注意resource_plan 參數。該窗口激活BATCH_PROCESSING 資源計劃。與此類似,你可以創建一個第二窗口,它在每天早晨激活ONLINE_PROCESSING資源計劃。

任務類允許你將任務分派給使用者組,它是資源管理與調度程序之間的連接。默認的任務類爲DEFAULT_JOB_CLASS,但是在創建一個任務時,你可以很容易地選擇一個不同的類。你還可以在創建任務之後很容易地由一個任務切換至另一個任務。

下一步

 

閱讀
關於該調度程序的更多資料
關於資源管理、資源計劃和使用者組的更多資料

瞭解關於該調度程序的更多信息
otn.oracle.com/obe/obe10gdb/manage/scheduler/schuser.htm
otn.oracle.com/obe/obe10gdb/manage/scheduler/schadmin.htm

 

代碼清單4 中所創建的窗口其定義帶有一個內嵌調度表,這就是說該調度表是該窗口定義的一部分。還有可能將一個窗口連接到一個單獨定義的調度表。你可以更進一步將一個窗口和幾個相關的任務連接到相一個調度表,這樣,當該調度表被觸發時,該窗口的資源計劃將被激活,所有連接到該調度表的任務便開始運行。

如果你有一些任務,只希望它們在窗口及其資源計劃被激活時運行,那麼你可以根據窗口而不是根據預定的調度表來調度這些任務。如果你有兩個或多個窗口共享同一個資源計劃,則你可將這些窗口結合成一個窗口組。以下語句說明了如何創建一個包含夜間和週末運行的窗口的批處理窗口組:

BEGIN
   DBMS_SCHEDULER.CREATE_WINDOW_GROUP(
      group_name=>'batch_processing',
      window_list=>'NIGHT,WEEKEND');
END;

監控與日誌

這一新的調度程序提供了卓越的監控和日誌工具,它們特別便於通過Oracle 企業管理器 10g的數據庫控制界面來使用。圖 3 給出了你可以從"調度程序任務"頁看到的已排定的任務列表。點擊"運行"選項卡可以查看當前運行的任務。點擊"運行歷史"選項卡,你會看到類似於圖 4中的一個日誌。 每個日誌條目表示一個任務實例,你可以立即看到哪個實例運行成功了,哪個實例運行失敗了。點擊一個任務名稱可以深入到一任務,你還可以進一步深入查看每次運行的詳細日誌條目。 日誌條目將被保存你所指定的一段時間。你可以爲日誌條目指定一個全局保持時間,你也可以爲不同的工作類定製日誌條目的保持時間。調度程序將每天檢查一次已經超過其保持時間的日誌條目,並將它們刪除。

圖3: 調度程序的已排定任務選項卡

圖4: 調度程序的任務運行歷史選項卡

對於任何希望減少調度、管理和監控重複性任務的單調乏味程度的DBA來說,這一新的調度程序及其在數據庫控制中的強力支持都是深受歡迎的技術成就。程序、調度表、任務、任務類、窗口和窗口組的體系結構是一個功能強大的特性集,並且爲在未來版本中進一步提高打下了基礎。相對於編寫PL/SQL表達式來計算任務執行時間間隔的老DBMS_JOB方法,日曆語法的使用更簡單、更可靠。這一新的調度程序可以提供很多功能。請很好地利用它吧。

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章