PolarDB提供DBMS_JOB包調度與管理定時任務。本文為您介紹如何創建、管理和刪除一個定時任務。
前提條件
- DBMS_JOB支持用戶自行通過配置參數開啟。方法如下:
- 登錄PolarDB控制臺,找到目標集群。
- 在左側導航欄中,選擇 。
- 在shared_preload_libraries參數的插件列表中添加
dbms_job
。
- PolarDB集群的內核版本為V1.1.7及以上版本。如何查看內核版本,請參見新版本更新說明。
注意事項
- DBMS_JOB僅支持高權限用戶使用。如何創建高權限賬號,請參見創建數據庫賬號。
- 由于安全原因,DBMS_JOB插件暫時不支持用戶手動創建,如有需要,請前往配額中心,在配額名稱PolarDB PG dbms_job使用的操作列,單擊申請,申請創建。
- 如果之前安裝過DBMS_JOB相關插件,需要先刪除相關插件,然后參考本文重新安裝。刪除插件語法如下:警告 刪除插件會同時刪除相關定時任務,請務必提前備份。
drop extension dbms_job;
- 目前僅支持在
postgres
庫中創建DBMS_JOB插件,如果您需要在其他庫中使用定時任務,可以在postgres
庫中配置跨庫任務。具體操作,請參見跨庫執行定時任務。
準備測試數據
說明 測試數據僅適用本文中的操作示例。
創建一張名為
jobrun
的表用于測試,示例如下:CREATE TABLE jobrun (
id serial NOT NULL PRIMARY KEY,
runtime VARCHAR2(40)
);
創建一個名為
job_proc
的存儲過程,示例如下:CREATE PROCEDURE job_proc
IS
BEGIN
INSERT INTO jobrun(runtime) VALUES ('job_proc run at ' || TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));
END;
刪除插件
警告 刪除插件時會刪除所有已有的用戶任務。
刪除插件語法如下:
DROP EXTENSION dbms_job CASCADE;
創建定時任務
語法
調用
SUBMIT(job OUT BINARY_INTEGER, what VARCHAR2
[, next_date DATE [, interval VARCHAR2 ]])
參數 | 說明 |
---|---|
job | 請傳入jobid ,用于返回本次提交任務的ID。該ID自動生成且對每個任務都唯一。 |
what | 調用存儲過程名稱,不可為空。本次示例中使用了job_proc 存儲過程。 |
next_date | 定時任務的開始時間,如果不傳入則默認為當前時間。 |
interval | 定時任務的執行間隔。具體內容,請參見INTERVAL參考。 |
定時任務執行間隔 | 示例 |
---|---|
每分鐘執行 |
|
每天定時執行 | 每天凌晨1點執行:
|
每周定時執行 | 每周一凌晨1點執行:
|
每月定時執行 | 每月1日凌晨1點執行:
|
每季度定時執行 | 每季度的第一天凌晨1點執行:
|
每年定時執行 | 每年1月1日凌晨1點執行:
|
固定時間點執行 | 每天早上的8點10分運行:
|
固定時間間隔執行 | 每個小時的第15分鐘運行,例如8點15分、9點15分、10點15分等。
|
job_proc
存儲過程創建一個定時任務,示例如下:DECLARE
jobid INTEGER;
BEGIN
DBMS_JOB.SUBMIT(jobid,'job_proc;', SYSDATE, 'SYSDATE + 1/(24 * 60)');
END;
說明 如果定時任務中的時間使用了單引號,這種嵌套會導致語法錯誤,錯誤示例如下:
DBMS_JOB.SUBMIT(jobid,'job_proc;', SYSDATE, 'TRUNC(sysdate,'mi') + 1/(24*60)');
您需要將對應的參數改為$$
的形式來避免這種錯誤,正確示例如下:
DBMS_JOB.SUBMIT(jobid,'job_proc;', SYSDATE, $$TRUNC(sysdate,'mi') + 1/(24*60)$$);
修改定時任務的內容、執行時間和執行間隔
語法
修改任務ID為1的定時任務,調用的存儲過程不變,定時任務開始時間修改為2020年12月29日,任務執行間隔設置為每個小時的15分執行一次。示例如下:
CHANGE(job BINARY_INTEGER what VARCHAR2, next_date DATE,interval VARCHAR2)
參數 | 說明 |
---|---|
job | 任務ID,如何查看請參見查看定時任務。 |
what | 調用存儲過程名稱。 說明 如果保持當前值不變,可將此參數設置為 NULL 。 |
next_date | 定時任務的開始時間。 說明 如果保持當前值不變,可將此參數設置為 NULL 。 |
interval | 定時任務的執行間隔。具體內容,請參見INTERVAL參考。 說明 如果保持當前值不變,可將此參數設置為 NULL 。 |
BEGIN
DBMS_JOB.CHANGE(1,NULL,TO_DATE('29-DEC-20','DD-MON-YY'),$$Trunc(sysdate,'hh') + (60+15)/(24*60)$$);
END;
修改定時任務的執行間隔
語法
修改任務ID為1的定時任務,任務執行間隔修改為每天凌晨1點執行一次。示例如下:
INTERVAL(job BINARY_INTEGER, interval VARCHAR2)
參數 | 說明 |
---|---|
job | 任務ID,如何查看請參見查看定時任務。 |
interval | 定時任務的執行間隔。具體內容,請參見INTERVAL參考。 |
BEGIN
DBMS_JOB.INTERVAL(1,'TRUNC(sysdate) + 1 + 1/(24)');
END;
修改定時任務的執行時間
語法
修改任務ID為1的定時任務,定時任務開始時間設置為2020年12月30日。示例如下:
NEXT_DATE(job BINARY_INTEGER, next_date DATE)
參數 | 說明 |
---|---|
job | 任務ID,如何查看請參見查看定時任務。 |
next_date | 定時任務的開始時間。 |
BEGIN
DBMS_JOB.NEXT_DATE(1, TO_DATE('30-DEC-20','DD-MON-YY'));
END;
修改定時任務的內容
語法
修改任務ID為1的定時任務,將調用的存儲過程改為
WHAT(job BINARY_INTEGER, what VARCHAR2)
參數 | 說明 |
---|---|
job | 任務ID,如何查看請參見查看定時任務。 |
what | 調用的存儲過程名稱。 |
job_proc2
。示例如下:BEGIN
DBMS_JOB.WHAT(1,'job_proc2');
END;
停止和啟動定時任務
語法
將任務ID為1的定時任務設置為已損壞狀態。示例如下:
BROKEN(job BINARY_INTEGER, broken BOOLEAN [, next_date DATE ])
參數 | 說明 |
---|---|
job | 任務ID,如何查看請參見查看定時任務。 |
broken | 定時任務的狀態,取值如下:
|
next_date | 定時任務的開始時間,如果不傳入則默認為當前時間。 |
BEGIN
DBMS_JOB.BROKEN(1,true);
END;
將任務ID為1的定時任務設置為正常運行狀態。示例如下:BEGIN
DBMS_JOB.BROKEN(1,false);
END;
強制啟動定時任務
語法
強制啟動任務ID為1的定時任務。示例如下:
RUN(job BINARY_INTEGER)
參數 | 說明 |
---|---|
job | 任務ID,如何查看請參見查看定時任務。 |
BEGIN
DBMS_JOB.RUN(1);
END;
刪除定時任務
語法
刪除任務ID為1的定時任務。示例如下:
REMOVE(job BINARY_INTEGER)
參數 | 說明 |
---|---|
job | 任務ID,如何查看請參見查看定時任務。 |
BEGIN
DBMS_JOB.REMOVE(1);
END;
查看定時任務
您可以通過如下語句查看當前用戶創建的定時任務列表:
select * from sys.user_jobs;
查看任務執行記錄
您可以通過如下語句查看定時任務的執行記錄:
select * from dbmsjob.pga_joblog;
跨庫執行定時任務
由于DBMS_JOB只能配置在postgres
庫,其他庫如果需要設置定時任務則需要進行跨庫任務。
以下示例中,DBMS_JOB的配置庫為postgres
,運行庫為test
,需要在test
庫中的某張表每分鐘插入一條數據。如何創建數據庫,請參見創建數據庫。
- 在
test
庫中創建一個名為jobrun
的表和一個名為job_proc
的存儲過程。- 創建名為
jobrun
的表,命令如下:CREATE TABLE public.jobrun ( id serial NOT NULL PRIMARY KEY, runtime VARCHAR2(40) );
- 創建名為
job_proc
的存儲過程,命令如下:CREATE PROCEDURE public.job_proc IS BEGIN INSERT INTO jobrun(runtime) VALUES ('job_proc run at ' || TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss')); END;
- 創建名為
- 切換到
postgres
庫,創建定時任務。您需要在
DBMS_JOB.SUBMIT()
函數中添加目標庫,本例中目標庫名為test
。其他參數請參見創建定時任務。示例如下:DECLARE jobid INTEGER; BEGIN DBMS_JOB.SUBMIT(jobid,'job_proc;', SYSDATE, 'SYSDATE + 1/(24 * 60)','test'); END;
- 在
postgres
中查看定時任務的狀態和執行記錄。- 查看定時任務:
返回結果如下:select * from sys.user_jobs;
job | jobloguser | job_user | database | job_created | job_changed | last_date | last_sec | next_date | next_sec | total_time | broken | interval | failures | what | instance -----+------------+----------+----------+----------------------------------+----------------------------------+----------------------------------+----------+---------------------------+----------+-----------------+--------+------------------------------------------+----------+-----------------------------------------------------------------------------------------------------------------+---------- 1 | DBUSER | dbuser | postgres | 29-OCT-20 02:38:49.478494 +00:00 | 29-OCT-20 02:38:49.478494 +00:00 | 29-OCT-20 02:51:12.025001 +00:00 | 02:51:12 | 29-OCT-20 02:53:12 +00:00 | 02:53:12 | 00:00:00.243224 | N | BEGIN return SYSDATE + 1/(24 * 30); END; | 0 | BEGIN EXECUTE IMMEDIATE 'SELECT dbmsjob.dbms_job_internal_job_link(''BEGIN job_proc; END;'', ''test'');' ; END | 0
- 查看執行記錄:
返回結果如下:select * from dbmsjob.pga_joblog;
jlgid | jlgjobid | jlgstatus | jlgstart | jlgduration -------+----------+-----------+----------------------------------+----------------- 1 | 1 | s | 29-OCT-20 02:38:49.762995 +00:00 | 00:00:00.017495 2 | 1 | s | 29-OCT-20 02:39:50.061113 +00:00 | 00:00:00.016463 3 | 1 | s | 29-OCT-20 02:40:50.062331 +00:00 | 00:00:00.016244
- 查看定時任務:
- 切換到
test
庫,查看表中數據。查詢命令如下:
查詢結果如下:select * from jobrun;
id | runtime ----+------------------------------------- 1 | job_proc run at 2020-10-29 02:38:50 2 | job_proc run at 2020-10-29 02:39:50 3 | job_proc run at 2020-10-29 02:40:50
說明 如果您需要修改跨庫任務的信息,需要在修改函數時附加對應的數據庫名稱。例如將上述示例中每分鐘運行一次的計劃改為每兩分鐘運行一次,示例如下:
BEGIN
DBMS_JOB.CHANGE(1,NULL,SYSDATE,'SYSDATE + 1/(24 * 30)','test');
END;