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来关闭。