如何在没有外部类似 cron 的工具的情况下在 Postgresql 上运行重复任务?

Ste*_*han 48 postgresql jobs scheduled-tasks

我想定期调用存储过程。在 Oracle 上,我会为此创建一个工作。我发现 Postgresql 可以通过使用外部工具(cron 等)和 PgAgent 很好地模拟这一点。

您是否知道不涉及外部工具的“内部”替代方案?

  • 我想避免存储在 pgAgent 命令行上的密码的安全问题。
  • 我想避免任何用于隐藏密码 ( ~/.pgpass) 的额外系统配置。

Postgresql 8.3
Linux RedHat 64 位

Cra*_*ger 33

即使您正在运行即将发布(在撰写本文时)的 PostgreSQL 10 或当前的 PostgreSQL 9.6,而不是像 8.3 这样的古老版本,仍然没有内置的任务调度程序。

需要像 PgAgent 或外部 cron 作业之类的东西,没有方便的解决方法。

9.3 中引入的后台工作功能应该有望允许像 PgAgent 这样的工具在以后的版本中移动到 PostgreSQL 核心中,但还没有完成。即使在 9.3 上,您仍然必须运行 cron 或 pgagent。

一些人正在研究基于后台工作程序的调度程序,并且有一些补丁会提供工具来帮助解决这个问题。但是从 PostgreSQL 10 开始,仍然没有质量好、被广泛采用的调度程序,大多数人使用 cron / ms 任务调度程序 / 等。

也请看一下版本政策;您正在运行一个过时且不受支持的版本。

  • @Alex 您将不得不在某个时候升级,而且只会越来越难。顺便问一下,什么8.3点发布?您错过了多少重要的错误修复?或者你至少在 8.3.23 上?也就是说,正如我所解释的,即使在即将发布的 9.3 版本中,您想要的功能也不存在,尽管已经添加了一些允许添加的基础工作。 (3认同)

小智 30

从 PostgreSQL 9.5 开始,您可以使用pg_cron扩展,它作为共享库加载到 PostgreSQL 中。

设置完成后,创建作业非常简单:

SELECT cron.schedule('30 3 * * 6', $$DELETE FROM events WHERE event_time < now() - interval '1 week'$$);
Run Code Online (Sandbox Code Playgroud)

这将根据指定的 cron 计划运行删除命令。您还可以使用@reboot在服务器重新启动时安排作业,如果您升级热备份,pg_cron 将自动开始运行作业。

您可以在 pg_hba.conf 中为 cron 用户提供 localhost 访问,而不是使用 .pgpass。


Lie*_*yan 5

你真的真的不想这样做。Postgres 不是一个操作系统,而是一个数据库服务器。即使数据库支持运行计划任务,像这样滥用数据库也不是一个好主意。

如果您担心不想设置密码和其他内容,这很容易解决。使用信任或身份验证设置本地 Unix 套接字连接,以该用户身份运行 cronjob。

在其开箱即用的配置中,通常 postgres 设置系统用户postgres来运行数据库服务器,并且该系统用户通常已经预先配置,因此在通过本地 unix 套接字连接时可以使用信任身份验证连接到本地服务器。您可以以 postgres 系统用户身份运行 cronjob,连接到本地套接字,然后如果您不希望存储过程以超级用户权限运行,则切换角色。

在默认设置下,您可以这样做:

$ sudo -u postgres crontab -e
Run Code Online (Sandbox Code Playgroud)

在编辑器中,添加到 crontab 条目,如下所示:

0    0    *     *    * bash /path/to/run_stored_procedure.sh
Run Code Online (Sandbox Code Playgroud)

在 /path/to/run_stored_procedure.sh 文件中,您只需使用 psql 来调用存储过程

#!/usr/bin/env bash
psql my_db_name <<END
    SET ROLE limited_user;
    SELECT my_stored_proc();
    SELECT 1 FROM my_stored_proc();
END
Run Code Online (Sandbox Code Playgroud)

  • _“像这样滥用数据库并不是一个好主意”_您为什么认为这是滥用?不同的主流 RDBMS 往往有类似的方法,我认为这并不是那么糟糕。另外,如果您无法访问操作系统,那么您就缺少 crontab。 (23认同)
  • 滥用取决于你用它做什么。有许多在数据库层使用 cron 的扩展,例如 timescaledb。我还认为一个很好的用例是自动刷新物化视图。为什么不在数据库中承担这个责任呢?我确实理解这种情绪,因为它很容易被滥用。 (3认同)