1. 什么是pg_corn

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

-- Delete old data on Saturday at 3:30am (GMT)
SELECT cron.schedule('30 3 * * 6', $$DELETE FROM events WHERE event_time < now() - interval '1 week'$$);
 schedule
----------
       42

-- Vacuum every day at 10:00am (GMT)
SELECT cron.schedule('0 10 * * *', 'VACUUM');
 schedule
----------
       43

-- Stop scheduling a job
SELECT cron.unschedule(43);
 unschedule
------------
          t

pg_cron可以并行运行多个作业,但一次最多运行一个作业实例。如果第二次运行应该在第一次运行完成之前开始,则第二次运行将在第一次运行完成后立即排队并启动。

计划使用标准的 cron 语法,其中 * 表示“每个时间段运行”,特定数字表示“但仅在此时”:

 ┌───────────── min (0 - 59)
 │ ┌────────────── hour (0 - 23)
 │ │ ┌─────────────── day of month (1 - 31)
 │ │ │ ┌──────────────── month (1 - 12)
 │ │ │ │ ┌───────────────── day of week (0 - 6) (0 to 6 are Sunday to
 │ │ │ │ │                  Saturday, or use names; 7 is also Sunday)
 │ │ │ │ │
 │ │ │ │ │
 * * * * *

创建 cron 计划的简单方法是:crontab.guru

pg_cron中处理解析和调度的代码直接来自 Paul Vixie 的 cron 源代码,因此支持相同的选项。请注意,pg_cron始终使用 GMT!

1.2.调度系统维护

在为系统维护任务设置pg_cron作业时要格外小心,因为它们可能会产生意想不到的后果。例如,调度命令来终止空闲连接可能会中断关键的后台进程,例如夜间备份。通常,有一个现有的 Postgres 设置,例如 可以无风险地执行这些常见的维护任务。pg_terminate_backend(pid)``idle_session_timeout

1.3. 例子

1.3.1.每周删除数据

周六凌晨 3:30(格林威治标准时间)删除旧数据:

select cron.schedule (
    'saturday-cleanup', -- name of the cron job
    '30 3 * * 6', -- Saturday at 3:30am (GMT)
    $$ delete from events where event_time < now() - interval '1 week' $$
);

1.3.2. Run a vacuum every day

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

1.3.3. 每分钟调用一次 Supabase Edge 函数

每分钟向 Supabase Edge 函数发出 POST 请求。注意:这需要pg_net要启用。

select
  cron.schedule(
    'invoke-function-every-minute',
    '* * * * *', -- every minute
    $$
    select
      net.http_post(
          url:='https://project-ref.supabase.co/functions/v1/function-name',
          headers:='{"Content-Type": "application/json", "Authorization": "Bearer YOUR_ANON_KEY"}'::jsonb,
          body:=concat('{"time": "', now(), '"}')::jsonb
      ) as request_id;
    $$
  );

1.3.4. 编辑作业

将作业调用的频率更改为每 5 分钟调用一次。'vacuum'

select cron.alter_job(
  job_id := (select jobid from cron.job where jobname = 'vacuum'),
  schedule := '*/5 * * * *'
);

该功能的完整选项包括:cron.alter_job()

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

1.3.5.取消计划作业

取消计划名为'nightly-vacuum'

select cron.unschedule('nightly-vacuum');

1.3.6.查看以前运行的作业

查看最近运行的 10 个作业

select * from cron.job_run_details
order by start_time desc
limit 10;

1.3.7.查看所有任务

SELECT * FROM cron.job;
jobidschedulecommandnodenamenodeportdatabaseusernameactivejobname
10629 03 * * *vacuum freeze test_tablelocalhost8192database1adminusertdatabase1 manual vacuum
159 23 * * *vacuum freeze pgbench_accountslocalhost8192postgresadminusertmanual vacuum

2.安装pg_cron

2.1. yum安装

  1. 使用 [PGDGG] 在装有 PostgreSQL 16 的 Red Hat、CentOS、Fedora、Amazon Linux 上安装:
# Install the pg_cron extension
sudo yum install -y pg_cron_16
  1. 使用 [PostgreSQL] 在 Debian、Ubuntu 上安装 16 使用 apt.postgresql.org:
# Install the pg_cron extension
sudo apt-get -y install postgresql-16-cron
  1. 您还可以通过从源代码构建来安装 pg_cron:
git clone https://github.com/citusdata/pg_cron.git
cd pg_cron
# Ensure pg_config is in your path, e.g.
export PATH=/usr/pgsql-16/bin:$PATH
make && sudo PATH=$PATH make install

2.2.下载安装

https://github.com/citusdata/pg_cron

![[pg_cron_github_source.png]]

下载软件包并解压

su - postgres

确认pg_config包含在$PATH中

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

3. 使用pg_cron

使用superuser用户增加扩展

CREATE EXTENSION pg_cron;

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

GRANT USAGE ON SCHEMA cron TO scott;
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐