PostgreSql pg_cron

416 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

一、概述

pg_cron 是一个简单的基于 cron 的 PostgreSQL(9.5或更高版本)作业调度程序,它在数据库中作为扩展运行。它使用与常规 cron 相同的语法,但它允许你直接从数据库调度 PostgreSQL 命令。

二、参数

postgres=# select name,setting from pg_settings where name like '%cron%';
            name             |  setting
-----------------------------+-----------
 cron.database_name          | postgres
 cron.enable_superuser_jobs  | on
 cron.host                   | localhost
 cron.log_min_messages       | warning
 cron.log_run                | on
 cron.log_statement          | on
 cron.max_running_jobs       | 32
 cron.use_background_workers | off
(8 rows)

database_name:定时任务所在数据库。
enable_superuser_jobs:超级用户是否可启动定时任务。
host:执行定时任务的主机名。
log_min_messages:日志级别。
log_run:定时任务执行信息是否记录到 job_run_details 表中。
log_statement:执行任务前,是否将sql打印到日志。
max_running_jobs:可以同时运行的job数量。

扩展安装后会自动创建名为 cron 的模式,并在该模式下生成 cron 相关的字典表。

--字典表 cron.job

                             Table "cron.job"
  Column  |  Type   |               Default               |     Description
----------+---------+-------------------------------------+----------------------
 jobid    | bigint  | nextval('cron.jobid_seq'::regclass) | 定时任务 ID
 schedule | text    |                                     | 定时计划
 command  | text    |                                     | 定时任务作业内容
 nodename | text    | 'localhost'::text                   | 执行定时任务的主机名
 nodeport | integer | inet_server_port()                  | 执行定时任务的端口号
 database | text    | current_database()                  | 执行定时任务的数据库
 username | text    | CURRENT_USER                        | 执行定时任务的用户
 active   | boolean | true                                | 定时任务状态
 jobname  | name    |                                     | 定时任务名字

--字典表 cron.job_run_details
                                   Table "cron.job_run_details"
     Column     |           Type           |               Default               |       Description
----------------+--------------------------+-------------------------------------+--------------------------
 jobid          | bigint                   |                                     | 定时任务 ID
 runid          | bigint                   | nextval('cron.runid_seq'::regclass) | 定时计划运行 ID
 job_pid        | integer                  |                                     | 定时任务 PID
 database       | text                     |                                     | 运行定时任务的数据库名
 username       | text                     |                                     | 运行定时任务的数据库用户
 command        | text                     |                                     | 运行定任务的作业内容
 status         | text                     |                                     | 定时任务的运行结果
 return_message | text                     |                                     | 定时任务返回信息
 start_time     | timestamp with time zone |                                     | 定时任务开始时间
 end_time       | timestamp with time zone |                                     | 定时任务结束时间

三、语法

1)schedule 创建定时任务

SELECT cron.schedule('<定时计划>', '<定时任务>');
SELECT cron.schedule('<定时任务名称>', '<定时计划>', '<定时任务>');
SELECT cron.schedule('<定时任务名称>', '<定时计划>', '<定时任务>', '<执行数据库>', '<执行用户>', '<任务是否启用>');

<定时计划>:定时任务的执行间隔时间,策略。
<定时任务>:定时任务的执行作业。
<执行数据库>:默认值为空,表示在postgres库执行。
<执行用户>:默认值为空,表示使用当前账号执行。
<任务是否启用>:默认值为true,表示启用该定时任务。

<定时计划>语法

使用标准的操作系统 cron 语法:
 ┌───────────── 分钟 (取值为0 - 59)
 │ ┌────────────── 小时 (取值为0 - 23)
 │ │ ┌─────────────── 日期 (取值为1 - 31)
 │ │ │ ┌──────────────── 月份 (取值为1 - 12)
 │ │ │ │ ┌───────────────── 一周中的一天 (取值为0 - 60表示周日)
 │ │ │ │ │
 │ │ │ │ │
 │ │ │ │ │
  *  *  *  *  *


*            表示任意时间都可以运行。
特定数字      表示仅在这个时间运行。
,            表示分隔多个指定时间。
-            表示时间范围。
/            表示范围间隔。

2)alter_job 修改定时任务

SELECT cron.alter_job('<定时任务ID>, '<定时计划>', '<定时任务>', '<执行数据库>', '<执行用户>', '<任务是否启用>');

3)删除定时任务

SELECT cron.unschedule(<定时任务ID>);
SELECT cron.unschedule('<定时任务名称>');

四、示例

1)下载二进制安装包编译安装

gitee.com/mirrors/pg_… 上传数据库服务器,解压并编译安装。

mv pg_cron-v1.4.1.zip /home/postgres/
su - postgres
unzip pg_cron-v1.4.1.zip
cd pg_cron-v1.4.1
make && make install

2)数据库内创建扩展

alter system set shared_preload_libraries=pg_cron;
pg_ctl restart
show shared_preload_libraries;
create extension pg_cron;
\dx

3)启用定时任务

--配置本地免密登录(下列方式均可)
a. pg_hba.conf 中本地连接改为 trust。
b. 配置密码文件~/.pgpass。
c. 设置 PGPASSWORD 环境变量。

--构建测试表
create table t1(id serial primary key,name varchar(10));

--创建定时任务(每2分钟向t1表插入一条数据)
SELECT cron.schedule('每2分钟向t1表插入一条数据','*/2 * * * *', $$insert into public.t1(name) values(repeat(chr(int4(random()*26)+65),4))$$);

--查看定时任务
select * from cron.job;
select * from cron.job_run_details;

4)管理定时任务

--修改定时任务
SELECT cron.alter_job(1,'* */1 * * *',$$insert into public.t1(name) values('ssss')$$,null,'每1小时向t1表插入一条数据','f');

--停止定时任务
SELECT cron.alter_job(1,null,null,null,null,'f');


--删除定时任务
SELECT cron.unschedule(1);
SELECT cron.unschedule('每2分钟向t1表插入一条数据');