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


41

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

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

  • 我想避免与pgAgent命令行上存储的密码有关的安全问题。
  • 我想避免隐藏密码(~/.pgpass)的任何其他系统配置。

PostgreSQL 8.3
Linux RedHat 64位


您能补充为什么不能使用pgAgent或crontab吗?具体是什么功能都丢失..
WrinkleFree

@Rohan我已经更新了我的问题
Stephan

帖子似乎已被复制并粘贴到stackoverflow.com/q/16958625/398670
Craig Ringer 2013年

Answers:


30

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

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

希望9.3中引入的后台工作程序功能应允许将PgAgent之类的工具在以后的版本中移至PostgreSQL内核中,但尚未完成。即使在9.3上,您仍然必须运行cron或pgagent。

少数人正在基于后台工作者的调度程序上工作,并且即将发布一些修补程序,这些修补程序应该可以提供帮助。但是到PostgreSQL 10为止,仍然没有良好的质量,被广泛采用的调度程序,大多数人使用cron / ms任务调度程序/等。

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


Please take a look at the version policy,则无法升级Postgresql。
斯蒂芬

2
@Alex您将不得不在某个时候进行升级,但这只会变得越来越难。顺便说一下,什么是8.3点释放?您缺少多少个重要的错误修复程序?还是您至少在8.3.23上?就是说,正如我所解释的,即使在即将发布的9.3版本中,您所需的功能也不存在,尽管已添加了一些允许添加该功能的基础。
Craig Ringer 2013年

我将与老板交谈:)
Stephan 2013年

1
@Alex好主意:-)。至少紧急更新到8.3.23,然后开始着手计划升级到较新的版本。它不会解决这个问题,但它是一个不错的主意,以节省未来的痛苦。我支持的客户数量之多,即使他们保持最新状态,也从未有过。我们不只是为了踢球而发行新版本;-)。阅读每个.0版本的发行说明,以获取可能需要处理的事项的指导,并阅读升级手册。您唯一可能的痛点是standard_conforming_stringsbytea_output
Craig Ringer 2013年

克雷格,您如何看待pg_cron?
穆罕默德(Mehmet)'18

21

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

设置好之后,创建工作非常简单:

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

这将根据指定的cron计划运行delete命令。您还可以使用它@reboot来计划服务器重启时的作业,如果您升级了热备用服务器,pg_cron将自动开始运行作业。

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


-1

您确实非常不想这样做。Postgres不是操作系统,而是数据库服务器。即使数据库支持运行计划的任务,也不应该这样滥用数据库。

如果您担心的是不想设置密码和设置,那很容易解决。而是使用信任或身份验证来建立本地Unix套接字连接,以该用户身份运行cronjob。

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

在默认设置中,您可以执行以下操作:

$ sudo -u postgres crontab -e

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

0    0    *     *    * bash /path/to/run_stored_procedure.sh

在/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

1
“像这样滥用数据库并不是一个好主意。” 为什么您认为这是滥用?不同的主流RDBMS倾向于采用相似的方法,但我认为这不是那么可怕。另外,如果您无权访问操作系统,那么使用crontab会很容易。
dezso
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.