lt_cron 是 LightDB 的基于 cron 的简单作业调度程序,作为扩展运行在数据库内部。它允许您直接从数据库中调度 LightDB 命令:
-- 每周六的凌晨3点30分(美国东部时区)进行 VACUUM 操作
SELECT cron.schedule('30 3 * * 6', 'VACUUM');
schedule
----------
42
-- 每天上午10点(美国东部时区)进行 VACUUM 操作
SELECT cron.schedule('nightly-vacuum', '0 10 * * *', 'VACUUM');
schedule
----------
43
-- 将每天的 VACUUM 操作时间改为美国东部时区的凌晨3点
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
lt_cron 可以支持秒级精度:
-- 每天上午10点零30秒(美国东部时区)进行 VACUUM 操作
SELECT cron.schedule('30 0 10 * * *', 'VACUUM');
schedule
----------
45
-- 每秒钟进行 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '* * * * * *', 'VACUUM');
schedule
----------
46
-- 将 VACUUM 操作时间改为每 10 秒钟一次
SELECT cron.schedule('dayly-vacuum', '*/10 * * * * *', 'VACUUM');
schedule
----------
46
lt_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点零30秒(美国东部时区)执行一次 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '30 0 10 * * *', 'VACUUM', 'single');
schedule
----------
46
-- 每天上午10点零30秒(美国东部时区)执行 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '30 0 10 * * *', 'VACUUM', 'next');
schedule
----------
46
'asap' 表示尽快执行的任务,在同一任务中,每次最多运行一个作业实例。
如果第二次运行在第一次完成之前应该开始,则第二次运行将排队并在第一次运行完成后立即启动。
-- 每 30 秒钟执行一次 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '*/30 * * * * *', 'VACUUM', 'asap');
schedule
----------
46
-- 每天上午10点零30秒(美国东部时区)执行 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '30 0 10 * * *', 'VACUUM', 'asap');
schedule
----------
46
'next' 表示下一个时间间隔调度任务,在同一任务中,每次最多运行一个作业实例。
如果第二次运行在第一次完成之前应该开始,则第二次运行将排队并在下一个计时周期的时间点启动。
与以前版本兼容,模式参数输入 'timing' 与 'next' 相同。
-- 每 30 秒钟执行一次 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '*/30 * * * * *', 'VACUUM', 'next');
schedule
----------
46
-- 每天上午10点零30秒(美国东部时区)执行 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '30 0 10 * * *', 'VACUUM', 'next');
schedule
----------
46
'fixed' 表示固定时间间隔调度任务,在同一任务中,默认情况下最多运行四个作业实例。
如果第二次运行在第一次完成之前应该开始,则第二次运行不会等待,而会在定时周期的时间点启动,
然后与第一个未完成的任务并行执行。
当同一任务过期时,您可以通过在 lightdb.conf 中配置 'cron.max_connections_per_task' GUC
参数来修改最大并发执行数,
并重新启动数据库以生效。最大上限为 16。
-- 每 30 秒钟执行一次 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '*/30 * * * * *', 'VACUUM', 'fixed');
schedule
----------
46
-- 每天上午10点零30秒(美国东部时区)执行 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '30 0 10 * * *', 'VACUUM', 'fixed');
schedule
----------
46
lt_cron 可以支持时区配置。您可以在第五个参数中传递时区值。 如果您想配置时区,必须传递第一个参数任务名称和第四个参数任务模式。 如果未配置时区,则默认为美国东部时区:
-- 每天上午10点(格林尼治标准时间)执行 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '0 10 * * *', 'VACUUM', 'next', '0');
schedule
----------
46
-- 每天上午10点(西十时区)执行 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '0 10 * * *', 'VACUUM', 'next', '-10');
schedule
----------
46
-- 仅在下一个上午10点(美国东部六时区)执行一次 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '0 10 * * *', 'VACUUM', 'single', '6');
schedule
----------
46
lt_cron 可以支持执行 Linux 操作系统命令。您可以在第六个参数中传递命令类型值。传递参数 'sql' 表示第三个参数为 SQL 命令, 传递参数 'linux' 表示第三个参数为 Linux 命令。如果要配置命令类型,必须传递第一个参数任务名称、第四个参数任务模式和第五个参数时区。 如果未配置命令类型,则默认为 SQL 命令。请注意,执行 Linux 命令必须是超级用户。
-- 每天上午10点(美国东部时区)执行 VACUUM 操作
SELECT cron.schedule('dayly-vacuum', '0 10 * * *', 'VACUUM', 'next', '8', 'sql');
schedule
----------
46
-- 每天晚上23点59分删除日志文件(美国东部时区)
SELECT cron.schedule('dayly-touch', '59 23 * * *', 'rm -rf $LTDATA/log/*', 'next', '8', 'linux');
schedule
----------
46
lt_cron 可以并行运行多个作业,默认使用下一个时间间隔模式,即每次最多运行一个作业实例。 如果第二次运行在第一次完成之前应该开始,则第二次运行将排队并在下一个计时周期的时间点启动。
lt_cron 支持 SQL 命令的计划任务默认超时时间为 3 分钟,适用于所有类型的任务。
如果任务执行超时,它将在 cron.job_run_details 中记录错误并返回,等待下一次执行。
您可以通过在 lightdb.conf 中设置 cron.task_running_timeout GUC 参数来修改定时任务的超时时间,并重新启动数据库以生效。
最大值为 60 分钟;如果设置为 0,则表示没有超时限制。
请注意,Linux 命令定时任务没有超时机制。
该计划使用标准的 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 视图中看到自己的作业。
-- View active jobs
select * from cron.job;
可以在cron.job_run_details中查看正在运行和最近完成的定时任务运行的状态。
select * from cron.job_run_details order by start_time desc limit 5;
┌───────┬───────┬─────────┬──────────┬──────────┬───────────────────┬───────────┬──────────────────┬───────────────────────────────┬───────────────────────────────┐
│ jobid │ runid │ job_pid │ database │ username │ command │ status │ return_message │ start_time │ end_time │
├───────┼───────┼─────────┼──────────┼──────────┼───────────────────┼───────────┼──────────────────┼───────────────────────────────┼───────────────────────────────┤
│ 10 │ 4328 │ 2610 │ postgres │ marco │ select process() │ succeeded │ SELECT 1 │ 2023-02-07 09:30:00.098164+01 │ 2023-02-07 09:30:00.130729+01 │
│ 10 │ 4327 │ 2609 │ postgres │ marco │ select process() │ succeeded │ SELECT 1 │ 2023-02-07 09:29:00.015168+01 │ 2023-02-07 09:29:00.832308+01 │
│ 10 │ 4321 │ 2603 │ postgres │ marco │ select process() │ succeeded │ SELECT 1 │ 2023-02-07 09:28:00.011965+01 │ 2023-02-07 09:28:01.420901+01 │
│ 10 │ 4320 │ 2602 │ postgres │ marco │ select process() │ failed │ server restarted │ 2023-02-07 09:27:00.011833+01 │ 2023-02-07 09:27:00.72121+01 │
│ 9 │ 4320 │ 2602 │ postgres │ marco │ select do_stuff() │ failed │ job canceled │ 2023-02-07 09:26:00.011833+01 │ 2023-02-07 09:26:00.22121+01 │
└───────┴───────┴─────────┴──────────┴──────────┴───────────────────┴───────────┴──────────────────┴───────────────────────────────┴───────────────────────────────┘
(10 rows)
cron.job_run_details中最多保留距当前时间最近的10万条定时任务记录,早期多余的记录会被定期自动删除。
如果不想使用cron.job_run_details记录任务状态,则可以通过在lightdb.conf配置文件中添加cron.log_run=off来关闭。