pg_cron配置与使用

实验环境:postgresql-15.1    CentOS 7.9 x86-64

pg_cron版本:1.5.1

一 概述 

该插件源码在github上项目地址:https://github.com/citusdata/pg_cron

pg_cron 是一个简单的基于cron的 PostgreSQL(10 或更高版本)作业调度程序,它作为扩展在数据库内部运行。它使用与常规cron相同的语法,但它允许您直接从数据库调度PostgreSQL命令。您还可以使用"[1-59] seconds"来根据时间间隔安排作业。(来自官方README)

使用和OS一样的cron语法来定义执行计划:

 

缺点(已发现的):

  1. 只能指定到PG中的一个数据库中使用
  2. 对不同的job,同一时间点是可以并发执行的,但是对于同一个job,假如该job第一次还未执行完,第二次执行就到时间了,那么第二次执行就会等待第一次执行完成后才能执行(后续有实验)

二 安装

https://github.com/citusdata/pg_cron

2.1 编译安装二进制文件

下载软件包并解压

su - postgres

确认pg_config包含在$PATH中

[postgres@centos7 pkg_pg]$ which pg_config
/pg/pghome/bin/pg_config

解压并make安装

tar -xvf pg_cron-1.5.1.tar.gz
cd pg_cron-1.5.1/
make
make install 

安装完成,需要配置参数后才可以安装扩展.

2.2 配置pg_cron参数

为了在PG启动时同步启动pg_cron后台进程,你需要将pg_cron添加到shared_preload_libraries参数中.

请注意:pg_cron不会在备库中运行任何job,但是当备库提升为主库时,将会自动运行job

alter system set shared_preload_libraries='pg_cron';

该参数需要重启数据库生效,生效后,数据库才能识别其余cron.*参数的状态

pg_ctl restart

查看与pg_cron有关的参数:

postgres=# select * from pg_settings where name like 'cron%';

name                       |setting  |unit|category          |short_desc                                        |extra_desc                                                  |context   |vartype|source |min_val|max_val|enumvals                                                                      |boot_val |reset_val|sourcefile|sourceline|pending_restart|
---------------------------+---------+----+------------------+--------------------------------------------------+------------------------------------------------------------+----------+-------+-------+-------+-------+------------------------------------------------------------------------------+---------+---------+----------+----------+---------------+
cron.database_name         |postgres |    |Customized Options|Database in which pg_cron metadata is kept.       |                                                            |postmaster|string |default|       |       |NULL                                                                          |postgres |postgres |          |          |false          |
cron.enable_superuser_jobs |on       |    |Customized Options|Allow jobs to be scheduled as superuser           |                                                            |postmaster|bool   |default|       |       |NULL                                                                          |on       |on       |          |          |false          |
cron.host                  |localhost|    |Customized Options|Hostname to connect to postgres.                  |This setting has no effect when background workers are used.|postmaster|string |default|       |       |NULL                                                                          |localhost|localhost|          |          |false          |
cron.log_min_messages      |warning  |    |Customized Options|log_min_messages for the launcher bgworker.       |                                                            |sighup    |enum   |default|       |       |{debug5,debug4,debug3,debug2,debug1,info,notice,warning,error,log,fatal,panic}|warning  |warning  |          |          |false          |
cron.log_run               |on       |    |Customized Options|Log all jobs runs into the job_run_details table  |                                                            |postmaster|bool   |default|       |       |NULL                                                                          |on       |on       |          |          |false          |
cron.log_statement         |on       |    |Customized Options|Log all cron statements prior to execution.       |                                                            |postmaster|bool   |default|       |       |NULL                                                                          |on       |on       |          |          |false          |
cron.max_running_jobs      |32       |    |Customized Options|Maximum number of jobs that can run concurrently. |                                                            |postmaster|integer|default|0      |800    |NULL                                                                          |32       |32       |          |          |false          |
cron.timezone              |GMT      |    |Customized Options|Specify timezone used for cron schedule.          |                                                            |postmaster|string |default|       |       |NULL                                                                          |GMT      |GMT      |          |          |false          |
cron.use_background_workers|off      |    |Customized Options|Use background workers instead of client sessions.|                                                            |postmaster|bool   |default|       |       |NULL                                                                          |off      |off      |          |          |false          |

(9 rows)
  1. cron.database_name: 默认情况下,pg_cron后台进程的系统表创建在"postgres"数据库下,但是可以通过cron.database_name参数来指定系统表的存储位置.
  2. cron.timezone: 默认情况下pg_cron使用GMT时区的时间,但是新版本可以通过设置该参数来指定时区,中国东八区使用PRC
  3. cron.enable_superuser_jobs: 默认on,superuser可以修改/调度所有的job
  4. cron.log_min_messages: 记录log的最小粒度,默认记录等级warning
  5. cron.log_run:记录所有的job执行情况,记录到job_run_details,默认打开
  6. cron.log_statement:在执行之前记录所有cron语句,默认打开
  7. cron.max_running_jobs:可以同时运行的最大作业数,默认32
  8. cron.use_background_workers:使用后台进程执行,而不是client会话
  9. cron.host: 当使用client会话模式时,指定显示的主机名,但是当cron.use_background_workers为on时(使用后台进程模式时),该参数无效
alter system set cron.timezone='PRC';
alter system set cron.database_name='db_test';     --注意:只能一个库用,所以这里改成将要使用的库名

其他参数我们默认无需修改,根据需要自己定制参数

需要重启数据库让参数生效

pg_ctl restart

2.3 PG中创建扩展

使用superuser用户增加扩展

CREATE EXTENSION pg_cron;

假如想让普通用户也能创建cron,那么授权usage给普通用户

GRANT USAGE ON SCHEMA cron TO scott;

2.4 让pg_cron能够运行job

pg_cron有两种方式:client模式和后台进程模式

2.4.1 client模式运行pg_cron

重要:默认情况下,pg_cron使用libpq去创建新的会话连接到local database,所以需要:

1. 在pg_hba.conf中允许本地用户登录

2. 在pg_hba.conf中设置本地登录trust,或者设置.pgpass文件,实现免密登录

(有些环境禁用本地免密登录,我在此处配置.pgpass,有条件可以直接配置pg_hba.conf中trust,减少出错点)

还有特殊方案:使用本地unix domain socket 作为主机名,并在pg_hba.conf中配置相关的trust条目,这通常也比较安全(配置cron.host='/tmp')

2.4.2 后台进程模式运行pg_cron(需要调整max_worker_processes)

不太建议使用该方式,因为牵扯到max_worker_processes参数调整,和服务器资源等相关

# 使用后台进程模式,而不是使用客户端模式
cron.use_background_workers = on
# 提高max_worker_processes参数=20,该参数默认为8
max_worker_processes = 20

三 定时任务的创建和管理

环境:创建数据库db_test和用户scott


postgres=# create database db_test;
CREATE DATABASE
postgres=# create user scott password 'tiger';
CREATE ROLE
postgres=# \c db_test 
You are now connected to database "db_test" as user "postgres".
db_test=# grant all  ON schema public TO scott ;
GRANT

普通用户scott创建测试表

db_test=> create table t1 (id serial,curr_time varchar,curr_user varchar);
CREATE TABLE
添加~/.pgpass
localhost:5432:db_test:scott:tiger

3.1 创建cron类型的任务

 

3.1.1 使用cron语法

创建一条执行语句的计划

SELECT cron.schedule('56 15 * * *',$$insert into t1(curr_time,curr_user) values(now()::varchar,user)$$);

为了测试,可以定一个马上要到的时间

3.1.2 使用时间间隔

SELECT cron.schedule('10 seconds',user)$$);

3.1.3 指定任务名

SELECT cron.schedule('Ever 10s insert data','10 seconds',user)$$);

3.1.4 每晚上3点执行VACUUM

SELECT cron.schedule('nightly-vacuum','0 3 * * *','VACUUM');

3.2 查询job清单

select * from cron.job;

db_test=> select * from cron.job;
 jobid |  schedule   |                             command                             | nodename  | nodeport | database | username | active |       jobname        
-------+-------------+-----------------------------------------------------------------+-----------+----------+----------+----------+--------+----------------------
     1 | 41 15 * * * | insert into t1(curr_time) values(now()::varchar);               | localhost |     5432 | db_test  | scott    | t      | 
     2 | 52 15 * * * | insert into t1(curr_time) values(now()::varchar);               | localhost |     5432 | db_test  | scott    | t      | 
     3 | 56 15 * * * | insert into t1(curr_time,user) | localhost |     5432 | db_test  | scott    | t      | 
     4 | 59 15 * * * | insert into t1(curr_time,user) | localhost |     5432 | db_test  | scott    | t      | 
     6 | 10 seconds  | insert into t1(curr_time,user) | localhost |     5432 | db_test  | scott    | t      | Ever 10s insert data
(5 rows)
 

3.3 查询job执行日志

select * from cron.job_run_details order by start_time desc ;

db_test=> select * from cron.job_run_details order by start_time desc ;

jobid|runid|job_pid|database|username|command                                                        |status   |return_message   |start_time                   |end_time                     |
-----+-----+-------+--------+--------+---------------------------------------------------------------+---------+-----------------+-----------------------------+-----------------------------+
    3|    1|       |db_test |scott   |insert into t1(curr_time,user)|failed   |connection failed|                             |                             |
    4|    2|   3880|db_test |scott   |insert into t1(curr_time,user)|succeeded|INSERT 0 1       |2023-03-21 15:59:00.017 +0800|2023-03-21 15:59:00.018 +0800|
(2 rows)

return_message:返回的结果,发现第一个是因为连接失败了,之后可以结合pg日志检查免密认证的情况

3.4 修改job

语法:

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

遇到问题:发现普通用户即使能够创建和删除,但是也不能修改job,应该是个BUG?

db_test=> select cron.alter_job('6','15 seconds',user)$$);
ERROR:  permission denied for function alter_job

3.5 删除job

语法:

SELECT cron.unschedule(<定时任务ID>);
SELECT cron.unschedule('<定时任务名称>');
此处删除job,普通用户就能执行成功了
db_test=> SELECT cron.unschedule(6);
 unschedule 
------------
 t
(1 row)

四 对pg_cron并发执行的探索

思路:

job1和job2,设置相同的任务时间,同时对测试表进行写入,

job3执行pg_sleep(180),目的是测试阻挡job1和job2

1. 创建1张表,

create table t2 (id serial,curr_user varchar,job_name varchar);

2. 创建3个job

job1和job2增加pg_sleep(3)是为了区分开2个不同的任务设定到同一时间后,是否也会相互等待

job3设置180s,是为了验证同一个job未执行完,后面该job又到执行时间的情况,能否直接执行

SELECT cron.schedule('job1','*/2 * * * *',$$insert into t2(curr_time,curr_user,job_name) values(now()::varchar,user,'job1');select pg_sleep(3)$$);

SELECT cron.schedule('job2','job2');select pg_sleep(3)$$);

SELECT cron.schedule('job3','job3');select pg_sleep(180)$$);

3.等待多执行几次,验证结论


db_test=> select * from t2;
 id |           curr_time           | curr_user | job_name 
----+-------------------------------+-----------+----------
 18 | 2023-03-21 16:54:00.018432+08 | scott     | job1
 19 | 2023-03-21 16:54:00.034451+08 | scott     | job2
 20 | 2023-03-21 16:54:00.035248+08 | scott     | job3
 21 | 2023-03-21 16:56:00.007111+08 | scott     | job1
 22 | 2023-03-21 16:56:00.012271+08 | scott     | job2
 23 | 2023-03-21 16:57:00.098638+08 | scott     | job3      --本来是偶数分钟执行,现在排到16:57了,正好距离第一次执行差180s
 24 | 2023-03-21 16:58:00.019738+08 | scott     | job1
 25 | 2023-03-21 16:58:00.031114+08 | scott     | job2
 26 | 2023-03-21 17:00:00.016945+08 | scott     | job1
 27 | 2023-03-21 17:00:00.026808+08 | scott     | job2
 28 | 2023-03-21 17:00:00.188775+08 | scott     | job3
 29 | 2023-03-21 17:02:00.014714+08 | scott     | job1
 30 | 2023-03-21 17:02:00.025062+08 | scott     | job2
 32 | 2023-03-21 17:04:00.016704+08 | scott     | job1
 33 | 2023-03-21 17:04:00.027617+08 | scott     | job2
(15 rows)

验证结论:

对不同的job,同一时间点是可以并发执行的

对于同一个job,就到第二次执行的时间了,那么第二次执行就会等待第一次执行完成后才能执行.

原文地址:https://blog.csdn.net/dsc1245/article/details/129692963

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读601次。Oracle的数据导入导出是一项基本的技能,但是对于懂数据库却不熟悉Oracle的同学可能会有一定的障碍。正好在最近的一个项目中碰到了这样一个任务,于是研究了一下Oracle的数据导入导出,在这里跟大家分享一下。......_oracle 迁移方法 对比
文章浏览阅读553次。开头还是介绍一下群,如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,在新加的朋友会分到2群(共700多人左右 1 + 2)。最近我们在使用MYSQL 8 的情况下(8.025)在数据库运行中出现一个问题 参数prefer_order_i..._mysql prefer_ordering_index
文章浏览阅读3.5k次,点赞3次,收藏7次。折腾了两个小时多才成功连上,在这分享一下我的经验,也仅仅是经验分享,有不足的地方欢迎大家在评论区补充交流。_navicat连接opengauss
文章浏览阅读2.7k次。JSON 代表 JavaScript Object Notation。它是一种开放标准格式,将数据组织成中详述的键/值对和数组。_postgresql json
文章浏览阅读2.9k次,点赞2次,收藏6次。navicat 连接postgresql 注:navicat老版本可能报错。1.在springboot中引入我们需要的依赖以及相应版本。用代码生成器生成代码后,即可进行增删改查(略)安装好postgresql 略。更改配置信息(注释中有)_mybatisplus postgresql
文章浏览阅读1.4k次。postgre进阶sql,包含分组排序、JSON解析、修改、删除、更新、强制踢出数据库所有使用用户、连表更新与删除、获取今年第一天、获取近12个月的年月、锁表处理、系统表使用(查询所有表和字段及注释、查询表占用空间)、指定数据库查找模式search_path、postgre备份及还原_pgsql分组取每组第一条
文章浏览阅读3.3k次。上一篇我们学习了日志清理,日志清理虽然解决了日志膨胀的问题,但就无法再恢复检查点之前的一致性状态。因此,我们还需要日志归档,pg的日志归档原理和Oracle类似,不过归档命令需要自己配置。以下代码在postmaster.c除了开启归档外,还需要保证wal_level不能是MINIMAL状态(因为该状态下有些操作不会记录日志)。在db启动时,会同时检查archive_mode和wal_level。以下代码也在postmaster.c(PostmasterMain函数)。......_postgresql archive_mode
文章浏览阅读3k次。系统:ubuntu22.04.3目的:利用向日葵实现windows远程控制ubuntu。_csdn局域网桌面控制ubuntu
文章浏览阅读1.6k次。表分区是解决一些因单表过大引用的性能问题的方式,比如某张表过大就会造成查询变慢,可能分区是一种解决方案。一般建议当单表大小超过内存就可以考虑表分区了。1,继承式分区,分为触发器(trigger)和规则(rule)两种方式触发器的方式1)创建表CREATE TABLE "public"."track_info_trigger_partition" ( "id" serial, "object_type" int2 NOT NULL DEFAULT 0, "object_name..._pg数据表分区的实现
文章浏览阅读3.3k次。物联网平台开源的有几个,就我晓得的有、、thingskit、JetLink、DG-iot(还有其他开源的,欢迎在评论区留言哦!),然后重点分析了下ThingsBoard、ThingsPanel和JetLink,ThingsBoard和Jetlinks是工程师思维产品,可以更多的通过配置去实现开发的目的,ThingsPanel是业务人员思路产品,或者开发或者用,避免了复杂的配置带来的较高学习门槛。ThingsBoard和Jetlinks是Java技术体系的,ThingsPanel是PHP开发的。_jetlinks和thingsboard
文章浏览阅读3.8k次。PostgreSQL 数据类型转换_pgsql数字转字符串
文章浏览阅读7k次,点赞3次,收藏14次。在做数据统计页面时,总会遇到统计某段时间内,每天、每月、每年的数据视图(柱状图、折线图等)。这些统计数据一眼看过去也简单呀,不就是按照时间周期(天、月、年)对统计数据进行分个组就完了嘛?但是会有一个问题,简单的写个sql对周期分组,获取到的统计数据是缺失的,即没有数据的那天,整条记录也都没有了。如下图需求:以当前月份(2023年2月)为起点,往后倒推一年,查询之前一年里每个月的统计数据。可见图中的数据其实是缺少的,这条sql只查询到了有数据的月份(23年的1月、2月,22年的12月)_如何用一条sql查出按年按月按天的汇总
文章浏览阅读3.8k次,点赞66次,收藏51次。PostgreSQL全球开发小组与2022年10月13日,宣布发布PostgreSQL15,这是世界上最先进的开源数据库的最新版本_mysql8 postgresql15
文章浏览阅读1.3k次。上文介绍了磁盘管理器中VFD的实现原理,本篇将从上层角度讲解磁盘管理器的工作细节。_smgrrelationdata
文章浏览阅读1.1k次。PostgreSQL设置中文语言界面和局域网访问_postgressql汉化
文章浏览阅读4.2k次。PostgreSQL 修改数据存储路径_如何设置postgresql 数据目录
文章浏览阅读4.7k次。在项目中用到了多数据源,在连接postgres数据库时,项目启动报错,说数据库连接错误,说dual不存在,网上好多教程都是说数据库查询的时候的大小写问题,而这个仅仅是连接,咋鞥却处理方法是修改application-dev.yml中的配置文件.项目中的druid参数是这样的:确实在配置文件中有个查询语句。_relation "dual" does not exist
文章浏览阅读4.9k次。PostgreSQL是一款强大的关系型数据库,但在实际使用过程中,许多用户经常会遇到慢SQL的问题。这些问题不仅会降低数据库性能,还会直接影响业务流程和用户体验。因此,本文将会深入分析PostgreSQL慢SQL的原因和优化方案,帮助用户更好地利用这个优秀的数据库系统。无论你是初学者还是专业开发者,本文都将为你提供实用的技巧和方法,让你的PostgreSQL数据库始终保持高效快速。_postgresql数据库优化
文章浏览阅读1.6k次。Linux配置postgresql开机自启_linux 启动pgsql
文章浏览阅读2k次。本篇介绍如何在centos7系统搭建一个postgresql主备集群实现最近的HA(高可用)架构。后续更高级的HA模式都是基于这个最基本的主备搭建。_postgresql主备