[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;
/
??? 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;
/
??? 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;
/
?? 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;
/
?? 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;
/
?? 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
)
(
?? 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=-1SUN
?
????? ● 每月的第三個星期五:
????? FREQ=MONTHLY; BYDAY=3FRI
????? FREQ=MONTHLY; BYDAY=3FRI
?
????? ● 從每月底算起(而不是從每月初算起)的第二個星期五:
????? FREQ=MONTHLY; BYDAY=-2FRI
????? 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;
/
?? 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
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;
/
?? 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;
/
?? 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;
/
?? 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;
/
?? 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)題下找到(顯示在圖中的一個紅色橢圓中)。
?
?
圖 1: Administration 頁面
?
??? 所有與調(diào)度程序相關(guān)的任務(wù)(如創(chuàng)建、刪除和維護(hù)作業(yè))都能夠通過該頁面中的超鏈接任務(wù)輕松完成。 讓我們看看這些任務(wù)中的一部分。 我們在早些時候創(chuàng)建了所有這些任務(wù),因此單擊 Jobs 標(biāo)簽將顯示一個類似于圖 2 的屏幕。
?
?
圖 2: 計(jì)劃作業(yè)
?
??? 單擊 COLLECT_STATS 作業(yè)允許您修改它的屬性。 當(dāng)您單擊 "Job Name" 時,將出現(xiàn)圖 3 中顯示的屏幕。
?
?
圖 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 章。
?
?
?
?
?