三月 28, 2025
摘要:pg_timetable
程序是 PostgreSQL 的一个高级作业调度工具。
目录
pg_timetable 简介
在数据库管理中,作业调度一直发挥着重要作用。对于 PostgreSQL 而言,其广受欢迎的作业调度器有 PgAgent 和 pg_cron。然而,还有一个名为 pg_timetable 的作业调度器,它完全由数据库驱动,并提供了一些先进的概念。在本文中,我们将重点介绍 pg_timetable 的一些主要特性、安装方法和使用案例。
主要特性
- 完全由数据库驱动的配置
- 基于 PostgreSQL 服务器时区,类似 Cron 的调度风格
- 内置发送邮件等任务
- 完全支持由数据库驱动的日志记录
- 任务可设置为链式执行
- 任务链中可包含内置命令、SQL 语句和可执行文件
- 可向任务链 / 任务传递参数
安装
目前,安装和运行 pg_timetable 有两种方式:
- 容器安装。相关内容请参考此页面。
- 本地安装,即从源代码构建。这里我们将讨论这种方法。
1. 在您的系统上下载并安装 GO。
2. 克隆 pg_timetable 仓库
$ git clone https://github.com/cybertec-postgresql/pg_timetable.git
$ cd pg_timetable
3. 运行 pg_timetable
$ go run main.go --dbname=dbname --clientname=worker001 --user=scheduler --password=strongpassword
4. 或者,构建一个二进制文件并运行它:
$ go build
$ ./pg_timetable --dbname=dbname --clientname=worker001 --user=scheduler --password=strongpassword
使用 pg_timetable 演示作业调度
在本用例中,将会展示如何使用 pg_timetable 作为调度器来安排一个作业,该作业会在每天午夜 12 点刷新物化视图。
1. 下载 pg_timetable 可执行文件(遵循上述安装部分中的步骤 2)。
2. 确保 PostgreSQL 服务器已启动并运行,并且拥有一个对目标数据库具有 CREATE 权限的角色,例如:
CREATE ROLE scheduler PASSWORD '***********';
GRANT CREATE ON DATABASE postgres TO scheduler;
CREATE TABLE t_demo (grp int, data numeric);
INSERT INTO t_demo SELECT 1, random()
FROM generate_series(1, 5000000);
CREATE MATERIALIZED VIEW mat_view AS
SELECT grp, avg(data), count(*)
FROM t_demo
GROUP BY 1;
ALTER MATERIALIZED VIEW mat_view OWNER TO scheduler;
GRANT SELECT ON mat_view TO scheduler;
SELECT * FROM mat_view;
grp | avg | count
-----+--------------------------+---------
1 | 0.5001807958659610956005 | 5000000
(1 row)
INSERT INTO t_demo
SELECT 2, random()
FROM generate_series(1, 5000000);
3. 创建一个新作业,以在 Postgres 服务器时区的每晚 12 点刷新物化视图:
SELECT timetable.add_job('refresh-matview', '0 12 * * *', 'REFRESH MATERIALIZED VIEW public.mat_view');
add_job
---------
1
(1 row)
4. 运行 pg_timetable:
$ ./pg_timetable --dbname=postgres --clientname=worker001 --user=scheduler --password=********
2024-09-09 11:59:20.929 [INFO] [sid:697146069] Starting new session...
2024-09-09 11:59:20.941 [INFO] Database connection established
2024-09-10 12:00:00.961 [INFO] Accepting asynchronous chains execution requests...
2024-09-10 12:00:00.970 [INFO] [count:0] Retrieve scheduled chains to run @reboot
2024-09-10 12:00:00.991 [INFO] [count:3] Retrieve scheduled chains to run
2024-09-10 12:00:00.994 [INFO] [count:0] Retrieve interval chains to run
2024-09-10 12:00:00.019 [INFO] [chain:1] Starting chain
2024-09-10 12:00:00.722 [INFO] [chain:1] [task:1] [txid:2613] Starting task
2024-09-10 12:00:00.074 [INFO] [chain:1] [task:1] [txid:2613] Starting task
2024-09-10 12:00:00.141 [INFO] [chain:1] [task:1] [txid:2613] Closing remote session
2024-09-10 12:00:00.141 [INFO] [chain:1] [task:1] [txid:2613] Task executed successfully
2024-09-10 12:00:00.185 [INFO] [chain:1] [txid:2613] Chain executed successfully
在首次启动 pg_timetable 时,会创建一个必要的 timetable 模式。作为参考,以下是表结构:
postgres=# \dn
List of schemas
Name | Owner
-----------+-----------
public | postgres
timetable | scheduler
(2 rows)
postgres=# set search_path to timetable ;
postgres=# \dt
List of relations
Schema | Name | Type | Owner
-----------+----------------+-------+-----------
timetable | active_chain | table | scheduler
timetable | active_session | table | scheduler
timetable | chain | table | scheduler
timetable | execution_log | table | scheduler
timetable | log | table | scheduler
timetable | migration | table | scheduler
timetable | parameter | table | scheduler
timetable | task | table | scheduler
(8 rows)
5. 从数据库日志中可以观察到,物化视图已按计划刷新。
数据库日志的输出:
2024-09-10 12:00:00 UTC [14334] LOG: statement: REFRESH MATERIALIZED VIEW public.mat_view
使用 psql 连接到数据库,执行查询:
SELECT * FROM mat_view;
grp | avg | count
-----+---------------------------+---------
1 | 0.5001807958659610956005 | 5000000
2 | 0.50000009110202547559215 | 5000000
(2 rows)
以下是 pg_timetable 系统表的内容:
select * from active_session ;
client_pid | server_pid | client_name | started_at
------------+------------+-------------+-----------------------------
697146069 | 20137 | worker001 | 2024-09-10 11:59:205672+00
(1 row)
select * from chain;
-[ RECORD 1 ]--------+--------------------
chain_id | 1
chain_name | refresh-matview
run_at | 0 12 * * *
max_instances |
timeout | 0
live | t
self_destruct | f
exclusive_execution | f
client_name |
on_error |
select * from execution_log where chain_id=1;
-[ RECORD 1 ]-+------------------------------------------
chain_id | 1
task_id | 1
txid | 2613
last_run | 2024-09-10 12:00:00.137404+00
finished | 2024-09-10 12:00:00.586543+00
pid | 697146069
returncode | 0
kind | SQL
command | REFRESH MATERIALIZED VIEW public.mat_view
output | REFRESH MATERIALIZED VIEW
client_name | worker001
总之,pg_timetable 是开源的,可供所有人免费使用。其主要优点包括:pg_timetable 是用 GO 编写的独立进程,它像任何其他客户端程序一样连接到 PostgreSQL。因此,如果调度器崩溃,不会对服务器造成损害。pg_timetable 提供了多种内置任务,有助于您轻松灵活地组合这些操作。此外,pg_timetable 是用 GO 实现的,因此是一个可直接启动的可执行文件。所以,在安装过程中无需担心库或依赖项的问题。