介绍:
pg_cron 相当于在database内部的一个crontab程序,类似于Oracle中的job和scheduler.
pg_cron 可以同时运行多个job,但在同一时刻,只有一个job在执行,后续的job会挂起,直到前一个执行完成。
项目地址:
https://github.com/citusdata/pg_cron
安装使用
pg_cron的使用需要PG版本在9.4及以上,因为用到的一个结构体在9.4版本中进行了扩展。
9.3:
typedef void (*bgworker_main_type)(Datum main_arg);
typedef struct BackgroundWorker
{
char bgw_name[BGW_MAXLEN];
int bgw_flags;
BgWorkerStartTime bgw_start_time;
int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */
bgworker_main_type bgw_main;
Datum bgw_main_arg;
} BackgroundWorker;
在make的时候会报错:
src/pg_cron.c:169: error: ‘BackgroundWorker’ has no member named ‘bgw_notify_pid’
src/pg_cron.c:170: error: ‘BackgroundWorker’ has no member named ‘bgw_library_name’
9.4:
typedef void (*bgworker_main_type)(Datum main_arg);
typedef struct BackgroundWorker
{
char bgw_name[BGW_MAXLEN];
int bgw_flags;
BgWorkerStartTime bgw_start_time;
int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */
bgworker_main_type bgw_main;
char bgw_library_name[BGW_MAXLEN]; /* only if bgw_main is NULL */
char bgw_function_name[BGW_MAXLEN]; /* only if bgw_main is NULL */
Datum bgw_main_arg;
int bgw_notify_pid;
} BackgroundWorker;
9.3中报错缺失的部分在9.4中刚好有。
本例环境是9.5.3
参照read me 进行安装:
git clone https://github.com/citusdata/pg_cron.git
cd pg_cron
PATH=/usr/local/pgsql/bin/:$PATH make
sudo PATH=/usr/local/pgsql/bin/:$PATH make install
修改postgres.conf 参数:
# add to postgresql.conf:
shared_preload_libraries = 'pg_cron'
重启之后,创建扩展:
postgres@postgres:5532 # create extension pg_cron;
CREATE EXTENSION
默认情况下,会在postgres database下创建cron schema,如果需要指定数据库,需要添加参数:cron.database_name。
创建测试表:
postgres@postgres:5532 # create table t_cron ( insert_date timestamp);
CREATE TABLE
postgres@postgres:5532 # insert into t_cron values (now());
INSERT 0 1
postgres@postgres:5532 # select * from t_cron;
insert_date
----------------------------
2016-11-01 17:07:09.652907
(1 row)
创建cron,每分钟往测试表insert一条数据:
postgres@postgres:5532 # SELECT cron.schedule('* * * * *', 'insert into t_cron values (now())');
schedule
----------
1
几分钟之后,可以看到测试表中已经有了数据:
postgres@postgres:5532 # select * from t_cron;
insert_date
----------------------------
2016-11-01 17:07:09.652907
2016-11-01 17:09:00.002224
2016-11-01 17:10:00.006202
2016-11-01 17:11:00.003283
2016-11-01 17:12:00.003382
(5 rows)
pg_cron 运行成功。
查看当前job:
postgres@postgres:5532 # select * from cron.job;
jobid | schedule | command | nodename | nodeport | database | username
-------+-----------+-----------------------------------+-----------+----------+----------+----------
1 | * * * * * | insert into t_cron values (now()) | localhost | 5532 | postgres | postgres
(1 row)
停止job:
postgres@postgres:5532 # select cron.unschedule(1);
unschedule
------------
t
(1 row)
postgres@postgres:5532 #
postgres@postgres:5532 # select * from cron.job;
jobid | schedule | command | nodename | nodeport | database | username
-------+----------+---------+----------+----------+----------+----------
(0 rows)