Как запускать повторяющиеся задачи в Postgresql без внешнего инструмента, похожего на cron?

41

Я хотел бы вызывать хранимую процедуру на регулярной основе. На Oracle я бы создал для этого работу. Я обнаружил, что Postgresql может хорошо имитировать это с помощью внешнего инструмента (cron и т. Д.) И PgAgent.

Знаете ли вы о «внутренней» альтернативе, в которой не использовался бы внешний инструмент?

  • Я хочу избежать проблем безопасности с паролем, хранящимся в командной строке pgAgent.
  • Я хочу избежать любой дополнительной конфигурации системы для сокрытия пароля ( ~/.pgpass).

Postgresql 8.3
Linux RedHat 64bit

Stephan
источник
Можете ли вы добавить, почему вы не можете использовать pgAgent или crontab? в частности, какие функции отсутствуют ..
WrinkleFree
@Rohan Я обновил свой вопрос
Стефан
Кажется, что сообщение было скопировано и вставлено в stackoverflow.com/q/16958625/398670
Крейг Рингер

Ответы:

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 не вариант.
Стефан
3
@ Алекс Вам придется обновиться в какой-то момент, и будет только сложнее. Какой 8.3 пункт выпуска, кстати? Сколько значительных исправлений вы пропустили? Или ты хотя бы на 8.3.23? Тем не менее, как я объяснил, нужной вам функции не существует даже в предстоящем выпуске 9.3, хотя некоторые основы для ее добавления были добавлены.
Крейг Рингер
Я поговорю с моим боссом :)
Стефан
1
@ Алекс Хорошая идея :-). Как минимум срочно обновите до 8.3.23, затем начните работу над планами обновления до более новой версии. Это не решит этот вопрос, но это очень хорошая идея, чтобы спасти боль в будущем. Число клиентов, которых я поддерживаю, у которых есть проблемы, которых у них никогда не было бы, если бы они оставались в курсе, просто поразительно. Мы не выпускаем новые версии только для удовольствия ;-). Прочтите примечания к выпуску для каждой версии .0, чтобы узнать, что вам может понадобиться, и прочтите руководство по обновлению. Ваши единственные вероятные болевые точки - это standard_conforming_stringsи bytea_output.
Крейг Рингер
Крейг, что ты думаешь о pg_cron?
Мехмет
21

Начиная с PostgreSQL 9.5, вы можете использовать расширение pg_cron , которое загружается как общая библиотека в PostgreSQL.

После настройки создать вакансию довольно просто:

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

Это запустит команду удаления в соответствии с указанным расписанием cron. Вы также можете использовать @rebootдля планирования задания при перезапуске сервера, и pg_cron автоматически запустит выполнение заданий, если вы включите горячее резервирование.

Вместо использования .pgpass вы можете предоставить локальный доступ для пользователя cron в pg_hba.conf.

Марко Слот
источник
-1

Вы действительно, действительно не хотите этого делать. Postgres - это не операционная система, это сервер базы данных. Даже если база данных поддерживает выполнение запланированных задач, не стоит злоупотреблять этой базой данных.

Если вы обеспокоены тем, что не хотите устанавливать пароль и другие материалы, это легко решить. Вместо этого установите локальное соединение с сокетом Unix, используя доверительную или идентификационную аутентификацию , запустите ваш cronjob от имени этого пользователя.

В стандартной конфигурации postgres обычно настраивает системного пользователя postgresдля запуска сервера db, и этот системный пользователь обычно уже настроен заранее, поэтому он может подключаться к локальному серверу с помощью доверительной аутентификации при подключении через локальный сокет unix. Вы можете запустить свой cronjob от имени пользователя системы postgres, подключиться к локальному сокету и затем поменять роль, если не хотите, чтобы хранимая процедура выполнялась с привилегиями суперпользователя.

В настройках по умолчанию вы можете просто сделать это:

$ 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
«Это не очень хорошая идея, чтобы так злоупотреблять базой данных» Почему вы думаете, что это злоупотребление? В разных основных РСУБД есть сходные подходы, и я не думаю, что это так ужасно. Кроме того, если у вас нет доступа к ОС, вам не хватает crontab.
Дезсо