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
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)$$);
修改定时任务的内容、执行时间和执行间隔
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;
修改定时任务的执行间隔
INTERVAL(job BINARY_INTEGER, interval VARCHAR2)
参数 | 说明 |
---|---|
job
|
任务ID,如何查看请参见 查看定时任务 。 |
interval
|
定时任务的执行间隔。具体内容,请参见 INTERVAL参考 。 |
BEGIN
DBMS_JOB.INTERVAL(1,'TRUNC(sysdate) + 1 + 1/(24)');
END;
修改定时任务的执行时间
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;
修改定时任务的内容
WHAT(job BINARY_INTEGER, what VARCHAR2)
参数 | 说明 |
---|---|
job
|
任务ID,如何查看请参见 查看定时任务 。 |
what
|
调用的存储过程名称。 |
job_proc2
。示例如下:
BEGIN
DBMS_JOB.WHAT(1,'job_proc2');
END;
停止和启动定时任务
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;
强制启动定时任务
RUN(job BINARY_INTEGER)
参数 | 说明 |
---|---|
job
|
任务ID,如何查看请参见 查看定时任务 。 |
BEGIN
DBMS_JOB.RUN(1);
END;
删除定时任务
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 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');