Job隊列的管理
?
??? 之前學習過一次Job的管理了,但是這次在學習DBA的時候看到,就從理論的高度再重新全面得學習一回。Job的管理比較簡單,主要就是對DBMS_JOB這個包的應用和一些參數的設置,而且DBMS_JOB包也比較簡單,不需要太復雜的記憶,基本上看一遍就能記住。在建立JOB的時候,最需要注意的還是時間的偏移問題,需要解決好。
?
?
一、Job執行基礎知識
?
??? 1、作業隊列進程(Jnnn)
?
??? Oracle使用Job隊列進程(Jnnn)來執行作業隊列中的Job。對于每一個實例,這些Job隊列進程都是由Job隊列協調程序(CJQ0)后臺進程動態派生的。
??? CJQ0定期從DBA_JOBS視圖中選出準備運行的Job,并按時間排序,然后派生出Jnnn進程運行選中的Job,每個Jnnn執行一個Job。
?
??? 2、JOB_QUEUE_PROCESSES參數
?
??? JOB_QUEUE_PROCESSES參數用于控制一個實例上能夠并發運行Jnnn進程的最大數目,例如:
??? JOB_QUEUE_PROCESSES = 60 指同一時間最多并發處理60個Job
?
??? 另:如果JOB_QUEUE_PROCESSES = 0則表示數據庫啟動時不啟動任何Job隊列協調程序進程,也不執行任何Job
?
??? 3、JOB_QUEUE_PROCESSES的修改
?
??? Jnnn由Job隊列協調進程創建,每次按需要創建Job隊列所需的最多的Jnnn進程。當Jnnn執行完某個Job時,它將輪詢另一個要執行的Job,如果沒有要執行的Job,則該進程進入空閑狀態,并在指定時間后再次輪詢,在輪詢到預定次數后,如果還沒有找到要執行的作業,則該進程終止。
?
??? ALTER SYSTEM SET JOB_QUEUE_PROCESSES; 可用該語句動態修改最大并發Jnnn進程數目
?
??? 注1:如果ALTER SYSTEM修改后的JOB_QUEUE_PROCESSES小于當前執行的Jnnn數,則允許超出的執行完當前任務。
??? 注2:如果實例運行在受限模式,則Jnnn進程不執行Job
?
?
二、管理Job隊列
?
??? 1、DBMS_JOB包
?
??? Oracle中使用DBMS_JOB包來執行JOB的管理操作,具體包括以下過程:
?
??? SUBMIT??? :將Job提交到Job隊列
??? REMOVE??? :從Job隊列中刪除指定Job
??? CHANGE??? :修改Job( WHAT + NEXT_DATE + INTERVAL )
??? WHAT????? :修改Job的說明(SQL語句)
??? NEXT_DATE :修改Job的下一次執行時間
? ? INTERVAL? :修改Job的執行間隔
?? BROKEN??? :設置Job損壞標記(不再執行)
??? RUN?????? :強制執行Job
?
??? 2、DBMS_JOB.SUBMIT
?
??? 使用DBMS_JOB.SUBMIT來提交JOB,主要有以下參數:
?
??? JOB?????? :這是一個輸出參數,是系統分配給JOB的標識符。
??? WHAT????? :希望執行的PL/SQL代碼
??? NEXT_DATE :Job下一次運行的日期,默認為SYSDATE
??? INTERVAL? :計算下一次執行的日期,默認值為NULL
??? NO_PARSE? :TRUE-分析與首次執行Job相關聯的過程;FALSE-分析與Job相關的過程(???)
?
??? 具體的說明如下:
?
????? a) 作業環境
?
??????? 當Job被提交時,Oracle還會記錄以下信息:
??????? * 當前user
??????? * 提交或更改Job的user
??????? * 當前schema(可能用了alter session set current_schema語句)
??????? * MAC權限
??????? * NLS_LANGUAGE
??????? * NLS_TERRITORY
??????? * NLS_CURRENCY
??????? * NLS_ISO_CURRENCY
??????? * NLS_NUMERIC_CHARACTERS
??????? * NLS_DATE_FORMAT
??????? * NLS_DATE_LANGUAGE
??????? * NLS_SORT
?
????? b) Job的導入和導出
?
??????? 可以在數據庫之間導入和導出Job,如果導入時的標識符相同,則不能導入,作為新Job提交
?
????? c) Job所有者
?
??????? 提交者即為Job的所有者,只有Job的所有者可以對Job進行修改、強制執行、刪除
?
?? ?? d) Job號碼
?
??????? 用于區分的唯一標識符,由SYS.JOBSEQ序列自動產生,永遠不能修改,除非刪除重建
?
????? e) Job定義
?
??????? 一般在SUBMIT中的WHAT參數都是對某個過程的調用,使用單引號標注。
?
??????? 注:不能從一個Job中run另一個Job(remove等其他操作是可以的)
?
????? f) Job執行間隔
?
??????? 在Job當前執行完成后,會馬上計算INTERVAL的指,來指定下一次的運行時間,下面的INTERVAL指都是正確的:
??????? 'SYSDATE + 7' --本次執行后的7天
??????? 'SYSDATE + 1/48' --本次執行后的半小時
??????? 'NEXT_DAY(TRUNC(SYSDATE),''MONDAY'') + 15/24' --每個星期一下午3點
??????? 'NEXT_DAY(ADD_MONTHS(TRUNC(SYSDATE,''Q''),3),''THURSDAY'')' --每個季度星期四
?
??????? 注:要注意其中的''分隔
?
?? ?? g) 數據庫鏈接和Job
?
??????? 如果在Job中使用到了數據庫的鏈接,那么必須包括用戶名和密碼,如果是匿名鏈接,則提交不成功
?
??? 3、Job的執行
?
??? Jnnn執行Job時,擁有Job所有者的默認權限,所有者必須為Job中引用的所有對象授予所需的對象權限
??? 當用DBMS_JOB.RUN強制執行Job時:用戶只有所有者的默認權限,所有用過角色授予Job所有者的權限都不可用
?
????? a) Job隊列鎖
?
??????? Oracle使用Job隊列鎖確保每次Job只在一個會話中執行。
?
??????? 通過查找V$JOB視圖的'JQ'類型鎖,可以查看明細信息:
??????? SELECT SID,TYPE,ID1,ID2 FROM V$LOCK WHERE TYPE = 'JQ'; --ID2表示Job標識符
?
????? b) Job執行錯誤
?
??????? Job執行失敗時,報ORA-12012錯,主要是這樣幾個原因:
??????? ① 網絡失敗或實例失敗
??????? ② 當執行Job時發生異常情況
?
??????? 若Job返回錯誤,則Oracle會在1分鐘后重試,然后在2分鐘后重試,再在4分鐘后重試,每次間隔都是前一次的2倍。
??????? 直到失敗16次,則將該Job標記為“損壞”,并且不再嘗試執行該Job。
?
??? 4、刪除Job
?
??? DBMS_JOB.REMOVE(14144); --直接輸入Job號即可
?
??? 限制:
??????? ① 可以刪除目前正在執行的Job,但Job會執行完成當前任務后再被刪除
??????? ② 只能刪除自己的所有Job,若要刪除其他user的Job,會報錯Job不在列表中
?
??? 5、更改Job
?
??? 使用CHANGE、WHAT、NEXT_DATE、INTERVAL來修改,只要注明Job號即可。
?
??? 限制:還是只能修改自己所有的Job
?
??? 6、損壞的Job
?
??? Job被標記為損壞只有兩種途徑:
??? ① 嘗試執行16次失敗
??? ② 用DBMS_JOB.BROKEN標記為損壞
?
??? 運行被標注為損壞的Job也只有兩種途徑:
??? ① 用DBMS_JOB.RUN強制執行
??? ② 用DBMS_JOB.BROKEN標記用未損壞
?
??? 示例:
??? DBMS_JOB.BROKEN(14144, TRUE); --標記為損壞
??? DBMS_JOB.BROKEN(14144, FALSE, NEXT_DAY(SYSDATE, 'MONDAY')); --標記為未損壞并設置執行間隔
?
?? 7、強制執行Job
?
??? 直接用 DBMS_JOB.RUN(14144); 來強制執行Job
?
??? 注意:一但使用RUN后將不能回滾該Job,而且INTERVAL將會重新計算下一次執行時間
?
?? 8、終止Job
?
??? 使用 DBMS_JOB.BROKEN 或 KILL SESSION 兩種方法來終止Job
?
?
三、查看Job信息
?
??? DBA_JOBS:所有Job的信息
?? ALL_JOBS:當前用戶可以訪問的所有Job信息
??? DBA_JOBS_RUNNING:當前運行的Job信息
?
?
?