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