金仓KESV8R6任务调度
- 基本概念
• 程序(program)
程序对象描述调度器要运行的内容。
• 调度计划(schedule)
调度计划对象指定作业何时运行以及运行多少次。调度计划可以被多个作业共享。
• 作业(job)
作业就是用户定义的任务。描述用户定义任务的元数据集合。它定义了必须执行什么(动作)、何时(一次性或重复执行的调度或触发事件)。
三者之间的关系:作业通过调度计划控制程序按什么频率执行
- 使用自动作业
KingbaseES 通过kdb_schedule 插件提供了DBMS_JOB 和DBMS_SCHEDULER 包,其中定义了自动作业功能的相关函数,在使用kdb_shcedule 之前,我们需要将他添加到kingbase.conf 文件的shared_preload_libraries中。配置命令如下:
shared_preload_libraries = 'kdb_schedule' # (change requires restart)
并重启数据库, 并在数据库中通过下列create extension 命令创建该插件:
create extension kdb_schedule;
以下三个配置选项可以在配置文件中指定:
• job_queue_processes:允许用户启动的最大并发数,当其值设置为0 时,表示不启动自动作业功能, 默认为0,不开启自动作业。
• sys_job.log_level: 用于设置JOB 后台进程的日志级别, 更改后需要重新加载配置文件, 可选项:
LOG_ERROR,LOG_WARNING,LOG_DEBUG,默认为LOG_ERROR。
• sys_job.poll_time:用于设置轮询系统表间隔时间, 单位秒,默认值为10 秒。
- 创建自动调度作业
创建测试用表:
create table d_test(tid varchar2(64), insdate date);
创建测试存储过程:
\set SQLTERM /
create or replace procedure p_test() as
begin
insert into d_test values(to_char(sysdate, 'yyyymmddhh24miss'), sysdate);
commit;
end;
/
创建program,将program和要执行的操作绑定。这里的program就是要执行存储过程p_test。
begin
dbms_scheduler.create_program(program_name => 'prog_01',
program_type => 'PLSQL_BLOCK',
program_action => 'call public.p_test()',
acconnstr => 'user=system dbname=test port=6666 password=system',
acdbname => 'test',
number_of_arguments => 0,
enabled => true,
comments => 'test program');
end;
/
注意。'PLSQL_BLOCK' 必须大写,acdbname 必须指定。
select * from kdb_schedule.kdb_action;可查看program
创建schedule,将schedule和program绑定,指定program按找schedule配置的频率执行
begin
dbms_scheduler.create_schedule(schedule_name => 'schedule_01',
start_date => now(),
repeat_interval => 'freq=minutely;interval=1',
end_date => null,
comments => 'test schedule');
end;
/
select * from kdb_schedule.kdb_schedule;可查看schedule
freq=minutely;interval=1表示从创建定时任务开始,每分钟执行一次,FREQ可以是YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY,INTERVAL可指定的值的范围1-99,但目前金仓库FREQ =SECONDLY不生效,实际还是每分钟执行一次。
要实现按秒执行,可以改为'FREQ=MINUTELY;BYSECOND=0,10,20,30,40,50',这样便是每十秒执行一次,目前最快十秒一次,不能设置更短的时间。
其他情况也可以加上BY语句,可以精确控制定时任务执行的时间,例如'FREQ=MONTHLY;BYMONTHDAY=23;BYHOUR=0;BYMINUTE=10;BYSECOND=0'表示每月23日0时10分0秒执行定时任务
创建job,指定和job相关的program和schedule,运行和管理以job为单位
begin
dbms_scheduler.create_job(job_name => 'job_01',
program_name => 'prog_01',
schedule_name => 'schedule_01',
job_class => 'routine maintenance',
enabled => true,
auto_drop => true,
comments => 'test job',
credentail_name => null,
destination_name => null);
end;
select * from kdb_schedule.kdb_schedule_job;和select * from kdb_schedule.kdb_job_action;可查看job与schedule以及job与action之间的关系
select * from kdb_job可查看具体的job信息
默认job的状态是enable的,也就是已经开始执行了
- 自动调度作业管理
call dbms_scheduler.disable('job_01');
或者使用oracle语法:
\set SQLTERM /
定时任务disable:
begin
dbms_scheduler.disable(name => 'job_01');
end;
/
定时任务enable:
begin
dbms_scheduler.enable(name => 'job_01');
end;
/
手动执行定时任务:
begin
dbms_scheduler.run_job(job_name => 'job_01');
end;
/
删除定时任务:
begin
dbms_scheduler.drop_job(job_name => 'job_01');
end;
/
begin
dbms_scheduler.drop_schedule(schedule_name => 'schedule_01');
end;
/
begin
dbms_scheduler.drop_program(program_name => 'prog_01');
end;
/
- 自动调度作业排错
kdb_schedule.kdb_jobsteplog记录了job 调用的具体信息,如果有错误的,jsloutput会显示具体的错误信息。
sys_log/sys_jobbgworker.log及数据库日志也记录了相关的日志信息。
注意下图的bug,在视图kdb_job中的jobagentid列不为0,表示当前作业未正常完成,需要删除老的program、schedule和job并重建program、schedule和job来解决