The important thing in life is to have a great aim , and the determination

          常用鏈接

          統(tǒng)計

          IT技術(shù)鏈接

          保險相關(guān)

          友情鏈接

          基金知識

          生活相關(guān)

          最新評論

          oracle定時任務詳解(轉(zhuǎn)自CSDN)

           

          DBMS_JOB系統(tǒng)包是Oracle“任務隊列”子系統(tǒng)的API編程接口。DBMS_JOB包對于任務隊列提供了下面這些功能:提交并且執(zhí)行一個任務、改變?nèi)蝿盏膱?zhí)行參數(shù)以及刪除或者臨時掛起任務等。

          DBMS_JOB包是由ORACLE_HOME目錄下的rdbms/admin子目錄下的DBMSJOB.SQL和PRVTJOB.PLB 這兩個腳本文件創(chuàng)建的。這兩個文件被CATPROC.SQL腳本文件調(diào)用,而CATPROC.SQL這個文件一般是在數(shù)據(jù)庫創(chuàng)建后立即執(zhí)行的。腳本為DBMS_JOB包創(chuàng)建了一個公共同義詞,并給該包授予了公共的可執(zhí)行權(quán)限,所以所有的Oracle用戶均可以使用這個包。

          下面幾個數(shù)據(jù)字典視圖是關(guān)于任務隊列信息的,主要有DBA_JOBS, USER_JOBS和DBA_JOBS_RUNNING。這些字典視圖是由名為CATJOBQ.SQL的腳本文件創(chuàng)建的。該腳本文件和創(chuàng)建DBMS_JOB包的腳本文件一樣在ORACLE_HOME目錄的rdbms/admin子目錄中,同樣也是由腳本文件CATPROC.SQL調(diào)用。

          最后,要使任務隊列能正常運行,還必須啟動它自己專有的后臺過程。啟動后臺過程是通過在初始化文件init*.ora(實例不同,初始化文件名也略有不同)中設(shè)置初始化參數(shù)來進行的。下面就是該參數(shù):

          JOB_QUEUE_PROCESSES = n 

          其中,n可以是0到36之間的任何一個數(shù)。除了該參數(shù)以外,還有幾個關(guān)于任務隊列的初始化參數(shù),本文后面將會對其進行詳細討論。

          DBMS_JOB包中包含有許多過程,見表1所示。

          表1 DBMS_JOB包

           

          名稱 類型 描述
          DBMS_JOB.ISUBMIT 過程 提交一個新任務,用戶指定一個任務號
          DBMS_JOB.SUBMIT 過程 提交一個新任務,系統(tǒng)指定一個任務號
          DBMS_JOB.REMOVE 過程 從隊列中刪除一個已經(jīng)存在的任務
          DBMS_JOB.CHANGE 過程 更改用戶設(shè)定的任務參數(shù)
          DBMS_JOB.WHAT 過程 更改PL/SQL任務定義
          DBMS_JOB.NEXT_DATE 過程 更改任務下一次運行時間
          DBMS_JOB.INTERVAL 過程 更改任務運行的時間間隔
          DBMS_JOB.BROKEN 過程 將任務掛起,不讓其重復運行
          DBMS_JOB.RUN 過程 在當前會話中立即執(zhí)行任務
          DBMS_JOB.USER_EXPORT 過程 創(chuàng)建文字字符串,用于重新創(chuàng)建一個任務

          三、DBMS_JOB包參數(shù)

          DBMS_JOB包中所有的過程都有一組相同的公共參數(shù),用于定義任務,任務的運行時間以及任務定時運行的時間間隔。這些公共任務定義參數(shù)見表2所示。

          表2 DBMS_JOB過程的公共參數(shù)

           

          名稱 類型 注釋
          Job BINARY_INTEGER 任務的唯一識別號
          What VARCHAR2 作為任務執(zhí)行的PL/SQL代碼
          Next_date VARCHAR2 任務下一次運行的時間
          Interval VARCHAR2 日期表達式,用來計算下一次任務運行的時間

          下面我們來詳細討論這些參數(shù)的意義及用法。

          1、job

          參數(shù)job是一個整數(shù),用來唯一地標示一個任務。該參數(shù)既可由用戶指定也可由系統(tǒng)自動賦予,這完全取決于提交任務時選用了那一個任務提交過程。DBMS_JOB.SUBMIT過程通過獲得序列SYS.JOBSEQ的下一個值來自動賦予一個任務號。該任務號是作為一個OUT參數(shù)返回的,所以調(diào)用者隨后可以識別出提交的任務。而DBMS_JOB.ISUBMIT過程則由調(diào)用者給任務指定一個識別號,這時候,任務號的唯一性就完全取決于調(diào)用者了。

          除了刪除或者重新提交任務,一般來說任務號是不能改變的。即使當數(shù)據(jù)庫被導出或者被導入這樣極端的情況,任務號也將被保留下來。所以在執(zhí)行含有任務的數(shù)據(jù)的導入/導出操作時很可能會發(fā)生任務號沖突的現(xiàn)象。

          2、what

          what參數(shù)是一個可以轉(zhuǎn)化為合法PL/SQL調(diào)用的字符串,該調(diào)用將被任務隊列自動執(zhí)行。在what參數(shù)中,如果使用文字字符串,則該字符串必須用單引號括起來。 what參數(shù)也可以使用包含我們所需要字符串值的VARCHAR2變量。實際的PL/SQL調(diào)用必須用分號隔開。在PL/SQL調(diào)用中如果要嵌入文字字符串,則必須使用兩個單引號。

          what參數(shù)的長度在Oracle7.3中限制在2000個字節(jié)以內(nèi),在Oracle 8.0以后,擴大到了4000個字節(jié),這對于一般的應用已完全足夠。該參數(shù)的值一般情況下都是對一個PL/SQL存儲過程的調(diào)用。在實際應用中,盡管可以使用大匿名Pl/SQL塊,但建議大家最好不要這樣使用。還有一個實際經(jīng)驗就是最好將存儲過程調(diào)用封裝在一個匿名塊中,這樣可以避免一些比較莫名錯誤的產(chǎn)生。我來舉一個例子,一般情況下,what參數(shù)可以這樣引用:

           

          what =>’my_procedure(parameter1);’

          但是比較安全的引用,應該這樣寫:

          what =>’begin my_procedure(parameter1); end;’

          任何時候,我們只要通過更改what參數(shù)就可以達到更改任務定義的目的。但是有一點需要注意,通過改變what參數(shù)來改變?nèi)蝿斩x時,用戶當前的會話設(shè)置也被記錄下來并成為任務運行環(huán)境的一部分。如果當前會話設(shè)置和最初提交任務時的會話設(shè)置不同,就有可能改變?nèi)蝿盏倪\行行為。意識到這個潛在的副作用是非常重要的,無論何時只要應用到任何DBMS_JOB過程中的what參數(shù)時就一定要確保會話設(shè)置的正確。

          3、next_date

          Next_date參數(shù)是用來調(diào)度任務隊列中該任務下一次運行的時間。這個參數(shù)對于DBMS_JOB.SUBMIT和DBMS_JOB.BROKEN這兩個過程確省為系統(tǒng)當前時間,也就是說任務將立即運行。

          當將一個任務的next_date參數(shù)賦值為null時,則該任務下一次運行的時間將被指定為4000年1月1日,也就是說該任務將永遠不再運行。在大多數(shù)情況下,這可能是我們不愿意看到的情形。但是,換一個角度來考慮,如果想在任務隊列中保留該任務而又不想讓其運行,將next_date設(shè)置為null卻是一個非常簡單的辦法。

          Next_date也可以設(shè)置為過去的一個時間。這里要注意,系統(tǒng)任務的執(zhí)行順序是根據(jù)它們下一次的執(zhí)行時間來確定的,于是將next_date參數(shù)設(shè)置回去就可以達到將該任務排在任務隊列前面的目的。這在任務隊列進程不能跟上將要執(zhí)行的任務并且一個特定的任務需要盡快執(zhí)行時是非常有用的。

          4、Interval

          Internal參數(shù)是一個表示Oracle合法日期表達式的字符串。這個日期字符串的值在每次任務被執(zhí)行時算出,算出的日期表達式有兩種可能,要么是未來的一個時間要么就是null。這里要強調(diào)一點:很多開發(fā)者都沒有意識到next_date是在一個任務開始時算出的,而不是在任務成功完成時算出的。

          當任務成功完成時,系統(tǒng)通過更新任務隊列目錄表將前面算出的next_date值置為下一次任務要運行的時間。當由interval表達式算出next_date是null時,任務自動從任務隊列中移出,不會再繼續(xù)執(zhí)行。因此,如果傳遞一個null值給interval參數(shù),則該任務僅僅執(zhí)行一次。

          通過給interval參數(shù)賦各種不同的值,可以設(shè)計出復雜運行時間計劃的任務。本文后面的“任務間隔和日期算法”將對interval表達式進行詳細討論,并給出一個實際有用interval表達式的例子。

          四、任務隊列架構(gòu)和運行環(huán)境

          任務隊列在Oracle系統(tǒng)中其實是一個子系統(tǒng),它具有自己特定的后臺過程和目錄表。該子系統(tǒng)設(shè)計的目的是為了能不在用戶干預下自動運行PL/SQL過程。

          1、任務隊列后臺過程

          任務隊列(SNP)后臺過程隨著Oracle實例的啟動而同時啟動。在文章前面已經(jīng)談到初始化文件init.ora中的參數(shù)JOB_QUEUE_PROCESSES,用來設(shè)置有幾個隊列過程。這里設(shè)置了幾個過程,系統(tǒng)中就會有幾個SNP過程被啟動。JOB_QUEUE_PROCESSES這個參數(shù),可以是0到36中的任何一個數(shù),也就是說對于每個Oracle實例最多可以有36個SNP過程,也可以不支持隊列過程(=0)。在大多數(shù)操作系統(tǒng)中,SNP三個字母常作為過程名的一部分出現(xiàn)。如,在unix系統(tǒng)中,如果該Oracle實例名為ora8,有三個任務隊列過程,則這三個任務隊列過程名稱為:

           

          ora_ora8_snp0
          ora_ora8_snp1
          ora_ora8_snp2

          SNP后臺過程和其他的Oracle后臺過程的一個重要區(qū)別就是殺掉一個SNP過程不會影響到Oracle實例。當一個任務隊列過程失控或者消耗太多的資源時,就可以將其殺掉,當然這種情況不是經(jīng)常遇到的。當一個SNP過程被殺掉或者失敗時,Oracle就自動啟動一個新的SNP過程來代替它。

          2、有關(guān)任務隊列的初始化參數(shù)

          初始化文件init.ora中的幾個參數(shù)控制著任務隊列后臺的運行,下面我們將對其進行詳細討論。

          (1)、JOB_QUEUE_INTERVAL

          任務隊列過程定期喚醒并檢查任務隊列目錄表是否有任務需要執(zhí)行。參數(shù)JOB_QUEUE_INTERVAL決定SNP過程兩次檢查目錄表之間“休眠”多長時間(單位為秒)。間隔設(shè)的太小會造成由于SNP過程不斷檢查目錄表而導致不必要的系統(tǒng)吞吐量。相反如果間隔設(shè)得太大,SNP過程在特定的時間沒有被喚醒,那個時間的任務就不會能被運行。最佳的時間間隔設(shè)置要綜合考慮系統(tǒng)環(huán)境中不同的任務,60秒的確省設(shè)置可以滿足大多數(shù)的應用。

          (2)、JOB_QUEUE_KEEP_CONNECTIONS

          除了前面介紹的JOB_QUEUE_PROCESS和JOB_QUEUE_INTERVAL兩個參數(shù)以外,影響SNP后臺過程行為的第三個參數(shù)是JOB_QUEUE_KEEP_CONNECTIONS。當該參數(shù)為TRUE時,SNP過程在兩個任務的運行期間(也就是休眠期間),仍然和Oracle保持開放的連接。相反,如果為FALSE時,SNP過程將和數(shù)據(jù)庫斷開連接,當喚醒時刻到來時又重新連接并檢查任務隊列。

          選擇這兩種方法中的那一種,主要是考慮任務隊列的有效性和數(shù)據(jù)庫關(guān)閉方法。長期保持連接的效率比較高,但任務隊列會受到正常關(guān)閉數(shù)據(jù)庫的影響。這是因為任務隊列過程對于服務器管理器看來和一個普通用戶的過程沒有什么不同,而正常的關(guān)閉數(shù)據(jù)庫需要讓所有的用戶都斷開連接。而斷開連接和重新連接又給數(shù)據(jù)庫增加了負荷,但是可定期地使數(shù)據(jù)庫沒有可連接SNP過程,也就可以使數(shù)據(jù)庫正常關(guān)閉。對于有很多任務或者是任務重復執(zhí)行的時間間隔較短(一個小時或者更少)的環(huán)境,一般將JOB_QUEUE_KEEP_CONNECTIOONS設(shè)置為TRUE,并修改關(guān)閉數(shù)據(jù)庫的腳本為立即關(guān)閉。對于嚴格要求采用正常方式關(guān)閉的數(shù)據(jù)庫或者是任務較少,重復間隔較長的環(huán)境,一般將該參數(shù)設(shè)置為FALSE。最好,要提醒一句,SNP過程僅在沒有任何任務運行時才斷開,這種情況下,那些需要比較長時間運行的任務SNP將在它們的生命周期內(nèi)一致保持開放的連接,這就延遲了正常關(guān)閉數(shù)據(jù)庫的時間。

          3、建立運行環(huán)境

          當SNP過程喚醒時,它首先查看任務隊列目錄中所有的任務是否當前的時間超過了下一次運行的日期時間。SNP檢測到需要該時間立即執(zhí)行的任務后,這些任務按照下一次執(zhí)行日期的順序依次執(zhí)行。當SNP過程開始執(zhí)行一個任務時,其過程如下:

          1. 以任務所有者的用戶名開始一個新的數(shù)據(jù)庫會話。
          2. 當任務第一次提交或是最后一次被修改時,更改會話NLS設(shè)置和目前就緒的任務相匹配。
          3. 通過interval日期表達式和系統(tǒng)時間,計算下一次執(zhí)行時間。
          4. 執(zhí)行任務定義的PL/SQL
          5. 如果運行成功,任務的下一次執(zhí)行日期(next_date)被更新,否則,失敗計數(shù)加1。
          6. 經(jīng)過JOB_QUEUS_INTERVAL秒后,又到了另一個任務的運行時間,重復上面的過程。

          在前兩步中,SNP過程創(chuàng)建了一個模仿用戶運行任務定義的PL/SQL的會話環(huán)境。然而,這個模仿的運行環(huán)境并不是和用戶實際會話環(huán)境完全一樣,需要注意以下兩點:第一,在任務提交時任何可用的非確省角色都將在任務運行環(huán)境中不可用。因此,那些想從非確省角色中取得權(quán)限的任務不能提交,用戶確省角色的修改可以通過在任務未來運行期間動態(tài)修改來完成。第二,任何任務定義本身或者過程執(zhí)行中需要的數(shù)據(jù)庫聯(lián)接都必須完全滿足遠程的用戶名和密碼。SNP過程不能在沒有顯式指明口令的情況下初始化一個遠程會話。顯然,SNP過程不能假定將本地用戶的口令作為遠程運行環(huán)境會話設(shè)置的一部分。

          提交的任務如果運行失敗會怎么樣呢?當任務運行失敗時,SNP過程在1分鐘后將再次試圖運行該任務。如果這次運行又失敗了,下一次嘗試將在2分鐘后進行,再下一次在4分鐘以后。任務隊列每次加倍重試間隔直到它超過了正常的運行間隔。在連續(xù)16次失敗后,任務就被標記為中斷的(broken),如果沒有用戶干預,任務隊列將不再重復執(zhí)行。

          五、任務隊列字典表和視圖

          任務隊列中的任務信息可以通過表3所示的幾個字典視圖來查看,這些視圖是由CATJOBQ.sql腳本創(chuàng)建的。表4和5是各個視圖每個字段的含義。

          表3. 任務隊列中關(guān)于任務的數(shù)據(jù)字典視圖

           

          視圖名 描述
          DBA_JOBS 本數(shù)據(jù)庫中定義到任務隊列中的任務
          DBA_JOBS_RUNNING 目前正在運行的任務
          USER_JOBS 當前用戶擁有的任務

          表4. DBA_JOBS 和 USER_JOBS.字典視圖的字段含義

           

          字段(列) 類型 描述
          JOB NUMBER 任務的唯一標示號
          LOG_USER VARCHAR2(30) 提交任務的用戶
          PRIV_USER VARCHAR2(30) 賦予任務權(quán)限的用戶
          SCHEMA_USER VARCHAR2(30) 對任務作語法分析的用戶模式
          LAST_DATE DATE 最后一次成功運行任務的時間
          LAST_SEC VARCHAR2(8) 如HH24:MM:SS格式的last_date日期的小時,分鐘和秒
          THIS_DATE DATE 正在運行任務的開始時間,如果沒有運行任務則為null
          THIS_SEC VARCHAR2(8) 如HH24:MM:SS格式的this_date日期的小時,分鐘和秒
          NEXT_DATE DATE 下一次定時運行任務的時間
          NEXT_SEC VARCHAR2(8) 如HH24:MM:SS格式的next_date日期的小時,分鐘和秒
          TOTAL_TIME NUMBER 該任務運行所需要的總時間,單位為秒
          BROKEN VARCHAR2(1) 標志參數(shù),Y標示任務中斷,以后不會運行
          INTERVAL VARCHAR2(200) 用于計算下一運行時間的表達式
          FAILURES NUMBER 任務運行連續(xù)沒有成功的次數(shù)
          WHAT VARCHAR2(2000) 執(zhí)行任務的PL/SQL塊
          CURRENT_SESSION_LABEL RAW MLSLABEL 該任務的信任Oracle會話符
          CLEARANCE_HI RAW MLSLABEL 該任務可信任的Oracle最大間隙
          CLEARANCE_LO RAW MLSLABEL 該任務可信任的Oracle最小間隙
          NLS_ENV VARCHAR2(2000) 任務運行的NLS會話設(shè)置
          MISC_ENV RAW(32) 任務運行的其他一些會話參數(shù)

          表 5. 視圖DBA_JOBS_RUNNING的字段含義

           

          數(shù)據(jù)類型 描述
          SID NUMBER 目前正在運行任務的會話ID
          JOB NUMBER 任務的唯一標示符
          FAILURES NUMBER 連續(xù)不成功執(zhí)行的累計次數(shù)
          LAST_DATE DATE 最后一次成功執(zhí)行的日期
          LAST_SEC VARCHAR2(8) 如HH24:MM:SS格式的last_date日期的小時,分鐘和秒
          THIS_DATE DATE 目前正在運行任務的開始日期
          THIS_SEC VARCHAR2(8) 如HH24:MM:SS格式的this_date日期的小時,分鐘和秒

          六、任務重復運行間隔和間隔設(shè)計算法

          任務重復運行的時間間隔取決于interval參數(shù)中設(shè)置的日期表達式。下面就來詳細談談該如何設(shè)置interval參數(shù)才能準確滿足我們的任務需求。一般來講,對于一個任務的定時執(zhí)行,有三種定時要求。

          1. 在一個特定的時間間隔后,重復運行該任務。
          2. 在特定的日期和時間運行任務。
          3. 任務成功完成后,下一次執(zhí)行應該在一個特定的時間間隔之后。

          第一種調(diào)度任務需求的日期算法比較簡單,即'SYSDATE+n',這里n是一個以天為單位的時間間隔。表6給出了一些這種時間間隔設(shè)置的例子。

          表6 一些簡單的interval參數(shù)設(shè)置例子

           

          描述 Interval參數(shù)值
          每天運行一次 'SYSDATE + 1'
          每小時運行一次 'SYSDATE + 1/24'
          每10分鐘運行一次 'SYSDATE + 10/(60*24)'
          每30秒運行一次 'SYSDATE + 30/(60*24*60)'
          每隔一星期運行一次 'SYSDATE + 7'
          不再運行該任務并刪除它 NULL

          表6所示的任務間隔表達式不能保證任務的下一次運行時間在一個特定的日期或者時間,僅僅能夠指定一個任務兩次運行之間的時間間隔。例如,如果一個任務第一次運行是在凌晨12點,interval指定為'SYSDATE + 1',則該任務將被計劃在第二天的凌晨12點執(zhí)行。但是,如果某用戶在下午4點手工(DBMS_JOB.RUN)執(zhí)行了該任務,那么該任務將被重新定時到第二天的下午4點。還有一個可能的原因是如果數(shù)據(jù)庫關(guān)閉或者說任務隊列非常的忙以至于任務不能在計劃的那個時間點準時執(zhí)行。在這種情況下,任務將試圖盡快運行,也就是說只要數(shù)據(jù)庫一打開或者是任務隊列不忙就開始執(zhí)行,但是這時,運行時間已經(jīng)從原來的提交時間漂移到了后來真正的運行時間。這種下一次運行時間的不斷“漂移”是采用簡單時間間隔表達式的典型特征。

          第二種調(diào)度任務需求相對于第一種就需要更復雜的時間間隔(interval)表達式,表7是一些要求在特定的時間運行任務的interval設(shè)置例子。

          表 7. 定時到特定日期或時間的任務例子

           

          描述 INTERVAL參數(shù)值
          每天午夜12點 'TRUNC(SYSDATE + 1)'
          每天早上8點30分 'TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)'
          每星期二中午12點 'NEXT_DAY(TRUNC(SYSDATE ), ''TUESDAY'' ) + 12/24'
          每個月第一天的午夜12點 'TRUNC(LAST_DAY(SYSDATE ) + 1)'
          每個季度最后一天的晚上11點 'TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), 'Q' ) -1/24'
          每星期六和日早上6點10分 'TRUNC(LEAST(NEXT_DAY(SYSDATE, ''SATURDAY"), NEXT_DAY(SYSDATE, "SUNDAY"))) + (6×60+10)/(24×60)'

          第三種調(diào)度任務需求無論通過怎樣設(shè)置interval日期表達式也不能滿足要求。這時因為一個任務的下一次運行時間在任務開始時才計算,而在此時是不知道任務在何時結(jié)束的。遇到這種情況怎么辦呢?當然辦法肯定是有的,我們可以通過為任務隊列寫過程的辦法來實現(xiàn)。這里我只是簡單介紹以下,可以在前一個任務隊列執(zhí)行的過程中,取得任務完成的系統(tǒng)時間,然后加上指定的時間間隔,拿這個時間來控制下一個要執(zhí)行的任務。這里有一個前提條件,就是目前運行的任務本身必須要嚴格遵守自己的時間計劃。

          結(jié)論

          Oracle中的定時任務是在Oracle系統(tǒng)中是一個非常重要的子系統(tǒng),運用得當,可以極大的提高我們的系統(tǒng)運行和維護能力。而Oracle數(shù)據(jù)復制的延遲事務隊列管理完全是基于Oracle的隊列任務,對其的深刻理解有助于我們更好地管理數(shù)據(jù)復制。


          posted on 2009-08-26 10:30 鴻雁 閱讀(458) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 龙岩市| 石楼县| 海口市| 泗阳县| 孟州市| 靖江市| 县级市| 琼海市| 内江市| 东乡| 宽甸| 福清市| 炎陵县| 天祝| 朝阳县| 泸州市| 定结县| 壶关县| 泉州市| 长海县| 项城市| 北碚区| 成都市| 嘉善县| 翁牛特旗| 乐安县| 镇赉县| 延安市| 刚察县| 凯里市| 章丘市| 乌什县| 元谋县| 安溪县| 普格县| 安平县| 依安县| 肇庆市| 高陵县| 昌平区| 通河县|