暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

一文带你了解PolarDB中的定时任务

PolarDB 2025-02-27
33

一文带你了解PolarDB中的定时任务

前言

定时任务是一种在预定的时间点或者时间间隔内自动执行的任务。定时任务通常由一个调度器负责管理和执行。调度器根据预定的时间规则来触发任务的执行。常见的时间规则包括每天的特定时间点、每周的特定日期和时间、每月的特定日期和时间等。调度器还可以根据任务的需要设置任务的执行次数和重复间隔。

定时任务的应用场景非常广泛。在服务器端,定时任务常用于定期执行后台任务、生成报告、清理垃圾数据等。在客户端,定时任务可以用于更新数据、提醒用户、执行自动化操作等。无论是在服务器端还是客户端,定时任务都可以提高工作效率,减轻人工操作的负担。

功能特点

pg_cron提供了在PolarDB数据库中执行定时任务的功能。pg_cron允许用户以SQL语句的形式调度任务,并在指定的时间点或者时间间隔内自动执行这些任务。

pg_cron的主要特点包括:

  1. 简单易用:用户可以通过执行SQL语句来创建、调度和管理任务,无需额外的编程或配置。

  2. 灵活的调度选项:pg_cron支持多种调度选项,包括按秒、分钟、小时、天、星期、月份等定时调度。

  3. 数据库级别的任务管理:pg_cron任务保存在数据库系统中,因此可以跨多个数据库共享和管理任务。

  4. 并发任务执行:pg_cron可以同时执行多个任务,提高任务执行效率。

  5. 可靠性和容错性:pg_cron提供了错误处理和容错机制,确保任务的正确执行并提供相应的日志记录。

使用pg_cron,用户可以轻松地在PolarDB数据库中创建和管理定时任务,例如备份数据、生成报告、定期清理等。它为数据库管理员和开发人员提供了一种简单而强大的方式来自动化重复性的任务,并提高工作效率。

设计原理

任务调度与唤醒

image

PG_CRON 通过维护JOB LIST和TASK LIST两个列表来进行后台调度和维护任务的执行。

首先,JOB LIST用于维护任务池中的任务列表,并通过唤醒机制来确保任务池的变动与JOB LIST保持一致。当数据库启动时,JOB LIST会从cron.job表中获取任务,并将其加入任务列表中。同时,如果用户对cron.job表进行了修改,触发器job_cache_invalidate()会刷新JOB LIST并重新遍历任务。

其次,用户可以通过调用函数schedule来申请任务,并使用unschedule来撤销任务。申请成功的任务会被储存在cron.job表中。而TASK LIST则从JOB LIST中获取有效的任务,并进行实际的调度执行。TASK LIST与JOB LIST保持实时一致,确保任务能够得到正确调度和执行。

任务的运行与等待

image

1 调度任务时,任务进入等待状态WAITING。

2 在WAITING状态下,检查当前任务的执行条件。如果条件不满足(例如任务处于非激活状态或计划时间还未到),则跳过该任务的调度。如果条件满足,则进入START状态。

3 在START状态下,构建任务的连接信息,并进行连接测试。如果连接成功,则进入CONNECTING状态;如果连接失败,则进入ERROR状态。

4 在CONNECTING状态下,检查任务是否激活,连接是否超时、连接是否失败以及socket是否准备就绪。如果所有条件都满足,则进入RUNNING状态;否则进入ERROR状态。

5 在SENDING状态下,检查任务是否激活,连接是否超时、连接是否失败以及socket是否准备就绪。如果条件满足,将准备好的定时任务文本发送至PolarDB服务器;否则进入ERROR状态。

6 在RUNNING状态下,检查任务是否激活,连接是否失败以及socket是否准备就绪、是否忙碌。如果所有条件都满足,接收socket传回的任务结果;否则跳出等待或进入ERROR状态。

7 在DONE状态下,任务完成,重置任务信息,并进入下一个任务循环。

8 在ERROR状态下,任务失败,重置连接信息,并进入任务完成状态。

用户手册

注意事项

  • 出于安全性考虑,您只能够通过系统函数来操作定时任务(系统提供了增加和删除定时任务的功能),普通用户对于cron.job
    (PG_CRON定时任务表)只有查看的权限。请您根据自己的需要选择函数的使用方法。

  • 数据库中的定时任务都储存于默认postgres数据库中,但是您可以在其它多个数据库上执行定时任务查询。

  • 定时任务执行的时间是GMT时间,请注意换算时间。

PG_CRON 子程序总览

子程序
描述
schedule
开始调度一个任务
unschedule
停止并删除一个任务
alter_job
修改一个任务,包括内容、名称、或者任务计划
schedule_in_database
在指定的数据库调度定时任务

SCHEDULE

该函数是调度任务的主函数,通过该函数接口来调度任务

语法

schedule(job_name text,
 schedule text,
 command text)

复制

参数说明

参数描述
job_name
任务名,可以缺省为空
schedule
任务的规划,用一个字符串表示,例如‘0 10 * * *’表示每天上午10点执行
command
任务内容,预期是一个SQL字符串

UNSCHEDULE

该函数用来停止调度并且删除某个任务

语法

unschedule(job_id bigint) 
unschedule(name text)

复制

参数说明

参数描述
job_id
要删除任务的任务ID(ID和名称二选一)
name
要删除任务的任务名(ID和名称二选一)

ALTER_JOB

用来修改任务的内容

语法

alter_job(job_id bigint,
  schedule text default null,
  command text default null,
  database text default null,
  active boolean default null)

复制

参数说明

参数描述
job_id
需要修改的任务ID
schedule
修改后的任务计划
command
修改后的任务内容
database
修改后的任务执行数据库
active
修改后任务是否处于激活状态(正常运行)

SCHEDULE_IN_DATABASE

语法

schedule_in_database(job_name text,
  schedule text,
  command text,
  database text)

复制

参数说明

参数描述
job_name
需要调度的任务名
schedule
调度任务计划
command
调度任务内容
database
调度执行数据库

最佳实践

定时任务开启与关闭

在数据库中执行下列脚本,即可开启或关闭pg_cron。

注意pg_cron默认需要创建在postgres数据库下,而任务可以在不同的数据库进行调度。

-- 开启pg_cron
CREATE EXTENSION pg_cron;

-- 关闭 pg_cron
DROP EXTENSION pg_cron;

复制

定时任务调用

-- 执行一个任务
SELECT cron.schedule('schedule''task')

-- 选定数据库执行任务 
select cron.schedule_in_database('test''* * * * *''select 1''t');

-- 删除一个任务
SELECT cron.unschedule(1)

-- 查看当前任务列表
SELECT * FROM cron.job;

复制

执行计划说明

  • 若干执行计划的示例
-- 周六3:30am (GMT) 删除过期数据 
SELECT cron.schedule('30 3 * * 6', $$DELETEFROMeventsWHERE event_time < now() - interval'1 week'$$);
 schedule
----------
       42

-- 每天的 10:00am (GMT) 执行磁盘清理
SELECT cron.schedule('0 10 * * *''VACUUM');
 schedule
----------
       43

-- 每分钟执行 指定脚本
SELECT cron.schedule('* * * * *''select 1;');
 schedule
----------
       44

-- 每个小时的 23分 执行 指定脚本
SELECT cron.schedule('23 * * * *''select 1;');
 schedule
----------
       45
       
-- 每个月的 4号 执行 指定脚本
SELECT cron.schedule('* * 4 * *''select 1;');
 schedule
----------
       46

复制

其中,PG_CRON计划使用标准的CRON语法,*
表示每个该时间运行,指定数字则表示仅在这个时间运行,如下所示。

 ┌───────────── 分钟 (0 - 59)
 │ ┌────────────── 小时 (0 - 23)
 │ │ ┌─────────────── 日期 (1 - 31)
 │ │ │ ┌──────────────── 月份 (1 - 12)
 │ │ │ │ ┌───────────────── 一周中的某一天 (0 - 6) (0 到 6 表示周末到下周六,
 │ │ │ │ │                   7 仍然是周末)
 * * * * *

复制

定时任务相关视图

-- 查询任务详情
postgres=> SELECT jobid,schedule,command,database,username,active,jobname FROM cron.job;
 jobid | schedule  | command  | database | username | active | jobname 
-------+-----------+----------+----------+----------+--------+---------
     2 | * * * * * | select1 | t        | t        | t      | test
(1row)

-- 查询任务执行日志
postgres=> select * from cron.job_run_details;
 jobid | runid | job_pid | database | username | command  |  status   | return_message |           start_time           |            end_time            
-------+-------+---------+----------+----------+----------+-----------+----------------+--------------------------------+--------------------------------
     2 |    10 |   *** | t        | t        | select1 | succeeded | 1row          | 2023-10-1206:21:00.007887 +00 | 2023-10-1206:21:00.008352 +00
(1row)

复制

文章转载自PolarDB,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论