Oracle 调度程序(scheduler)摘自一位大神
在11g中,Oracle提供了一個(gè)新建的Scheduler特性,幫助將作業(yè)實(shí)現(xiàn)自動(dòng)化。它還可以幫助你控制資源的利用與并可以將數(shù)據(jù)庫中的作業(yè)按優(yōu)先順序執(zhí)行。傳統(tǒng)的dbms_jobs的一個(gè)限制是它只能調(diào)度基于PL/SQL的作業(yè),不能用來調(diào)度操作系統(tǒng)的可執(zhí)行文件或腳本。
Scheduler包括如下權(quán)限: scheduler_admin角色包含所有的scheduler系統(tǒng)權(quán)限,授權(quán)如下: SQL> grant scheduler_admin to djp01 2 ?/ Grant succeeded. SQL> manage scheduler系統(tǒng)權(quán)限允許做以下工作:‘ 創(chuàng)建、刪除和更改作業(yè)類,窗口和窗口組。 停止作業(yè) 提前啟動(dòng)和停止窗口(關(guān)于這些部件在下文中進(jìn)行介紹)。 授權(quán)如下: SQL> grant manage scheduler to djp01 2 ?/ Grant succeeded. SQL> create job系統(tǒng)權(quán)限允許做如下工作: 創(chuàng)建作業(yè)(job)、進(jìn)度表(schedule)、程序(program)、鏈(chain)和事件(event)。 (關(guān)于這些部件在下文中會(huì)進(jìn)行介紹),授權(quán)如下: SQL> grant create job to djp01 2 ?/ Grant succeeded. SQL> 如果要執(zhí)行的程序在不同的模式下,那么必要擁有執(zhí)行相應(yīng)模式下的程序的執(zhí)行權(quán)限,如下execute any procedure。 Scheduler包括如下基本部件: (1)作業(yè)(job) 作業(yè)是一個(gè)計(jì)劃執(zhí)行一次或多次的任務(wù)。例子如下: SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss' 2 ?/ Session altered. SQL> alter session set nls_timestamp_tz_format = 'yyyy-mm-dd hh24:mi:ss.ff' 2 ?/ Session altered. SQL> alter session set nls_timestamp_format = 'yyyy-mm-dd hh24:mi:ss.ff' 2 ?/ Session altered. SQL>
說明:在使用調(diào)度程序時(shí),會(huì)涉及一些時(shí)間的相關(guān)信息,我這里進(jìn)行一些時(shí)間格式的設(shè)置方便使用。
SQL> create table emp_bak 2 ?as 3 ?select * 4 ?from employees 5 ?where 1 = 0 6 ?/ Table created. SQL>? SQL> begin 2 ? ? dbms_scheduler.create_job( 3 ? ? ? ?job_name=>'test_job', 4 ? ? ? ?job_type=>'PLSQL_BLOCK', 5 ? ? ? ?job_action=>'insert into emp_bak select * from employees where rownum <= 200;', 6 ? ? ? ?start_date=>'2012-12-09 14:40:00', 7 ? ? ? ?repeat_interval=>'FREQ=DAILY;INTERVAL=2', 8 ? ? ? ?end_date=>'2012-12-09 20:00:00', 9 ? ? ? ?comments=>'insert old employees into the emp_bak table', 10 ? ? ? ?auto_drop=>false, 11 ? ? ? ?enabled=>true); 12 ?end; 13 ?/ PL/SQL procedure successfully completed. SQL> 說明:job_name指定作業(yè)的名稱;job_type指定要?jiǎng)?chuàng)建的作業(yè)的類型,其值包括PLSQL_BLOCK(PL/SQL塊),STORED_PROCEDURE(存儲(chǔ)過程),EXECUTABLE(可執(zhí)行文件或Java程序)。job_action指定作業(yè)要執(zhí)行過程,命令或腳本。start_date與end_date指定作業(yè)的啟動(dòng)與結(jié)束時(shí)間。comments用于給當(dāng)前作業(yè)添加注釋。enabled指定創(chuàng)建作業(yè)時(shí),是否啟動(dòng)或禁用作業(yè),默認(rèn)值為false,表示禁用;值為true,表啟用。auto_drop指定該作業(yè)執(zhí)行完成后,是否自動(dòng)將其刪除,默認(rèn)值為true,表示執(zhí)行完成后自動(dòng)刪除該作業(yè)。repeat_interval指定作業(yè)執(zhí)行的頻率,FREQ=DAILY;INTERVAL=2表示每天運(yùn)行一次該作業(yè)。該值是一個(gè)日歷表達(dá)式(calendaring expression)由三個(gè)部分組成,Frequency: 這是表達(dá)式必須包含的部分,用FREQ指定,可能取的值為YEARLY,MONTHLY,WEEKLY,DAILY,HOURLY,MINUTELY和SECONDLY。repeat interval:這個(gè)時(shí)間間隔由INTERVAL關(guān)鍵字標(biāo)識(shí),表示執(zhí)行的頻率。specific:提供一個(gè)作業(yè)何時(shí)運(yùn)行的詳細(xì)信息,可能取值為:BYMONTH,BYWEEKNO,BYYEARDAY,BYMONTHDAY,BYDAY,BYHOUR,BYMINUTE和BYSECOND。例如:BYMONTHDAY表示每月的某一天,BYDAY表示每周的某一天。以下是典型的日歷表達(dá)式: FREQ=DAILY;INTERVAL=3;每三天執(zhí)行一次。 FREQ=HOURLY;INTERVAL=2;每隔一小時(shí)執(zhí)行一次。 FREQ=WEEKLY,BYDAY=SUN;每個(gè)星期日?qǐng)?zhí)行一次。 FREQ=WEEKLY;INTERVAL=2,BYDAY=FRI;每隔一周的周五執(zhí)行一次。 FREQ=MONTHLY;BYMONTHDAY=1;每月最后一天執(zhí)行一次。 FREQ=MINUTELY;INTERVAL=30;每半個(gè)小時(shí)執(zhí)行一次。 下面我們看一下執(zhí)行的情況: SQL> select count(*) 2 ?from emp_bak 3 ?/ COUNT(*) ---------- 200 SQL> 上述調(diào)度程序的作業(yè)成功運(yùn)行,下面我們看一些該作業(yè)的信息: SQL> select job_style,job_type,job_action,program_name,state 2 ?from dba_scheduler_jobs 3 ?where job_name = upper('test_job') 4 ?/ JOB_STYLE ? ? ? ? ? ? ?JOB_TYPE ---------------------- -------------------------------- JOB_ACTION -------------------------------------------------------------------------------- PROGRAM_NAME -------------------------------------------------------------------------------- STATE ------------------------------ REGULAR ? ? ? ? ? ? ? ?PLSQL_BLOCK insert into emp_bak select * from employees where rownum <= 200; COMPLETED SQL> 狀態(tài)顯示,該作業(yè)執(zhí)行完成,該作業(yè)的類型為REGULAR(規(guī)律性的)。 作業(yè)的其他一些管理: 禁用一個(gè)作業(yè): SQL> exec dbms_scheduler.disable('test_job'); PL/SQL procedure successfully completed. SQL> 激活一個(gè)作業(yè): SQL> exec dbms_scheduler.enable('test_job'); PL/SQL procedure successfully completed. SQL> 運(yùn)行一個(gè)作業(yè): SQL> truncate table emp_bak; Table truncated. SQL> exec dbms_scheduler.run_job('test_job'); PL/SQL procedure successfully completed. SQL> select count(*) 2 ?from emp_bak 3 ?/ COUNT(*) ---------- 200 SQL> 說明:該運(yùn)行相當(dāng)于是手工執(zhí)行一次相應(yīng)的程序。 停止一個(gè)作業(yè): SQL> exec dbms_scheduler.stop_job('test_job'); 如果一個(gè)作業(yè)不在運(yùn)行狀態(tài),它將會(huì)出現(xiàn)ORA-27366錯(cuò)誤。 刪除一個(gè)作業(yè): SQL> exec dbms_scheduler.drop_job('test_job'); PL/SQL procedure successfully completed. SQL>(2)進(jìn)度表(schedule)
進(jìn)度表是數(shù)據(jù)庫執(zhí)行一個(gè)作業(yè)的時(shí)間及頻率的說明。假如有一些作業(yè)都是在大致相同的時(shí)間內(nèi)運(yùn)行的,那么,可以使用一個(gè)進(jìn)度表,可以化這些作業(yè)的創(chuàng)建與管理。例子如下: SQL> begin 2 ? ? dbms_scheduler.create_schedule( 3 ? ? ? ?schedule_name=>'test_schedule', 4 ? ? ? ?start_date=>systimestamp, 5 ? ? ? ?repeat_interval=>'FREQ=MINUTELY;INTERVAL=30', 6 ? ? ? ?end_date=>systimestamp+3, 7 ? ? ? ?comments=>'Every 30 minute'); 8 ?end; 9 ?/ PL/SQL procedure successfully completed. SQL> 下面我們查看該進(jìn)度表的創(chuàng)建信息: SQL> select start_date,end_date,schedule_type 2 ?from dba_scheduler_schedules 3 ?where schedule_name = upper('test_schedule') 4 ?/ START_DATE --------------------------------------------------------------- END_DATE --------------------------------------------------------------- SCHEDULE_TYPE ---------------- 2012-12-09 17:22:43.781000 2012-12-12 17:22:43.000000 CALENDAR SQL>可以對(duì)已經(jīng)創(chuàng)建的進(jìn)度表進(jìn)行相關(guān)屬性的更改,如下:
SQL> begin 2 ? ? dbms_scheduler.set_attribute( 3 ? ? ? ?name=>'test_schedule', 4 ? ? ? ?attribute=>'start_date', 5 ? ? ? ?value=>systimestamp); 6 ?end; 7 ?/ PL/SQL procedure successfully completed. SQL> 對(duì)已經(jīng)有的進(jìn)度表,我們可以進(jìn)行刪除,如下: SQL> exec dbms_scheduler.drop_schedule('test_schedule'); PL/SQL procedure successfully completed. SQL> (3)程序(program) 程序包括關(guān)于一個(gè)scheduler作業(yè)的元數(shù)據(jù)。程序包括程序名,程序類型以及程序的動(dòng)作。它是一個(gè)過程或是可執(zhí)行腳本的實(shí)際名稱。例子如下: SQL> begin 2 ? ? dbms_scheduler.create_program( 3 ? ? ? ?program_name=>'test_program', 4 ? ? ? ?program_type=>'STORED_PROCEDURE', 5 ? ? ? ?program_action=>'auto_archive_emp', 6 ? ? ? ?enabled=>true, 7 ? ? ? ?comments=>'use to execute the procedure of auto_archive_emp'); 8 ?end; 9 ?/ PL/SQL procedure successfully completed. SQL> 說明:program_type與program_action同上述的job_type,job_action含義一樣,這里不再說明。enabled表示該程序是否被啟用,默認(rèn)值為false,表示禁用。 我們可以用如下的方法對(duì)程序進(jìn)行啟用或禁用: 禁用一個(gè)程序: SQL> exec dbms_scheduler.disable('test_program'); PL/SQL procedure successfully completed. SQL> 啟用一個(gè)程序: SQL> exec dbms_scheduler.enable('test_program'); PL/SQL procedure successfully completed. SQL> 同樣,我們也可以進(jìn)行刪除,如下: SQL> exec dbms_scheduler.drop_program('test_program'); PL/SQL procedure successfully completed. SQL> 對(duì)程序相關(guān)信息的查看可以使用dba_scheduler_programs數(shù)據(jù)字典。?
(4)鏈(chain) 可以使用調(diào)度程序鏈的概念將相關(guān)的程序鏈接在一起。因此,一個(gè)程序的成功運(yùn)行,可能是以另外的程序成功運(yùn)行為基礎(chǔ);還可以是基于一個(gè)鍵而非程序啟動(dòng)作業(yè)。鏈中連續(xù)的位置稱為鏈的“步驟(step)”,每個(gè)步驟指向另一個(gè)鏈,程序或事件。由于鏈?zhǔn)褂肙racle Streams Rules Engine(Oracle流規(guī)則引擎對(duì)象)。因此用戶必須具有create job 和Rules Engine權(quán)限才能創(chuàng)建一個(gè)鏈。例子如下: 進(jìn)行如下授權(quán): SQL> begin 2 ? ? dbms_rule_adm.grant_system_privilege( 3 ? ? ? ?dbms_rule_adm.create_rule_obj,'djp01'); 4 ? ? dbms_rule_adm.grant_system_privilege( 5 ? ? ? ?dbms_rule_adm.create_rule_set_obj,'djp01'); 6 ? ? dbms_rule_adm.grant_system_privilege( 7 ? ? ? ?dbms_rule_adm.create_evaluation_context_obj,'djp01'); 8 ?end; 9 ?/ PL/SQL procedure successfully completed. SQL> 創(chuàng)建如下: SQL> begin 2 ? ? dbms_scheduler.create_chain( 3 ? ? ? ?chain_name=>'test_chain', 4 ? ? ? ?comments=>'A shain test'); 5 ?end; 6 ?/ PL/SQL procedure successfully completed. SQL> 定義鏈步驟: SQL> begin 2 ? ? dbms_scheduler.define_chain_step( 3 ? ? ? ?chain_name=>'test_chain', 4 ? ? ? ?step_name=>'test_step1', 5 ? ? ? ?program_name=>'test_program1'); 6 ? ? dbms_scheduler.define_chain_step( 7 ? ? ? ?chain_name=>'test_chain', 8 ? ? ? ?step_name=>'test_step2', 9 ? ? ? ?program_name=>'test_program2'); 10 ?end; 11 ?/ PL/SQL procedure successfully completed. SQL> 說明:鏈步驟可以指向一個(gè)程序、鏈或事件。使用不同的參數(shù)進(jìn)行標(biāo)識(shí)。 為了使用鏈有效的運(yùn)行,必須給鏈添加規(guī)則,用于確定步驟何時(shí)運(yùn)行并指定運(yùn)行條件。如下: SQL> begin 2 ? ? dbms_scheduler.define_chain_rule( 3 ? ? ? ?chain_name=>'test_chain', 4 ? ? ? ?condition=>'true', 5 ? ? ? ?action=>'start test_step1'); 6 ? ? dbms_scheduler.define_chain_rule( 7 ? ? ? ?chain_name=>'test_chain', 8 ? ? ? ?condition=>'test_step1 completed', 9 ? ? ? ?action=>'start test_step2'); 10 ? ? dbms_scheduler.define_chain_rule( 11 ? ? ? ?chain_name=>'test_chain', 12 ? ? ? ?condition=>'test_step2 completed', 13 ? ? ? ?action=>'end'); 14 ?end; 15 ?/ PL/SQL procedure successfully completed. SQL> 說明:在規(guī)則中,我們按照每一步的先后順序進(jìn)行定義。如果每個(gè)步驟中都事務(wù)的先后關(guān)系,使用鏈?zhǔn)且粋€(gè)不錯(cuò)的選擇。在上述步驟完成之后,我們還需要對(duì)鏈進(jìn)行啟用,如下:
SQL> exec dbms_scheduler.enable('test_chain'); PL/SQL procedure successfully completed. SQL> 這時(shí),我們就可以在作業(yè)(job)中使用該鏈了(job_type指定為chain,job_action指定對(duì)應(yīng)鏈的名稱,如test_chain)。 我們還可以使用如下方式運(yùn)行: SQL> begin 2 ? ? dbms_scheduler.run_chain( 3 ? ? ? ?chain_name=>'test_chain', 4 ? ? ? ?start_steps=>'test_step1,test_step2'); 5 ?end; 6 ?/ PL/SQL procedure successfully completed. SQL> (5)事件(event)Scheduler使用Oracle Stream Advanced Qeueing(Oracle流高級(jí)隊(duì)列)觸發(fā)事件并啟動(dòng)基于事件的數(shù)據(jù)庫作業(yè)。事件是一個(gè)應(yīng)用程序或是進(jìn)程注意到某個(gè)事件或動(dòng)作時(shí)發(fā)出的一條消息。有兩種類型的事件:Scheduler引發(fā)的事件和應(yīng)用程序引發(fā)的事件。Scheduler引發(fā)的事件由Scheduler運(yùn)行中的變化而導(dǎo)致,比如Scheduler作業(yè)成功完成是一個(gè)事件。應(yīng)用程序引發(fā)的事件由Scheduler為啟動(dòng)一個(gè)作業(yè)而使用或是消費(fèi)。
使用基于事件的作業(yè),只要在create_job過程上指定event_condition與queue_spec即可。但是事件的定義涉及到了,dbms_aqadm程序包的一些使用。我查看了dbms_aqadm包的聲明,沒有相關(guān)的注釋,之后試了幾次,沒有達(dá)到效果,這個(gè)問題有待解決。 下面我們來看幾個(gè)綜合使用的例子: SQL> begin 2 ? ? dbms_scheduler.create_job( 3 ? ? ? ?job_name=>'test_job1', 4 ? ? ? ?program_name=>'test_program1', 5 ? ? ? ?schedule_name=>'test_schedule', 6 ? ? ? ?enabled=>true, 7 ? ? ? ?auto_drop=>false, 8 ? ? ? ?comments=>'use program and schedule to create job'); 9 ?end; 10 ?/ PL/SQL procedure successfully completed. SQL> 說明:在上述作業(yè)的創(chuàng)建中,我使用了程序與進(jìn)度表。如果要進(jìn)行調(diào)整,可以調(diào)整相應(yīng)的程序與進(jìn)行度即可。 SQL> begin 2 ? ? dbms_scheduler.create_job( 3 ? ? ? ?job_name=>'test_job2', 4 ? ? ? ?schedule_name=>'test_schedule', 5 ? ? ? ?job_type=>'chain', 6 ? ? ? ?job_action=>'test_chain', 7 ? ? ? ?enabled=>true, 8 ? ? ? ?auto_drop=>false, 9 ? ? ? ?comments=>'use chain to create job'); 10 ?end; 11 ?/ PL/SQL procedure successfully completed. SQL> 說明:在創(chuàng)建job時(shí),我們兩樣也可以指定一個(gè)鏈。如果要指定鏈,那么job_type為chain,job_action為所創(chuàng)建的鏈名。總結(jié)
以上是生活随笔為你收集整理的Oracle 调度程序(scheduler)摘自一位大神的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux bin文件制作
- 下一篇: 杭州社保转移怎么办理流程(社保跨省转移有