LightDB定时任务新特性
LightDB数据库除了对现有PostgreSQL开源定时任务模块pg_cron进行了支持,同时又拓展了一些新特性,包括支持秒级定时、支持不同任务模式、支持时区配置、支持超时时间配置等,具体功能如下:
pg_cron 是一个简单的基于 cron 的 LightDB 作业调度程序,它作为扩展在数据库中运行。它允许您直接从数据库调度 LightDB 命令:
-- 每周六凌晨 3:30 执行一次vacuum(东八时区) SELECT cron.schedule('30 3 * * 6', 'VACUUM'); schedule ---------- 42 -- 每天上午 10:00 执行一次vacuum(东八时区) SELECT cron.schedule('nightly-vacuum', '0 10 * * *', 'VACUUM'); schedule ---------- 43 -- 每天凌晨 3:00 执行一次vacuum(东八时区) SELECT cron.schedule('nightly-vacuum', '0 3 * * *', 'VACUUM'); schedule ---------- 43 -- 取消定时任务 SELECT cron.unschedule('nightly-vacuum' ); unschedule ------------ t (1 row) SELECT cron.unschedule(42); unschedule ------------ t
pg_cron 可以支持秒级精度:
-- 每天上午 10:00:30 执行一次vacuum(东八时区) SELECT cron.schedule('30 0 10 * * *', 'VACUUM'); schedule ---------- 45 -- 每秒执行一次vacuum SELECT cron.schedule('dayly-vacuum', '* * * * * *', 'VACUUM'); schedule ---------- 46 -- 每 10 秒执行一次vacuum SELECT cron.schedule('dayly-vacuum', '*/10 * * * * *', 'VACUUM'); schedule ---------- 46
pg_cron 可以支持四种任务模式,包括一次性任务、尽快执行、下一个间隔任务和固定间隔任务。可以在第四个参数中传入任务模式,有四个参数可供选择(如果要配置任务模式,必须传入第一个参数任务名称):
-
'single'
代表一次性任务,这意味着当任务执行完一次后,后面将不再执行。-- 立即执行一次vacuum SELECT cron.schedule('dayly-vacuum', '* * * * * *', 'VACUUM', 'single'); schedule ---------- 46 -- 每 30 秒执行一次vacuum SELECT cron.schedule('dayly-vacuum', '*/30 * * * * *', 'VACUUM', 'next'); schedule ---------- 46 -- 在下一个上午 10:00:30 时刻仅执行一次vacuum(东八时区) SELECT cron.schedule('dayly-vacuum', '30 0 10 * * *', 'VACUUM', 'single'); schedule ---------- 46 -- 每天上午 10:00:30执行一次vacuum(东八时区) SELECT cron.schedule('dayly-vacuum', '30 0 10 * * *', 'VACUUM', 'next'); schedule ---------- 46
-
'asap'
表示一个 asap 计划任务,对于同一个任务,它一次最多运行一个作业的一个实例。如果第二次运行应该在第一次运行完成之前开始,那么第二次运行会排队并在第一次运行完成后立即开始。-- 每 30 秒一次vacuum SELECT cron.schedule('dayly-vacuum', '*/30 * * * * *', 'VACUUM', 'asap'); schedule ---------- 46 -- 每天上午 10:00:30执行一次vacuum(东八时区) SELECT cron.schedule('dayly-vacuum', '30 0 10 * * *', 'VACUUM', 'asap'); schedule ---------- 46
-
'next'
表示下一个间隔调度任务,对于同一个任务,它一次最多运行一个作业实例。如果第二次运行应该在第一次运行完成之前开始,那么第二次运行将排队并在下一个计时周期的时间点开始。-- 每 30 秒一次vacuum SELECT cron.schedule('dayly-vacuum', '*/30 * * * * *', 'VACUUM', 'next'); schedule ---------- 46 -- 每天上午 10:00:30执行一次vacuum(东八时区) SELECT cron.schedule('dayly-vacuum', '30 0 10 * * *', 'VACUUM', 'next'); schedule ---------- 46
-
'fixed'
表示一个固定间隔的计划任务,对于同一个任务,它默认一次最多运行一个作业的四个实例。如果第二次运行应该在第一次完成之前开始,那么第二次运行不会等待,而是在计时周期的时间点开始,然后与第一次未完成的任务并行执行。'cron.max_connections_per_task'
您可以通过在 postgresql.conf 中配置 GUC 参数并重新启动数据库来 修改同一任务到期时的最大并发执行数。最大上限为 16。-- 每 30 秒执行一次vacuum SELECT cron.schedule('dayly-vacuum', '*/30 * * * * *', 'VACUUM', 'fixed'); schedule ---------- 46 -- 每天上午 10:00:30执行一次vacuum(东八时区) SELECT cron.schedule('dayly-vacuum', '30 0 10 * * *', 'VACUUM', 'fixed'); schedule ---------- 46
pg_cron 可以支持时区配置。您可以在第五个参数中传递时区值。如果要配置时区,必须传入第一个参数任务名称和第四个参数任务模式。如果没有配置时区,默认为东八时区:
-- 每天上午 10:00执行一次vacuum(格林威治标准时间) SELECT cron.schedule('dayly-vacuum', '0 10 * * *', 'VACUUM', 'next', '0'); schedule ---------- 46 -- 每天上午10:00执行一次vacuum(西十时区) SELECT cron.schedule('dayly-vacuum', '0 10 * * *', 'VACUUM', 'next', '-10'); schedule ---------- 46 -- 下一个上午 10:00执行一次vacuum(东六时区) SELECT cron.schedule('dayly-vacuum', '0 10 * * *', 'VACUUM', 'single', '6'); schedule ---------- 46
pg_cron 可以并行运行多个作业,默认情况下它使用下一个间隔模式,即一次最多运行一个作业的一个实例。如果第二次运行应该在第一次运行完成之前开始,那么第二次运行将排队并在下一个计时周期的时间点开始。
pg_cron 默认支持定时任务超时180秒,对所有类型的任务都有效。如果任务执行超时,它会记录错误cron.job_run_details
并返回,等待下一次执行。可以通过 cron.task_running_timeout
在postgresql.conf中设置guc参数修改定时任务超时时间,重启数据库生效。最大值为3600秒;如果设置为 0,则表示没有超时限制。
该计划使用标准的 cron 语法,其中 * 表示“每个时间段运行”,特定数字表示“但仅在此时”:
┌────────────── 分钟 (0 - 59) │ ┌────────────── 小时 (0 - 23) │ │ ┌─────────────── 一个月中的某天 (1 - 31) │ │ │ ┌──────────────── 月(1-12) │ │ │ │ ┌─────────────── 星期几(0 - 6)(0到6是星期天到 │ │ │ │ │ 星期六,或使用名称;7也是星期天) │ │ │ │ │ │ │ │ │ │ * * * * *
创建 cron 计划的一种简单方法是: crontab.guru。
它在标准 cron 语法的基础上进行了增强,以支持秒级任务:
┌──────────────秒(0 - 59) │ ┌───────────── 分钟 (0 - 59) │ │ ┌────────────── 小时 (0 - 23) │ │ │ ┌─────────────── 一个月中的某天 (1 - 31) │ │ │ │ ┌────────────── 月(1-12) │ │ │ │ │ ┌───────────────── 星期几 (0 - 6) (0 到 6 是星期天到 │ │ │ │ │ │ 星期六,或使用名称;7也是星期天) │ │ │ │ │ │ │ │ │ │ │ │ * * * * * *
为了安全起见,作业在调用 cron.schedule 函数的数据库中执行,并具有与当前用户相同的权限。此外,用户只能在cron.job
表格和cron.lt_job
视图中看到自己的作业。