为什么要从 pg_cron 迁移到 pg_timetable?
您可能希望从pg_cron迁移的原因有很多:
- 也许您需要在pg_cron不支持的平台上运行调度程序;
- 或者您想同时运行多个并行调度程序;
- 有可能你遇到了pg_cron中多年未修复的错误(#64,#96);
- 或者您受到pg_cron提供的调试工具的限制;
- 可能你认为pg_cron项目在被微软收购后已经过时和弃用;
- 或者您可能需要实现复杂的任务链而不是简单的 SQL 语句。
其实有很多原因。通过查看我在上一篇文章中介绍的PostgreSQL 调度程序比较表和官方自述文件中支持的平台表,可以发现其中的大多数。
先决条件
- 您已经在数据库中安装了pg_cron扩展。
- 您已安排pg_cron作业导出。
- 您已经通过对这个数据库运行pg_timetable至少一次来创建pg_timetable模式。架构将自动创建。您是否已经添加了一些链并不重要。
简单的解决方案
如果你想快速导出从pg_cron调度的作业到pg_timetable,你可以使用这个 SQL 片段:
1
2
3
4
5
6
7
SELECT timetable.add_job(
job_name => COALESCE(jobname, 'job: ' || command),
job_schedule => schedule,
job_command => command,
job_kind => 'SQL',
job_live => active
) FROM cron.job;
但是timetable.add_job(),有一些限制。首先,该函数将创建的任务标记为自治的,指定调度程序应该执行链外事务的任务。这不是错误,但许多自治链可能会导致使用一些额外的连接。
其次,源pg_cron作业的数据库连接参数丢失,使所有作业都是本地的。
正确的 pg_cron 到 pg_timetable 迁移脚本
要尽可能精确地导出每条可用信息,请根据它们在pg_cron中安排的角色使用此 SQL 片段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
SET ROLE 'scheduler'; -- set the role used by pg_cron
WITH cron_chain AS (
SELECT
nextval('timetable.chain_chain_id_seq'::regclass) AS cron_id,
jobname,
schedule,
active,
command,
CASE WHEN
database != current_database()
OR nodename != 'localhost'
OR username != CURRENT_USER
OR nodeport != inet_server_port()
THEN
format('host=%s port=%s dbname=%s user=%s', nodename, nodeport, database, username)
END AS connstr
FROM
cron.job
),
cte_chain AS (
INSERT INTO timetable.chain (chain_id, chain_name, run_at, live)
SELECT
cron_id, COALESCE(jobname, 'cronjob' || cron_id), schedule, active
FROM
cron_chain
),
cte_tasks AS (
INSERT INTO timetable.task (chain_id, task_order, kind, command, database_connection)
SELECT
cron_id, 1, 'SQL', command, connstr
FROM
cron_chain
RETURNING
chain_id, task_id
)
SELECT * FROM cte_tasks;
让我们一起逐行浏览这个脚本:
SET ROLE将在计划任务的所有者 pg_cron 用户下执行代码。这很重要,因为我们将在CURRENT_USER后面的代码中检查。- 在第一个 CTE 子句
cron_chain中,我们准备了pg_cron.job系统表中的所有内容。如果某些连接参数与默认值不同,我们假设此作业是针对远程数据库配置的。在这种情况下,我们编写默认的 PostgreSQL连接字符串。 - 第二个
cte_chain很简单。这里唯一的事情是我们必须确保链名不是空字符串。pg_cron允许省略其作业名称,但pg_timetable对此更为严格。 - 声明的其余部分绝对简单明了。如果需要,只需添加有关要执行的命令和远程数据库的连接字符串的信息。
最后…
我们有一个新的v4.7正式版本可用。完整的变更日志可在v4.7 发布页面上找到。我们要感谢所有贡献者和用户的帮助。
如果您想为pg_timetable做出贡献并帮助使其变得更好:
- ⭐给项目打颗星,
- 随时打开 🤚问题并提出 🎓问题
- 甚至考虑提交 📜拉取请求。
最后,祝你一切顺利!♥️
还有一件事。我要感谢 Cybertec 和 PostgreSQL 社区的每一个人,感谢你们为乌克兰人和我个人提供的支持!#StandWithUkraine 💙💛
我希望我们可以在会议、聚会或培训课程中亲自见面!
原文标题:MIGRATE SCHEDULED JOBS TO PG_TIMETABLE FROM PG_CRON
原文作者:Pavlo Golub
原文地址:https://www.cybertec-postgresql.com/en/migrate-scheduled-jobs-to-pg_timetable-from-pg_cron/




