Decode360's Blog

          業(yè)精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            397 隨筆 :: 33 文章 :: 29 評論 :: 0 Trackbacks
          [Oracle10G新特性]_19.調(diào)度程序
          ?
          ??? 這個屬性還真的是不錯,之前沒有注意過。特別是關(guān)于執(zhí)行操作系統(tǒng)程序和時間定義語法的更改,非常不錯。之前想要在一天的某2個時間執(zhí)行,都需要定義兩個job才可以,原來確實(shí)是可以通過decode函數(shù)來達(dá)到這個目的的,不過知道dbms_scheduler包的功能之后,就更加簡單了。總之這個又是一個10g的改進(jìn)之處,非常不錯。考慮一下直接應(yīng)用。
          ?
          -----------------------------------------------------------------------------
          ?
          調(diào)度程序
          ?
          您是否厭倦了在 dbms_job 中手工管理時間間隔的繁瑣,需要數(shù)據(jù)庫內(nèi)部有個新調(diào)度系統(tǒng)? 讓我們就著眼于數(shù)據(jù)庫本身來解決這個問題。
          ?
          ??? 你們中的一部分人可能廣泛使用 dbms_job 程序包來將數(shù)據(jù)庫作業(yè)提交到后臺運(yùn)行,控制運(yùn)行的時間或時間間隔,報(bào)告故障等等。 然而,我感覺你們中的大部分人不會這么做。

          ??? 這個程序包存在的問題是它只能夠處理 PL/SQL 代碼段 — 僅能處理匿名程序塊和存儲程序單元。 它不能在數(shù)據(jù)庫外部處理操作系統(tǒng)命令文件或可執(zhí)行文件中的任何東西。 為此,您將不得不求助于操作系統(tǒng)調(diào)度實(shí)用工具(如 Unix 中的 cron 或 Windows 中的 AT 命令)。 或者,您可以使用甚至可能通過提供圖形用戶界面來擴(kuò)展這種功能的第三方工具。
          ?
          ??? 雖然如此,dbms_job 有一個超過這些替代方法的獨(dú)特優(yōu)點(diǎn): 它只有在數(shù)據(jù)庫啟動并運(yùn)行時才有效。 如果數(shù)據(jù)庫關(guān)閉,則作業(yè)不會運(yùn)行。 數(shù)據(jù)庫外部的工具必須人工檢查數(shù)據(jù)庫是否啟動 — 而這可能很困難。 另一個優(yōu)點(diǎn)是 dbms_job 在數(shù)據(jù)庫內(nèi)部,因此您可以通過數(shù)據(jù)庫訪問實(shí)用工具(如 SQL*Plus)來訪問它。
          ?
          ??? Oracle 數(shù)據(jù)庫 10g 調(diào)度程序特性提供了各方面的好處: 它是直接在數(shù)據(jù)庫內(nèi)部的一個作業(yè)調(diào)度實(shí)用程序,強(qiáng)大到足夠處理所有類型的作業(yè),而不只是 PL/SQL 代碼段。 最好的一點(diǎn)是,它是數(shù)據(jù)庫自帶的,無需任何額外的成本。 在這一部分中,我們將看看它是如何工作的。
          ?
          ?
          將作業(yè)與程序連接
          ?
          ??? 也許最好通過一個例子來介紹這個概念。 假定您創(chuàng)建了一個 shell 腳本,以將存檔的日志文件轉(zhuǎn)移到一個不同的文件系統(tǒng)中,如下:
          ?
          /home/arup/dbtools/move_arcs.sh
          ?
          ??? 首先,您需要使數(shù)據(jù)庫知道這個腳本是一個要在作業(yè)中使用的程序。 要創(chuàng)建這個程序,您必須擁有 CREATE JOB 權(quán)限。
          ?
          begin
          ??? dbms_scheduler.create_program
          ??? (
          ?????? program_name?? => 'MOVE_ARCS',
          ?????? program_type?? => 'EXECUTABLE',
          ?????? program_action => '/home/arup/dbtools/move_arcs.sh',
          ?????? enabled??????? => TRUE,
          ?????? comments?????? => 'Moving Archived Logs to Staging Directory'
          ??? );
          end;
          /
          ?
          ??? 這里您創(chuàng)建了一個命名程序單元,將其指定為可執(zhí)行文件。注意這個程序單元叫什么。
          ?
          ??? 接下來,您將創(chuàng)建一個每 30 分鐘運(yùn)行一次的命名計(jì)劃,該計(jì)劃的名稱為 EVERY_30_MINS。 您將使用以下命令來完成這一操作:
          ?
          begin
          ??? dbms_scheduler.create_schedule
          ??? (
          ?????? schedule_name?? => 'EVERY_30_MINS',
          ?????? repeat_interval => 'FREQ=MINUTELY; INTERVAL=30',
          ?????? comments??????? => 'Every 30-mins'
          ??? );
          end;
          /
          ?
          ??? 現(xiàn)在創(chuàng)建了程序和計(jì)劃,接著您將把程序與計(jì)劃連接來創(chuàng)建作業(yè)。
          ?
          begin
          ?? dbms_scheduler.create_job
          ?? (
          ????? job_name????? => 'ARC_MOVE',
          ????? program_name? => 'MOVE_ARCS',
          ????? schedule_name => 'EVERY_30_MINS',
          ????? comments????? => 'Move Archived Logs to a Different Directory',
          ????? enabled?????? => TRUE
          ?? );
          end;
          /
          ?
          ??? 這將創(chuàng)建一個每 30 分鐘運(yùn)行一次的作業(yè),該作業(yè)執(zhí)行 shell 腳本 move_arcs.sh。它將由數(shù)據(jù)庫內(nèi)部的調(diào)度程序特性來處理 — 無需 cron 或 AT 實(shí)用工具。
          ?
          ?
          創(chuàng)建沒有程序的作業(yè)
          ?
          ??? 在上述情況下,您創(chuàng)建了一個程序來引用一個操作系統(tǒng)實(shí)用工具或程序,并創(chuàng)建了一個計(jì)劃來指定運(yùn)行的次數(shù),最后將這兩者連接起來創(chuàng)建作業(yè)。 不過,不需要從程序中創(chuàng)建作業(yè);也可以獨(dú)立地定義它們。 例如,您可以創(chuàng)建上述作業(yè),而無需首先創(chuàng)建一個程序。
          ?
          begin
          ?? dbms_scheduler.create_job
          ?? (
          ????? job_name????? => 'ARC_MOVE_2',
          ????? schedule_name => 'EVERY_30_MINS',
          ????? job_type????? => 'EXECUTABLE',
          ????? job_action??? => '/home/arup/dbtools/move_arcs.sh',
          ????? enabled?????? => true,
          ????? comments????? => 'Move Archived Logs to a Different Directory'
          ?? );
          end;
          /
          ?
          ??? 這里直接指定 OS 可執(zhí)行文件,而無需首先將其創(chuàng)建為一個程序。 同樣,您可以創(chuàng)建一個作業(yè),而無需一個命名的計(jì)劃。
          ?
          begin
          ?? dbms_scheduler.create_job
          ?? (
          ????? job_name??????? => 'ARC_MOVE_3',
          ????? job_type??????? => 'EXECUTABLE',
          ????? job_action????? => '/home/arup/dbtools/move_arcs.sh',
          ????? repeat_interval => 'FREQ=MINUTELY; INTERVAL=30',
          ????? enabled???????? => true,
          ????? comments??????? => 'Move Archived Logs to a Different Directory'
          ?? );
          end;
          /
          ?
          ??? Scheduler 超過 dbms_job 的一個優(yōu)點(diǎn)從我們最初的例子中可以很清楚地看出來: 能夠調(diào)用 OS 實(shí)用工具和程序,而不只是 PL/SQL 程序單元。 這一能力使它成為管理 Oracle 數(shù)據(jù)庫和相關(guān)作業(yè)的最全面的作業(yè)管理工具。
          ?
          ??? 不過,您可能已經(jīng)注意到了另一個同樣重要的優(yōu)點(diǎn): 能夠以自然語言定義時間間隔。 注意在上面的例子中,我們要我們的計(jì)劃每 30 分鐘運(yùn)行一次,因此通過一個簡單的類似英語的表達(dá)式(而不是 PL/SQL)定義了 REPEAT_INTERVAL 參數(shù):
          ?
          'FREQ=MINUTELY; INTERVAL=30'
          ?
          ??? 一個更復(fù)雜的例子甚至可以更好地幫助說明這一優(yōu)點(diǎn)。 假定您的生產(chǎn)應(yīng)用程序在上午 7:00 和下午 3:00 變得最活躍,為了收集系統(tǒng)統(tǒng)計(jì)數(shù)據(jù),您想從星期一到星期五僅在上午 7:00 和下午 3:00 運(yùn)行 Statspack。 如果您使用 DBMS_JOB.SUBMIT 來創(chuàng)建一個作業(yè),那么 NEXT_DATE 參數(shù)將看起來像這樣:
          ?
          DECODE
          (
          ?? SIGN
          ?? (
          ????? 15 - TO_CHAR(SYSDATE,'HH24')
          ?? ),
          ?? 1,
          ????? TRUNC(SYSDATE)+15/24,
          ?? TRUNC
          ?? (
          ????? SYSDATE +
          ????? DECODE
          ????? (
          ????????? TO_CHAR(SYSDATE,'D'), 6, 3, 1
          ????? )
          ??? )
          ??? +7/24
          )
          ?
          ??? 這種代碼容易理解嗎?實(shí)際上不容易。
          ?
          ??? 現(xiàn)在讓我們看看 DBMS_SCHEDULER 中的等價的作業(yè)。 REPEAT_INTERVAL 參數(shù)將像下面這么簡單:
          'FREQ=DAILY; BYDAY=MON,TUE,WED,THU,FRI; BYHOUR=7,15'
          ?
          ??? 此外,這個參數(shù)值可以接收各種時間間隔,它們中的一些非常強(qiáng)大。 下面是更多的一些例子:
          ?
          ????? ● 每月的最后一個星期天:
          ????? FREQ=MONTHLY; BYDAY=-1SUN
          ?
          ????? ● 每月的第三個星期五:
          ????? FREQ=MONTHLY; BYDAY=3FRI
          ?
          ????? ● 從每月底算起(而不是從每月初算起)的第二個星期五:
          ????? FREQ=MONTHLY; BYDAY=-2FRI
          ?
          ??? 數(shù)字前面的負(fù)號指示從月底算起,而不是從月初算起。
          ?
          ??? 如果您想要驗(yàn)證時間間隔設(shè)置是否正確,那應(yīng)該怎么辦? 看看從日歷字符串中構(gòu)造的各個日期不是很好嗎? 好的,您可以使用 EVALUATE_CALENDAR_STRING 過程來預(yù)覽接下來的日期的計(jì)算。 利用第一個例子 — 從星期一到星期五每天在上午 7:00 和下午 3:00 運(yùn)行 Statspack — 您可以按如下方式檢查您的時間間隔字符串的準(zhǔn)確性:
          ?
          set serveroutput on size 999999
          ?
          declare
          ?? L_start_date??? TIMESTAMP;
          ?? l_next_date???? TIMESTAMP;
          ?? l_return_date?? TIMESTAMP;
          begin
          ?? l_start_date := trunc(SYSTIMESTAMP);
          ?? l_return_date := l_start_date;
          ?? for ctr in 1..10 loop
          ????? dbms_scheduler.evaluate_calendar_string(
          ??????? 'FREQ=DAILY; BYDAY=MON,TUE,WED,THU,FRI; BYHOUR=7,15',
          ???????? l_start_date, l_return_date, l_next_date
          ????? );
          ????? dbms_output.put_line('Next Run on: ' ||
          ????????? to_char(l_next_date,'mm/dd/yyyy hh24:mi:ss')
          ????? );
          ????? l_return_date := l_next_date;
          end loop;
          end;
          /
          ?
          ??? 輸出結(jié)果如下:
          ?
          Next Run on: 03/22/2004 07:00:00
          Next Run on: 03/22/2004 15:00:00
          Next Run on: 03/23/2004 07:00:00
          Next Run on: 03/23/2004 15:00:00
          Next Run on: 03/24/2004 07:00:00
          Next Run on: 03/24/2004 15:00:00
          Next Run on: 03/25/2004 07:00:00
          Next Run on: 03/25/2004 15:00:00
          Next Run on: 03/26/2004 07:00:00
          Next Run on: 03/26/2004 15:00:00
          ?
          ??? 這確認(rèn)您的設(shè)置是正確的。
          ?
          ?
          類、計(jì)劃和窗口
          ?
          ??? 一個稱職的好的作業(yè)調(diào)度系統(tǒng)必須支持為作業(yè)安排優(yōu)先級的能力。 例如,統(tǒng)計(jì)數(shù)據(jù)收集作業(yè)突然進(jìn)入 OLTP 工作負(fù)載窗口,從而可能影響那里的性能。 為了確保統(tǒng)計(jì)數(shù)據(jù)收集作業(yè)不消耗資源從而影響 OLTP,您可以使用作業(yè)類、資源計(jì)劃和調(diào)度程序窗口。
          ???
          ??? 例如,當(dāng)定義一個作業(yè)時,您可以使之屬于一個作業(yè)類,作業(yè)類映射到一個資源使用組上,以進(jìn)行資源分配。 為此,首先您需要定義一個名稱為(比如說) OLTP_GROUP 的資源使用組。
          ?
          begin
          ?? dbms_resource_manager.clear_pending_area();
          ?? dbms_resource_manager.create_pending_area();
          ?? dbms_resource_manager.create_consumer_group (
          ?????? consumer_group => 'oltp_group',??
          ?????? comment => 'OLTP Activity Group'
          ?? );
          ?? dbms_resource_manager.submit_pending_area();
          end;
          /
          ?
          ??? 接下來,您需要創(chuàng)建一個資源計(jì)劃。
          ?
          begin
          ?? dbms_resource_manager.clear_pending_area();
          ?? dbms_resource_manager.create_pending_area();
          ?? dbms_resource_manager.create_plan
          ????? ('OLTP_PLAN', 'OLTP Database Activity Plan');
          ?? dbms_resource_manager.create_plan_directive(
          ????? plan => 'OLTP_PLAN',
          ????? group_or_subplan => 'OLTP_GROUP',
          ????? comment => 'This is the OLTP Plan',
          ????? cpu_p1 => 80, cpu_p2 => NULL, cpu_p3 => NULL, cpu_p4 => NULL,
          ????? cpu_p5 => NULL, cpu_p6 => NULL, cpu_p7 => NULL, cpu_p8 => NULL,
          ????? parallel_degree_limit_p1 => 4,
          ????? active_sess_pool_p1 => NULL,
          ????? queueing_p1 => NULL,
          ????? switch_group => 'OTHER_GROUPS',
          ????? switch_time => 10,
          ????? switch_estimate => true,
          ????? max_est_exec_time => 10,
          ????? undo_pool => 500,
          ????? max_idle_time => NULL,
          ????? max_idle_blocker_time => NULL,
          ????? switch_time_in_call => NULL
          ?? );
          ?? dbms_resource_manager.create_plan_directive(
          ????? plan => 'OLTP_PLAN',
          ????? group_or_subplan => 'OTHER_GROUPS',
          ????? comment => NULL,
          ????? cpu_p1 => 20, cpu_p2 => NULL, cpu_p3 => NULL, cpu_p4 => NULL,
          ????? cpu_p5 => NULL, cpu_p6 => NULL, cpu_p7 => NULL, cpu_p8 => NULL,
          ????? parallel_degree_limit_p1 => 0,
          ????? active_sess_pool_p1 => 0,
          ????? queueing_p1 => 0,
          ????? switch_group => NULL,
          ????? switch_time => NULL,
          ????? switch_estimate => false,
          ????? max_est_exec_time => 0,
          ????? undo_pool => 10,
          ????? max_idle_time => NULL,
          ????? max_idle_blocker_time => NULL,
          ????? switch_time_in_call => NULL
          ?? );
          ?? dbms_resource_manager.submit_pending_area();
          end;
          /
          ?
          ??? 最后,您利用之前創(chuàng)建的資源使用組來創(chuàng)建一個作業(yè)類。
          ?
          begin
          ?? dbms_scheduler.create_job_class(
          ????? job_class_name => 'OLTP_JOBS',
          ????? logging_level => DBMS_SCHEDULER.LOGGING_FULL,
          ????? log_history => 45,
          ????? resource_consumer_group => 'OLTP_GROUP',
          ????? comments => 'OLTP Related Jobs'
          ?? );
          end;
          /
          ?
          ??? 讓我們看看這個調(diào)用中的各個參數(shù)。 LOGGING_LEVEL 參數(shù)設(shè)置為作業(yè)類跟蹤多少日志數(shù)據(jù)。 設(shè)置 LOGGING_FULL 指示這個類中的作業(yè)上的所有活動 — 創(chuàng)建、刪除、運(yùn)行、更替等等 — 都將被記錄在日志中。 這些日志可以從 DBA_SCHEDULER_JOB_LOG 視圖中看到,并保留 45 天(在 LOG_HISTORY 參數(shù)中指定,默認(rèn)值是 30 天)。 還指定了與這個類相連的資源使用組。 這些作業(yè)類可以從 DBA_SCHEDULER_JOB_CLASSES 視圖中看到。
          ?
          ??? 當(dāng)您創(chuàng)建一個作業(yè)時,您可以隨意地將其與一個類關(guān)聯(lián)。 例如,當(dāng)創(chuàng)建 COLLECT_STATS 時,對于一個通過執(zhí)行一個存儲過程來收集優(yōu)化程序統(tǒng)計(jì)數(shù)據(jù)的作業(yè) collect_opt_stats(),您可能已經(jīng)指定了:
          ?
          begin
          ?? dbms_scheduler.create_job
          ?? (
          ????? job_name??????? => 'COLLECT_STATS',
          ????? job_type??????? => 'STORED_PROCEDURE',
          ????? job_action????? => 'collect_opt_stats',
          ????? job_class?????? => 'OLTP_JOBS',
          ????? repeat_interval => 'FREQ=WEEKLY; INTERVAL=1',
          ????? enabled???????? => true,
          ????? comments??????? => 'Collect Optimizer Stats'
          ?? );
          end;
          /
          ?
          ??? 這些命令將把新創(chuàng)建的作業(yè)放在 OLTP_JOBS 類中,然后后者由資源計(jì)劃 OLTP_GROUP 來管理,該資源計(jì)劃將限制分配多少 CPU 給過程、在它被切換到一個不同的組之前的最大運(yùn)行數(shù)、要切換到的組等等。 在這個類中定義的任意作業(yè)都將由相同的資源計(jì)劃指令來管理。 這一功能對于防止不同類型的作業(yè)過度占用系統(tǒng)資源特別有用。
          ?
          ??? 調(diào)度程序窗口是擁有一個相關(guān)的資源計(jì)劃的時間幀,它用于激活該計(jì)劃 — 從而在一個時間幀上支持作業(yè)的不同優(yōu)先級。 例如,一些作業(yè)(如更新數(shù)據(jù)庫以支持實(shí)時決策的批量程序)在白天需要高優(yōu)先級但在晚上變?yōu)榈蛢?yōu)先級(反之亦然)。 您可以通過定義不同的資源計(jì)劃,然后使用調(diào)度程序窗口激活它們來實(shí)施這種調(diào)度。
          ?
          ?
          監(jiān)視
          ?
          ??? 在一個作業(yè)啟動之后,您可以從 DBA_SCHEDULER_JOB_LOG 視圖中監(jiān)視它的狀態(tài),其中 STATUS 列顯示了作業(yè)的當(dāng)前狀態(tài)。 如果它顯示 FAILED,那么您可以進(jìn)一步向下查看,以從 DBA_SCHEDULER_JOB_RUN_DETAILS 視圖中找出原因。
          ?
          ?
          管理
          ?
          ??? 迄今為止,我們已經(jīng)討論了如何創(chuàng)建幾種類型的對象: 程序、計(jì)劃、作業(yè)類和作業(yè)。 如果您想修改它們中的一些,以調(diào)整適應(yīng)不斷變化的需求,那該怎么辦? 好的,您可以通過 DBMS_SCHEDULER 程序包中提供的 API 來實(shí)現(xiàn)這一目的。
          ?
          ??? 從企業(yè)管理器 10g 主頁的 Database 標(biāo)簽中,單擊 Administration 鏈接。 這將顯示 Administration 屏幕(如圖 1 所示)。所有與調(diào)度程序相關(guān)的任務(wù)都可以在右下角的 "Scheduler" 標(biāo)題下找到(顯示在圖中的一個紅色橢圓中)。
          ?
          01
          ?
          圖 1: Administration 頁面
          ?
          ??? 所有與調(diào)度程序相關(guān)的任務(wù)(如創(chuàng)建、刪除和維護(hù)作業(yè))都能夠通過該頁面中的超鏈接任務(wù)輕松完成。 讓我們看看這些任務(wù)中的一部分。 我們在早些時候創(chuàng)建了所有這些任務(wù),因此單擊 Jobs 標(biāo)簽將顯示一個類似于圖 2 的屏幕。
          ?
          02
          ?
          圖 2: 計(jì)劃作業(yè)
          ?
          ??? 單擊 COLLECT_STATS 作業(yè)允許您修改它的屬性。 當(dāng)您單擊 "Job Name" 時,將出現(xiàn)圖 3 中顯示的屏幕。
          ?
          03
          ?
          圖 3: 作業(yè)參數(shù)
          ?
          ??? 正如您所看到的,您可以通過單擊相應(yīng)的標(biāo)簽來修改作業(yè)的參數(shù)以及計(jì)劃和選項(xiàng)。 在完成所有的修改之后,您可以按下 "Apply" 鍵,使修改變?yōu)橛谰眯缘摹?在這么做之前,您可能想單擊標(biāo)記為 "Show SQL" 的按鈕,它顯示將執(zhí)行的確切的 SQL 語句 — 即使原因只是要查看調(diào)用了哪些 API,從而使您能夠了解幕后的工作。 您還可以將 SQL 存儲在一個腳本中,并在以后執(zhí)行它,或者將它存儲為一個模板,以便將來使用。
          ?
          ?
          結(jié)論
          ?
          ??? Oracle 數(shù)據(jù)庫 10g 中的調(diào)度程序是從原來的 dbms_job 接口實(shí)現(xiàn)的巨大的飛躍。
          ?
          ?
          ?
          關(guān)于這些特性和其它更高級的特性的更多信息,請參考 Oracle 數(shù)據(jù)庫管理員指 25
          ?
          ?
          ?
          ?
          ?
          posted on 2009-08-20 21:14 decode360 閱讀(579) 評論(0)  編輯  收藏 所屬分類: 08.DBA
          主站蜘蛛池模板: 江都市| 凌云县| 亳州市| 宝应县| 木里| 鄄城县| 奎屯市| 馆陶县| 新河县| 大宁县| 滕州市| 铅山县| 内乡县| 巴南区| 洛川县| 江门市| 鸡东县| 固安县| 临汾市| 聂拉木县| 台东县| 江孜县| 华蓥市| 吕梁市| 江永县| 芦溪县| 小金县| 梅河口市| 苏尼特左旗| 太仆寺旗| 富民县| 新平| 额济纳旗| 清远市| 固原市| 安图县| 包头市| 浑源县| 辽源市| 南和县| 霍林郭勒市|