標籤:style color io os 使用 ar strong for 檔案
一,啟動執行作業的進程 在 Oracle 中,是使用 “作業隊列協調進程(CJQ0)” 這個協調資料庫執行個體的作業隊列的後台進程,來監視作業隊列中的作業表(JOB$),並啟動作業隊列進程(Jnnn)。而當需要執行作業的時候,作業隊列Jnnn 將會執行由 DBMS_JOBS 包建立的作業請求,如下面的一個過程就是從 DBMS_JOBS 包中提取出來的
* 提交的作業請求的過程聲明:
PROCEDURE submit ( job OUT BINARY_INTEGER,
what IN VARCHAR2,
next_date IN DATE DEFAULT sysdate,
interval IN VARCHAR2 DEFAULT ‘null‘,
no_parse IN BOOLEAN DEFAULT FALSE,
instance IN BINARY_INTEGER DEFAULT 0,
force IN BOOLEAN DEFAULT FALSE );
-- Submit a new job. Chooses JOB from the sequence sys.jobseq.
-- instance and force are added for jobq queue affinity
-- If FORCE is TRUE, then any positive integer is acceptable as the job
-- instance. If FORCE is FALSE, then the specified instance must be running;
-- otherwise the routine raises an exception.
-- For example,
-- variable x number;
-- execute dbms_job.submit(:x,‘pack.proc(‘‘arg1‘‘);‘,sysdate,‘sysdate+1‘);
下面再通過包中給出的參數的含義就可以知道當我們需要添加作業的時候的各個參數各有什麼含義了:
- job 指定被執行的作業的作業號
- what 指定需要被執行的 pl/sql 代碼
- next_date 作業下一次已耗用時間,預設值為 sysdate
- interval 這裡是用來計算下一次作業執行時間的日期函數,預設為 NULL。(基本是估算)
- no_parse 一個標記。false(預設): Oracle 將分析與作業相關聯的過程。true: 將分析與首次執行的作業相關聯的過程。例如:如果希望在建立與作業相關聯的表完成之前提交作業,就需要設定為 true。
* 刪除先前提交的作業:
PROCEDURE remove ( job IN BINARY_INTEGER );
-- Remove an existing job from the job queue.
-- This currently does not stop a running job.
-- execute dbms_job.remove(14144);
* 更改作業:
PROCEDURE change ( job IN BINARY_INTEGER,
what IN VARCHAR2,
next_date IN DATE,
interval IN VARCHAR2,
instance IN BINARY_INTEGER DEFAULT NULL,
force IN BOOLEAN DEFAULT FALSE);
-- Change any of the the user-settable fields in a job
-- Parameter instance and force are added for job queue affinity
-- If what, next_date,or interval is null, leave that value as-is.
-- instance defaults to NULL indicates instance affinity is not changed.
-- If FORCE is FALSE, the specified instance (to which the instance number
-- change) must be running. Otherwise the routine raises an exception.
-- If FORCE is TRUE, any positive integer is acceptable as the job instance.
-- execute dbms_job.change( 14144, null, null, ‘sysdate+3‘);
* 對指定的作業修改作業說明
PROCEDURE what ( job IN BINARY_INTEGER,
what IN VARCHAR2 );
-- Change what an existing job does, and replace its environment
* 修改指定作業的下一次執行時間
PROCEDURE next_date ( job IN BINARY_INTEGER,
next_date IN DATE );
-- Change when an existing job will next execute
* 修改指定作業的執行間隔
PROCEDURE interval ( job IN BINARY_INTEGER,
interval IN VARCHAR2 );
-- Change how often a job executes * 設定或者重新設定作業損壞標記,如果作業損壞,則作業不能運行
PROCEDURE broken ( job IN BINARY_INTEGER,
broken IN BOOLEAN,
next_date IN DATE DEFAULT SYSDATE );
-- Set the broken flag. Broken jobs are never run.
* 強制執行某個指定的作業
PROCEDURE run ( job IN BINARY_INTEGER,
force IN BOOLEAN DEFAULT FALSE);
-- Run job JOB now. Run it even if it is broken.
-- Running the job will recompute next_date, see view user_jobs.
-- execute dbms_job.run(14144);
-- Warning: this will reinitialize the current session‘s packages
-- FORCE is added for job queue affinity
-- If FORCE is TRUE, instance affinity is irrelevant for running jobs in
-- the foreground process. If FORCE is FALSE, the job can be run in the
-- foreground only in the specified instance. dbms_job.run will raise an
-- exception if FORCE is FALSE and the connected instance is the wrong one.
其中,初始化參數 JOB_QUEUE_PROCESSES 控制資料庫執行個體能否啟動一個協調作業隊列程式進程。如果這個參數值為 0,表示在資料庫啟動的時候不啟動作業隊列協調進程,當然也不會執行作業隊列中的任何作業。該參數也可以指定在一個執行個體上能夠並發運行 Jnnn 進程的最大數目。可以指定的最大進程數目為 1000。
並且該參數是動態,可以使用如下語句動態更改設定:
alter system set JOB_QUEUE_PROCESSES = 20;
二,管理作業隊列 1,要使用以及管理作業隊列中的作業,可以使用 DBMS_JOB 包中的過程,並且使用作業隊列並不需要資料庫許可權,只要你有執行作業隊列過程的許可權既可。
2,下面舉些例子吧,這樣更 “實惠”:)
declare
-- Local variables here
jobno number;
begin
dbms_job.submit(jobno, ‘dbms_ddl.analyze_object(‘‘TABLE‘‘,‘‘SCOTT‘‘, ‘‘EMP‘‘, ‘‘ESTIMATE‘‘, ‘‘NULL‘‘, 50);‘, SYSDATE, ‘SYSDATE+1‘);
end;
3,下面是和作業(JOB)相關的一些屬性:
* 作業所有者
* 作業號碼 隊列中的作業用作業號碼進行標識。當提交作業時,它的作業號碼將從 sys.jobseq 序列中自動產生。一旦分配就不可以再更改作業號碼了。
* 工作定義 就是提交作業(submit)時指定的 what 需要執行的 pl/sql 代碼。這裡需要注意的是在工作定義中,需要使用兩個單引號括住字串哦,如同使用動態 sql 中的字串;還有,不能從一個作業中運行另一個作業。
* 作業執行間隔 用於指定兩次作業執行的間隔時間,也可以認為你的作業向間隔多長時間執行一次,特別適合那些周期性的任務。
一些常用的日期運算式:
- sysdate+7 每周運行一次
- sysdate+1/48 每半小時運行一次
- next_day(trunc(sysdate), "MONDAY")+15/24 每個星期一的下午 3 點開始運行
- next_day(add_months(trunc(sysdate, "Q"), 3), ‘TRUSDAY‘) 每個季度的第一個星期四
注意:
(1) 例如,如果在周一設定了執行間隔為“sysdate+7”, 但是因某種原因,沒有執行,直到周四才執行,則下次執行的時間是在每周四開始執行作業了。如果 interval 日期函數求出來的值是 NULL,
(2) 當然,如果你希望你作業一直在某個時間點開始執行,而不管上次執行的結束時間,則你的 interval 和 next_date 參數都應該如下方式指定:next_day(trunc(sysdate), "MONDAY")
4,下面我們再看看作業隊列是如何啟動並執行,以及其運行狀態的查看
(1) Oracle 通過使用作業隊列鎖來確保每次作業只是在一個會話中運行。可以使用鎖視圖來查看會話程式當前鎖的相關資訊:
select * from v$lock where type = ‘JQ‘;
也可以通過查看正在啟動並執行作業的情況:
select * from dba_jobs_running;
(2) 作業執行錯誤,有關失敗的資訊會紀錄在追蹤檔案和警示日誌中,並且 Oracle 會寫入編號為 Ora-12012 的訊息並包括失敗作業的作業號。
(3) 刪除作業,dbms_job.remove(作業號);
(4) 更改作業,
- dbms_job.change(作業號,NULL,NULL,‘SYSDATE+3‘);
將作業改為每三天運行一次
- dbms_job.what(作業號,‘scott.emppackage.give_raise(‘‘abc‘‘, 6000.00);‘);
改變作業的定義
- dbms_job.next_date(作業號,‘SYSDATE+5‘);
改變作業的下一次執行時間
- dbms_job.interval(作業號,NULL);
成功執行作業之後將不再運行該作業
三,查看作業隊列資訊 相關的資料字典視圖有:
* dba_jobs 資料庫中的所有作業
* all_jobs 目前使用者可以訪問的所有作業
* user_jobs 屬於目前使用者的所有作業
* dba_jobs_running 列出資料庫中當前啟動並執行所有作業
Oracle 中的作業隊列和隊列調度