F.54. pgpro_scheduler — планирование, контроль и управление выполнением заданий #

pgpro_scheduler — это встроенное в Postgres Pro Enterprise расширение, позволяющее планировать и контролировать задания, а также управлять их выполнением в базе данных Postgres Pro Enterprise. С pgpro_scheduler вы можете:

  • Задавать сложные расписания в виде объектов jsonb или строк crontab.

  • Динамически вычислять время следующего запуска для повторяющихся заданий.

  • Выполнять SQL-команды задания в одной или в нескольких последовательных транзакциях, если требуется.

  • Назначать задания для немедленного или отложенного однократного выполнения одновременно с обычными планируемыми заданиями.

По сравнению с внешними планировщиками pgpro_scheduler имеет следующие преимущества:

  • Любой пользователь может планировать задания независимо.

  • Планированием заданий можно управлять «на лету», не перезапуская базу данных.

  • pgpro_scheduler отличается очень лёгкой реализацией, так как для планирования и контроля заданий, а также для управления ими он использует фоновые рабочие процессы. И при этом pgpro_scheduler не задействует никакие клиентские подключения.

  • Для большей стабильности в каждой базе данных имеется собственный руководящий планировщик, а каждое запланированное задание выполняется в отдельном рабочем процессе.

Примечание

pgpro_scheduler находится в состоянии ожидания на ведомом сервере и будет активирован, когда ведущий станет ведомым.

Примечание

Обратите внимание, что для всех выполненных заданий в представлении pg_stat_activity в любом случае будет отображаться имя суперпользователя базы данных, который используется рабочим процессом.

F.54.1. Установка и подготовка #

Расширение pgpro_scheduler включено в состав Postgres Pro Enterprise. Установив Postgres Pro Enterprise, выполните следующие действия, чтобы подготовить pgpro_scheduler к работе:

  1. Добавьте pgpro_scheduler в параметр shared_preload_libraries в файле postgresql.conf:

    shared_preload_libraries = 'pgpro_scheduler'
  2. Создайте расширение pgpro_scheduler, выполнив следующий запрос:

    CREATE EXTENSION pgpro_scheduler;

    Расширение pgpro_scheduler необходимо создать в каждой базе данных, где вы планируете его использовать.

Завершив установку и подготовку, настройте pgpro_scheduler в вашей базе данных.

F.54.2. Конфигурирование #

Для настройки pgpro_scheduler необходимо иметь права суперпользователя.

Чтобы настроить pgpro_scheduler, измените следующие параметры в файле postgresql.conf:

  1. Укажите имена баз данных, для которых вам нужно будет настраивать задания, через запятую:

    schedule.database = 'база1,база2'
  2. Для ограничения рабочей нагрузки в вашей системе задайте максимальное число рабочих процессов, которые могут выполняться одновременно в каждой базе данных:

    schedule.max_workers = 5
  3. Дополнительно можно задать число рабочих процессов, доступных для одного выполнения задания:

    schedule.max_parallel_workers = 3

    По умолчанию для одноразовых заданий выделяются два процесса. Они не учитываются в ограничении schedule.max_workers. Таким образом, одноразовые задания могут выполняться параллельно с заданиями, планируемыми по графику, даже если все процессы в количестве schedule.max_workers заняты.

  4. Выполните pg_reload_conf(), чтобы изменения вступили в силу:

    SELECT pg_reload_conf();

Важно

Устанавливая переменные schedule.max_workers, schedule.max_parallel_workers и schedule.database, убедитесь, что в общем пуле рабочих процессов, заданном с помощью max_worker_processes, остаётся достаточно свободных процессов. Эти процессы могут потребоваться другим подсистемам Postgres Pro.

За подробной информацией по расчёту количества фоновых рабочих процессов и примерами конфигурации обратитесь к Подразделу F.54.3.

Фоновым процессам pgpro_scheduler доступна приоритизация ресурсов. Для запланированных заданий можно задать вес потребления ресурсов через соответствующие параметры конфигурации. За подробной информацией обратитесь к pgpro_rp.

Поведение pgpro_scheduler можно также динамически настраивать из командной строки. Данный пример показывает, как можно установить различное число рабочих процессов для разных баз данных:

ALTER SYSTEM SET schedule.database = 'database1,database2';
ALTER DATABASE database1 SET schedule.max_workers = 5;
ALTER DATABASE database2 SET schedule.max_workers = 3;
ALTER SYSTEM SET schedule.max_parallel_workers = 3;
SELECT pg_reload_conf();

Настроив pgpro_scheduler, включите его в вашей системе так:

SELECT schedule.enable();

Если эта функция возвратит true, значит pgpro_scheduler готов к использованию, и вы можете приступать к планированию заданий, как описано в Подразделе F.54.4.1 и Подразделе F.54.4.2.

Примечание

Если перезапустить сервер, pgpro_scheduler по умолчанию не будет запускаться автоматически. Чтобы поменять это поведение, присвойте параметру schedule.auto_enabled значение on.

См. также

Подраздел F.54.5.1

F.54.3. Вычисление необходимого количества фоновых рабочих процессов #

Максимальное количество рабочих процессов, используемых расширением pgpro_scheduler, вычисляется по следующей формуле:

1 + N * (1 + schedule.max_workers + schedule.max_parallel_workers)
  • 1: глобальный фоновый рабочий процесс типа supervisor для расширения pgpro_scheduler.

  • N: количество баз данных, перечисленных в параметре schedule.database. Для каждой из этих баз запускаются отдельный рабочий процесс типа database manager и другие фоновые процессы.

  • schedule.max_workers: максимальное количество фоновых рабочих процессов для планируемых заданий.

  • schedule.max_parallel_workers: максимальное количество фоновых рабочих процессов для одноразовых заданий.

Обратите внимание, что данная формула вычисляет общее количество фоновых рабочих процессов для базовой конфигурации, исходя из глобальных значений по умолчанию, заданных с помощью ALTER SYSTEM. Чтобы повысить производительность и учесть специфику отдельных задач, настройте параметры schedule.max_workers и schedule.max_parallel_workers индивидуально для каждой базы данных из списка schedule.database и учтите эти значения при расчёте общего количества процессов.

Значение параметра max_worker_processes должно обеспечивать достаточное количество рабочих процессов как для расширения pgpro_scheduler, так и для других подсистем Postgres Pro. Перед первым использованием pgpro_scheduler увеличьте значение max_worker_processes на величину, полученную по приведённой выше формуле. Корректируйте этот параметр при каждом изменении конфигурации pgpro_scheduler.

Например, если вы работаете с двумя базами данных и установили для schedule.max_workers значение 5, а для schedule.max_parallel_workers — значение 3, pgpro_scheduler может использовать до 1 + 2 * (1 + 5 + 3) = 19 фоновых рабочих процессов. Соответственно, значение параметра max_worker_processes необходимо увеличить на 19.

Рассмотрим более сложный пример: вы решили включить расширение для третьей базы данных. Параметры должны быть настроены следующим образом:

  • Для третьей базы данных для schedule.max_parallel_workers задайте значение 2, а для schedule.max_workers оставьте равным 5 (значение по умолчанию).

  • Для второй базы данных для параметра schedule.max_workers задайте значение 2.

В этом случае общее количество рабочих процессов, необходимых для pgpro_scheduler, составит:

1 + (1 + 5 + 3) + (1 + 2 + 3) + (1 + 5 + 2) = 24

Соответственно, значение параметра max_worker_processes необходимо увеличить ещё на 5 рабочих процессов (24 - 19 = 5).

Если все фоновые рабочие процессы в данном пуле заняты, задания ожидают освобождения одного из рабочих процессов. Это может приводить к задержкам выполнения заданий планировщика. Чтобы управлять процессом выполнения, планируемые и одноразовые задания помещаются в разные очереди.

При необходимости количество рабочих процессов можно изменить позднее. Чтобы проверить состояние расширения, используйте функцию schedule.status(). При появлении заданий в состоянии submitted, проверьте, что выделено достаточно фоновых рабочих процессов.

Изменение значений параметров schedule.max_workers и schedule.max_parallel_workers не влияет на уже запущенные задания.

F.54.4. Использование #

F.54.4.1. Создание планируемых заданий #

Чтобы создать и запланировать задание, вызовите функцию create_job(), которая принимает параметры планирования в виде объекта jsonb:

schedule.create_job(options jsonb)

В объекте jsonb вы должны задать одну или несколько SQL-команд в ключе commands и задать расписание выполнения в одном из следующих ключей:

  • dates — одна дата или массив дат в формате timestamp with time zone

  • cron — строка в традиционном формате crontab, включающем пять полей. В первом поле задаётся минута, во втором — час, в третьем — день месяца, в четвёртом — номер месяца, а в пятом — номер дня недели.

    ┌── минута (0 - 59)
    │ ┌─── час (0 - 23)
    │ │ ┌─── день месяца (1 - 31)
    │ │ │ ┌──── месяц (1 - 12)
    │ │ │ │ ┌──── день недели (0 - 6) (с воскресенья по субботу)
    │ │ │ │ │
    * * * * *

    Также может использоваться расширенный формат crontab с шестью полями. В этом формате первое поле задаёт секунду. Если вы задаёте строку в формате с шестью полями и секунды не имеют значения, задайте в первом поле 0.

    Также вместо строки crontab можно указать одно из следующих ключевых слов, определяющих, когда будет запускаться задание:

    • @every_second — каждую секунду

    • @hourly — в начале каждого часа

    • @daily — в начале каждого дня

    • @midnight — в начале каждого дня

    • @weekly — в начале каждой недели

    • @monthly — в начале каждого месяца

    • @yearly — в начале каждого года

    • @annually — в начале каждого года

  • rule — объект jsonb, содержащий один или несколько следующих ключей:

    • seconds — секунды; массив целых чисел в диапазоне [0, 59]

    • minutes — минуты; массив целых чисел в диапазоне [0, 59]

    • hours — часы; массив целых чисел в диапазоне [0, 23]

    • days — дни месяца; массив целых чисел в диапазоне [1, 31]

    • months — месяцы; массив целых чисел в диапазоне [1, 12]

    • wdays — дни недели; массив целых чисел в диапазоне [0, 6], где 0 — воскресенье.

    • onstart — целое значение 0 или 1. Если для onstart задано значение 1, задание выполняется только один раз при запуске pgpro_scheduler.

Для сложных случаев использования ключи dates, cron и rule можно комбинировать.

В результате pgpro_scheduler создаёт активное задание с заданным расписанием и возвращает идентификатор задания.

Подсказка

Для заданий с простым расписанием вы можете использовать следующий упрощённый синтаксис:

schedule.create_job(cron, commands)
schedule.create_job(dates, commands)

За подробностями обратитесь к описанию функции schedule.create_job().

Если потребуется, вы можете позже изменить один или несколько параметров расписания с помощью функций set_job_attribute() и set_job_attributes(), соответственно.

Если все рабочие процессы в указанное время заняты, задание ждёт, пока не появится свободный процесс. По умолчанию ожидание может продолжаться вечно. Вы можете ограничить максимальное время ожидания, установив ключ last_start_available в формате interval. В случае тайм-аута pgpro_scheduler отменяет выполнение задания.

Примеры:

Создание задания, которое будет запускаться каждый день в 15:00 и дополнительно, 31 декабря 2017 г. в 19:00, а также 4 апреля 2020 г. в 13:00:

SELECT schedule.create_job('{"commands": "SELECT 15", "cron": "0 15 * * *", "dates": [ "2017-12-31 19:00", "2020-04-04 13:00" ]}');

Ограничение периода, в течение которого задание будет ожидать выполнения, до 30 секунд после запланированного времени:

SELECT schedule.create_job('{"commands": "SELECT pg_sleep(100)", "cron": "15 */2 * * *", "last_start_available": "30 seconds" }');

Примечание

Как в запланированных, так и в одноразовых заданиях управлять основными транзакциями нельзя, в частности использовать COMMIT и ROLLBACK. Однако можно создавать автономные транзакции и управлять ими.

F.54.4.1.1. Указание интервала времени для выполнения задания #

В дополнение к обычному расписанию вы можете задать интервал времени, в котором может выполняться запланированное задание. Чтобы pgpro_scheduler выполнял задание только в указанном интервале, определите ключи start_date и end_date в формате timestamp with time zone. Вы можете задать только один из этих ключей, чтобы ограничить только время начала и время окончания, соответственно. Если вы определите интервал времени для задания, pgpro_scheduler будет исполнять это задание только в этом интервале. Если запущенное задание продолжает выполняться по достижении конца интервала, pgpro_scheduler завершает его и исключает из дальнейшего плана выполнения.

Примеры:

Создание задания, выполнение которого начнётся только после 11:00 1 мая 2017 г.:

SELECT schedule.create_job('{"commands": "SELECT now()", "cron": "2 17 * * *", "start_date": "2017-05-01 11:00" }');

Создание задания, которое будет выполняться в интервале от 11:00 1 мая до 15:00 4 июня 2017 г.:

SELECT schedule.create_job('{"commands": "SELECT now()", "cron": "2 17 * * *", "start_date": "2017-05-01 11:00", "end_date": "2017-06-04 15:00" }');
F.54.4.1.2. Выполнение SQL-команд в отдельных транзакциях #

В ключе commands значения могут задаваться в виде текста или массива. Если вы задаёте в нём отдельные команды SQL в виде текста, через точку с запятой, всё задание будет выполняться в одной транзакции. Если же требуется, чтобы каждая SQL-команда выполнялась в отдельной транзакции, передайте команды SQL в виде массива. Это поведение можно изменить, установив для параметра use_same_transaction значение true. В этом случае SQL-команды в массиве будут выполняться в одной транзакции.

Примеры:

Создание задания, которое будет выполняться полностью в одной транзакции:

SELECT schedule.create_job('{"commands": "SELECT 1; SELECT 2; SELECT 3;", "cron": "23 23 */2 * *" }');

Выполнение команд в отдельных транзакциях:

SELECT schedule.create_job('{"commands": [ "SELECT 1", "SELECT 2", "SELECT 3" ], "cron": "23 23 */2 * *" }');

Создание задания, которое будет выполняться полностью в одной транзакции, когда команды передаются в виде массива:

SELECT schedule.create_job('{"commands": [ "SELECT 1", "SELECT 2", "SELECT 3" ], "cron": "23 23 */2 * *", "use_same_transaction": true }');
F.54.4.1.3. Вычисление времени следующего запуска запланированного задания #

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

По завершении задания pgpro_scheduler выполняет SQL-оператор, заданный в ключе next_time_statement, который должен вычислить время следующего запуска и выдать результат типа timestamp with time zone. Если возвращаемое значение имеет другой тип или происходит ошибка, pgpro_scheduler помечает задание как нерабочее и отменяет его дальнейшее выполнение. Этот процесс повторяется при каждом последующем запуске.

Подсказка

Когда задание завершается, pgpro_scheduler устанавливает состояние транзакции в переменной schedule.transaction_state, в формате text. Вы можете использовать эту переменную в команде next_time_statement для динамического вычисления времени следующего запуска в зависимости от состояния транзакции. В момент выполнения next_time_statement переменная schedule.transaction_state должна содержать состояние основной транзакции — success (успех) или failure (сбой). Другие варианты состояния указывают на внутреннюю ошибку pgpro_scheduler.

Примеры:

Создание задания, которое запускается сначала в 10:45, а затем через день после завершения:

SELECT schedule.create_job('{"commands": "SELECT random()", "cron": "45 10 * * *", "next_time_statement": "SELECT now() + ''1 day''::interval" }');
F.54.4.1.4. Определение дополнительных условий для выполнения задания #

Расширение pgpro_scheduler позволяет определять дополнительные условия для выполнения задания:

  • Устанавливать интервалы времени для выполнения задания в ключе max_run_time. Если время выполнения задания истекает, pgpro_scheduler отменяет задание.

  • Определять максимальное время ожидания выполнения задания с использованием ключа last_start_available. Если происходит тайм-аут, pgpro_scheduler отменяет задание.

  • Планировать выполнение задания с правами другого пользователя, указав ключ run_as (при наличии прав суперпользователя).

  • Задавать SQL-команду, которая будет выполняться, если основная команда завершается ошибкой, в ключе onrollback.

Примеры:

Ограничение времени выполнения до 5 секунд:

SELECT schedule.create_job('{"commands": "SELECT pg_sleep(10)", "cron": "15 */10 * * *", "max_run_time": "5 seconds" }');

Ограничение периода ожидания выполнения задания до 30 секунд после запланированного времени:

SELECT schedule.create_job('{"commands": "SELECT pg_sleep(100)", "cron": "15 */2 * * *", "last_start_available": "30 seconds" }');

Запуск задания с правами пользователя robot:

SELECT schedule.create_job('{"commands": "SELECT session_user", "cron": "5 */5 * * *", "run_as": "robot" }');

Определение SQL-команды, которая будет выполняться в случае сбоя основной команды:

SELECT schedule.create_job('{"commands": "SELECT ''zzz''", "cron": "55 */12 * * *", "onrollback": "SELECT ''Cannot select zzz''" }');

F.54.4.2. Назначение одноразовых заданий #

Вы можете назначать задания для однократного выполнения, используя функцию schedule.submit_job(). Для таких заданий используется отдельный набор рабочих процессов в количестве, определённом переменной schedule.max_parallel_workers, и они могут выполняться одновременно с планируемыми заданиями. По умолчанию одновременно могут выполняться два одноразовых задания. Если вы назначите больше заданий, они будут ждать в очереди появления свободного рабочего процесса.

Чтобы выполнить одноразовое задание немедленно, передайте команды SQL в аргументе query. Например:

schedule.submit_job(query := 'select 1');

Вместо того, чтобы передавать параметры запроса SQL непосредственно, вы можете определить в аргументе query нумерованные местозаполнители, например, $1 и $2, и передать в аргументе params массив параметров так, чтобы каждому местозаполнителю соответствовал элемент массива. Для краткости имена параметров query и params можно опустить:

schedule.submit_job(query := 'select $1, $2', params := '{"text 1", "text 2"}')

Чтобы запустить одноразовое задание в определённое время, воспользуйтесь аргументом run_after:

schedule.submit_job('select ''flowers''', run_after := '2017-03-08 08:00:01');

Также вы можете отложить запуск задания до завершения заданий, указанных в аргументе depends_on. Например, чтобы запустить задание после завершения заданий под номерами 23, 15 и 334, выполните:

schedule.submit_job('select ''well done''', depends_on := '{23, 15, 334}')

Если требуется, выполнение задания можно переназначить, вызвав функцию schedule.resubmit() внутри запроса в аргументе query. Например:

schedule.submit_job('select 1, schedule.resubmit(run_after := ''5'')');

Параметр run_after задаёт интервал времени, после которого задание будет перезапущено, в секундах. По умолчанию интервал равен 1 секунде.

Переназначенное задание будет выполняться не больше раз, чем задано в аргументе resubmit_limit. По достижении этого предела задание переходит в состояние done (завершено), с соответствующим сообщением об ошибке.

Если вы хотите отменить переназначенное задание, выполните:

schedule.cancel_job(ид_задания bigint);

Для наблюдения за одноразовыми заданиями воспользуйтесь представлениями pgpro_scheduler job_status и all_job_status.

Все функции, предназначенные для управления одноразовыми заданиями, описаны в Подразделе F.54.5.6.3.

F.54.4.3. Изменение и удаление запланированных заданий #

Когда новое задание создаётся с помощью функции create_job(), оно становится активным и ждёт выполнения по заданному расписанию. Используя идентификатор задания, возвращённый функцией create_job(), вы можете изменить параметры расписания или удалить задание. Для изменения свойств заданий используются функции set_job_attribute() или set_job_attributes():

  • Для изменения одного свойства задания вызовите функцию set_job_attribute(), передав ей в параметрах идентификатор задания, имя изменяемого свойства и новое значение для него.

  • Для изменения сразу нескольких свойств задания воспользуйтесь функцией set_job_attributes(). В этом случае вы можете задать все эти свойства в одном объекте jsonb. Все ключи, которые можно использовать в расписании заданий, рассматриваются в описании функции create_job().

Чтобы временно отключить выполнение задания по расписанию, вызовите функцию deactivate_job():

schedule.deactivate_job(job_id integer)

Повторно активизировать задание позже можно, выполнив функцию activate_job():

schedule.activate_job(job_id integer)

Чтобы безвозвратно удалить задание из планировщика, воспользуйтесь функцией drop_job():

schedule.drop_job(job_id integer)

F.54.4.4. Наблюдение за запланированными заданиями #

Для наблюдения за выполнением заданий в системе в целом необходимо иметь права суперпользователя. Без таких прав можно наблюдать только за заданиями, принадлежащими вам. Для отслеживания запланированных заданий pgpro_scheduler предоставляет ряд функций, которые возвращают записи cron_rec или cron_job:

  • get_job() — выдаёт информацию о задании.

  • get_owned_cron() — выдаёт список заданий, принадлежащих пользователю.

  • get_cron() — выдаёт список заданий, выполняемых пользователем.

  • get_active_jobs() — возвращает список заданий, выполняемых в момент вызова функции.

  • get_log() — возвращает список всех завершённых заданий.

  • get_user_log() — возвращает список завершённых заданий, выполненных указанным пользователем.

  • clean_log() — удаляет все записи с информацией о завершённых заданиях.

Чтобы узнать больше о каждой функции, обратитесь к Подразделу F.54.5.6.

F.54.4.5. Аудит изменений расписания #

Расширение pgpro_scheduler позволяет включить аудит изменений расписания, чтобы выяснить, кто допустил ошибку, если в выполнении запланированных заданий произошли неожиданные изменения.

По умолчанию pgpro_scheduler не сохраняет информацию об изменениях в расписании заданий. Чтобы включить эту возможность, установите для параметра schedule.enable_history значение true. Когда этот параметр включён, pgpro_scheduler сохраняет изменения расписания в таблице schedule.cron__history, а информацию обо всех удалённых заданиях записывает в таблицу schedule.cron__deleted. Сохранённая в этих таблицах история никогда не удаляется, так что суперпользователь может пересмотреть изменения в расписании, внесённые любым пользователем в любой момент времени.

Подробнее сохраняемая информация описывается в Подразделе F.54.5.5.

F.54.4.6. Планирование заданий в кластере multimaster #

Используя pgpro_scheduler, вы можете управлять заданиями по расписанию и одноразовыми заданиями в кластере, настроенном с применением multimaster. pgpro_scheduler может управлять заданиями только на том узле, где он установлен. Таким образом, вы должны установить и включить pgpro_scheduler на всех узлах, где вы хотите планировать задания. Экземпляры pgpro_scheduler на разных узлах будут управлять заданиями независимо, но выполненные задания будут реплицироваться на другие узлы.

Даже если вы намерены планировать задания только на одном узле, pgpro_scheduler рекомендуется развернуть на нескольких узлах. В этом случае, если узел с запланированными заданиями откажет, эти задания возьмёт на себя другой экземпляр pgpro_scheduler. Если pgpro_scheduler работает на нескольких узлах, для выполнения задания выбирается узел с наименьшим идентификатором. Шаблон именования идентификаторов определяется переменной конфигурации schedule.nodename.

F.54.5. Справка #

F.54.5.1. Переменные GUC #

schedule.enabled (boolean) #

Устаревшая переменная. Определяет, включён ли pgpro_scheduler в данной системе.

По умолчанию: false.

Для pgpro_scheduler версии 2.5 или выше вы можете установить параметр schedule.auto_enabled, чтобы pgpro_scheduler включался при запуске сервера, или пользоваться функциями schedule.enable()/schedule.disable(), чтобы включать/отключать его, когда требуется. Проверить, работает ли pgpro_scheduler в данный момент, можно с помощью функции schedule.is_enabled().

schedule.auto_enabled (boolean) #

Определяет, будет ли pgpro_scheduler включаться при запуске сервера.

По умолчанию: false.

schedule.database (text) #

Задаёт базы данных, для которых включён pgpro_scheduler. Имена баз данных должны разделяться запятыми.

По умолчанию: пустая строка.

schedule.database_to_connect (text) #

База данных, к которой подключается pgpro_scheduler, чтобы получить метаданные кластера Postgres Pro Enterprise. Указанную базу данных нельзя удалить, пока работает pgpro_scheduler. Изменить этот параметр можно только при перезапуске сервера.

По умолчанию: postgres.

schedule.schema (text) #

Устаревший параметр. Задаёт имя схемы, в которой планировщик сохраняет свои таблицы и функции. Если вам нужно изменить схему по умолчанию, воспользуйтесь командой ALTER EXTENSION.

По умолчанию: schedule.

schedule.nodename (text) #

Указывает имя узла кластера, на котором работает pgpro_scheduler. Эту переменную не нужно изменять или использовать в конфигурации кластера с одним сервером.

В кластере, где работает multimaster, имя узла оканчивается его идентификатором в конфигурации multimaster. Например, если идентификатор узла равен 3, переменная schedule.nodename получает значение mtm-node-3. Однако если вы явно зададите переменную schedule.nodename в файле postgresql.conf или с помощью команды ALTER, pgpro_scheduler будет использовать заданное значение, не обращая внимания на идентификатор узла.

По умолчанию: primary.

schedule.max_workers (integer) #

Задаёт максимальное число одновременно работающих запланированных по расписанию заданий в одной базе.

По умолчанию: 2.

schedule.max_parallel_workers (integer) #

Задаёт максимальное число параллельных потоков, которые могут использоваться для выполнения одноразовых заданий.

По умолчанию: 2.

schedule.transaction_state (text) #

Внутренняя переменная, содержащая состояние выполняемого задания. pgpro_scheduler использует эту переменную для вычисления времени следующего запуска задания. Возможные значения:

  • success — транзакция завершилась успешно.

  • failure — транзакция завершилась сбоем.

  • running — транзакция в процессе выполнения.

  • undefined — транзакция ещё не запускалась.

В момент выполнения next_time_statement переменная schedule.transaction_state должна содержать либо success (успех), либо failure (сбой). Другие значения указывают на внутреннюю ошибку pgpro_scheduler.

schedule.enable_history (boolean) #

Включает протоколирование всех изменений расписания; при этом фиксируется и время изменения, и имя пользователя, который его внёс. Если добавляется новое задание или изменяется расписание существующего, эта информация сохраняется в таблице schedule.cron__history. Если задание удаляется, информация о нём сохраняется в таблице schedule.cron__deleted. Если вы впоследствии выключите параметр schedule.enable_history, уже записанная история изменений не будет удалена.

По умолчанию: false

F.54.5.2. SQL-схема #

Для размещения своих внутренних таблиц и функций расширение pgpro_scheduler использует SQL-схему schedule. Обращаться к его внутренним таблицам напрямую не следует. Для управления планированием заданий используйте функции, предоставляемые расширением pgpro_scheduler.

F.54.5.3. Типы SQL #

Планировщик pgpro_scheduler определяет следующие типы, используемые некоторыми функциями pgpro_scheduler.

F.54.5.3.1. cron_rec #

Этот тип содержит информацию о запланированном задании.

CREATE TYPE schedule.cron_rec AS(
    id integer,             -- идентификатор задания
    node text,              -- имя узла, на котором
                            -- оно будет выполняться
    name text,              -- имя задания
    comments text,          -- комментарий к заданию
    rule jsonb,             -- правила расписания
    commands text[],        -- SQL-команды, которые будут выполнены
    run_as text,            -- имя пользователя, запускающего задание
    owner text,             -- имя пользователя-владельца задания
    start_date timestamptz, -- нижняя граница окна выполнения задания;
                            -- NULL, если дата начала не ограничена
    end_date timestamptz,   -- верхняя граница окна выполнения задания;
                            -- NULL, если дата окончания не ограничена
    use_same_transaction boolean,   -- true, если набор SQL-команд
                                    -- будет выполняться в одной
                                    -- транзакции
    last_start_available interval,  -- макс. время, на которое может
                                    -- откладываться запуск задания, если
                                    -- нет доступных рабочих процессов
    max_run_time interval,  -- макс. время выполнения
    onrollback text,        -- SQL-команда, которая будет выполнена
                            -- при сбое основной транзакции
    max_instances int,      -- макс. число экземпляров задания, которые
                            -- могут быть запущены одновременно
    next_time_statement text,   -- SQL-оператор, который будет вычислять
                                -- время следующего запуска
    active boolean,         -- true, если задание запланировано
                            -- успешно
    broken boolean          -- true, если в конфигурации задания есть
                            -- ошибки, препятствующие его
                            -- дальнейшему выполнению
);
F.54.5.3.2. cron_job #

Этот тип содержит информацию о выполнении определённого задания.

CREATE TYPE schedule.cron_job AS(
    cron integer,           -- идентификатор задания
    node text,              -- имя узла, на котором
                            -- оно будет выполняться
    scheduled_at timestamptz,       -- запланированное время выполнения
    name text,              -- имя задания
    comments text,          -- комментарий к заданию
    commands text[],        -- SQL-команды, которые будут выполнены
    run_as text,            -- имя пользователя, запускающего задание
    owner text,             -- имя пользователя-владельца задания
    use_same_transaction boolean,   -- true, если набор SQL-команд
                                    -- будет выполняться в одной
                                    -- транзакции
    started timestamptz,    -- время, когда задание было запущено
    last_start_available timestamp, -- макс. время, до которого может
                                    -- откладываться запуск задания, если
                                    -- нет доступных рабочих процессов
    finished timestamptz,   -- время, когда задание было завершено
    max_run_time interval,  -- максимальная длительность выполнения
    onrollback text,        -- SQL-команда, которая будет выполнена
                            -- при сбое основной транзакции
    next_time_statement text,   -- SQL-оператор, который будет вычислять
                                -- время следующего запуска
    max_instances int,      -- макс. число одновременно выполняемых
                            -- экземпляров задания
    status job_status_t,    -- состояние задания: working (выполняется),
                            -- done (завершено), error (ошибка)
    message text            -- сообщение об ошибке
);
F.54.5.3.3. job_status_t #

Тип-перечисление. Может принимать следующие значения:

  • working — задание выполняется.

  • done — выполнение задания завершено.

  • error — выполнение задания завершилось ошибкой.

F.54.5.3.4. job_at_status_t #

Тип-перечисление. Может принимать следующие значения:

  • submitted — задание поступило в очередь, но ещё не начинало выполняться.

  • processing — задание выполняется.

  • done — выполнение задания завершено.

F.54.5.3.5. timetable_job_type_t #

Тип-перечисление. Может принимать следующие значения:

  • periodical — запланированное задание.

  • onetime — одноразовое задание.

F.54.5.3.6. timetable_job_status_t #

Тип-перечисление. Может принимать следующие значения:

  • inprogress — задание выполняется.

  • done — выполнение задания завершено.

  • error — выполнение задания завершилось ошибкой.

  • submitted — задание поступило в очередь, но ещё не начинало выполняться.

F.54.5.4. Представления #

В составе расширения pgpro_scheduler есть несколько представлений для наблюдения за состоянием выполнения одноразовых заданий:

F.54.5.4.1. Представление job_status #

Показывает состояние одноразовых заданий, принадлежащих текущему пользователю.

Таблица F.39. Представление job_status

Имя столбцаТип столбцаОписание
idbigintИдентификатор задания.
nodetextИмя узла, выбранного для выполнения задания.
nametextИмя задания.
commentstextКомментарии к заданию.
run_aftertimestamp with time zoneВремя, после которого должно начаться выполнение задания.
querytextSQL-команды, выполняемые заданием.
paramstext[]Массив параметров для SQL-запроса.
depends_onbigint[]Массив идентификаторов заданий, от которых зависит выполнение данного задания.
run_astextПользователь (или роль), права которого используются для выполнения задания.
attemptbigintЧисло попыток выполнения.
resubmit_limitbigintМаксимально допустимое число переназначений задания.
max_wait_intervalintervalМаксимальный интервал времени, на который может быть отложено выполнение задания, если в назначенное время все доступные рабочие процессы будут заняты.
max_durationintervalИнтервал времени, в течение которого может выполняться задание.
submit_timetimestamp with time zoneВремя, когда задание было добавлено в очередь выполнения.
canceledbooleanОпределяет, было ли задание отменено пользователем.
start_timetimestamp with time zoneВремя, когда началось выполнение задания.
is_successboolean
  • true — задание было выполнено успешно.

  • false — выполнение задания завершилось с ошибками.

errortextСообщение об ошибке.
done_timetimestamp with time zoneВремя, когда завершилось выполнение задания.
statusjob_at_status_tСостояние задания. За подробностями обратитесь к Подразделу F.54.5.3.4.

F.54.5.4.2. Представление all_job_status #

Показывает состояние всех одноразовых заданий. Для обращения к этому представлению необходимо иметь права суперпользователя.

Таблица F.40. Представление all_job_status

Имя столбцаТип столбцаОписание
idbigintИдентификатор задания.
nodetextИмя узла, выбранного для выполнения задания.
nametextИмя задания.
commentstextКомментарии к заданию.
run_aftertimestamp with time zoneВремя, после которого должно начаться выполнение задания.
querytextSQL-команды, выполняемые заданием.
paramstext[]Массив параметров для SQL-запроса.
depends_onbigint[]Массив идентификаторов заданий, от которых зависит выполнение данного задания.
run_astextПользователь (или роль), права которого используются для выполнения задания.
ownertextПользователь, создавший задание.
attemptbigintЧисло попыток выполнения.
resubmit_limitbigintМаксимально допустимое число переназначений задания.
max_wait_intervalintervalМаксимальный интервал времени, на который может быть отложено выполнение задания, если в назначенное время все доступные рабочие процессы будут заняты.
max_durationintervalИнтервал времени, в течение которого может выполняться задание.
submit_timetimestamp with time zoneВремя, когда задание было добавлено в очередь выполнения.
canceledbooleanОпределяет, было ли задание отменено пользователем.
start_timetimestamp with time zoneВремя, когда началось выполнение задания.
is_successboolean
  • true — задание было выполнено успешно.

  • false — выполнение задания завершилось с ошибками.

errortextСообщение об ошибке.
done_timetimestamp with time zoneВремя, когда завершилось выполнение задания.
statusjob_at_status_tСостояние задания. За подробностями обратитесь к Подразделу F.54.5.3.4.

F.54.5.5. Таблицы аудита #

В следующих таблицах сохраняются все изменения расписания, если параметр schedule.enable_history имеет значение true. Если вы впоследствии отключите schedule.enable_history, ранее записанная история изменений сохранится.

F.54.5.5.1. Таблица schedule.cron__history #

В этой таблице регистрируются изменения в расписании заданий. Когда назначается новое задание или изменяется расписание существующего, в эту таблицу добавляется новая строка, содержащая следующую информацию:

  • Вся информация о запланированном задании, которая определена в типе данных cron_rec. Подробнее тип cron_rec описан в Подразделе F.54.5.3.

  • submitter — имя пользователя, изменившего расписание.

  • version_id — уникальный идентификатор, назначаемый каждому изменению в расписании.

  • submit_time — время изменения расписания.

F.54.5.5.2. Таблица schedule.cron__deleted #

В этой таблице регистрируются все задания, удаляемые из расписания:

  • cron — идентификатор удалённого задания.

  • submitter — имя пользователя, удалившего задание.

  • submit_time — время удаления задания.

F.54.5.6. Функции #

pgpro_scheduler предоставляет два отдельных набора функций для управления заданиями, выполняемыми по расписанию, и одноразовыми заданиями, а также несколько функций общего назначения для включения/отключения расширения pgpro_scheduler в вашей базе данных и отображения его текущего состояния:

Важно

Для конкретного задания можно использовать только те функции, которые предназначены для данного типа задания.

F.54.5.6.1. Функции общего назначения #

Эти функции предназначены для управления расширением pgpro_scheduler.

schedule.enable() #

Включает pgpro_scheduler для текущего экземпляра Postgres Pro Enterprise.

Возвращаемые значения:

  • true, если планировщик pgpro_scheduler включён и готов к использованию.

  • false, если выполнить команду не удалось.

schedule.is_enabled() #

Проверяет, работает ли pgpro_scheduler.

Возвращаемые значения:

  • true, если планировщик pgpro_scheduler включён и готов к использованию.

  • false, если планировщик pgpro_scheduler в настоящее время не работает.

schedule.disable() #

Отключает pgpro_scheduler для текущего экземпляра Postgres Pro Enterprise.

Возвращаемые значения:

  • true, если планировщик pgpro_scheduler отключён.

  • false, если выполнить команду не удалось.

schedule.start() #

Запускает pgpro_scheduler для текущей подключённой базы данных.

Возвращаемые значения:

  • truepgpro_scheduler запущен успешно.

  • false — в случае сбоя команды или если pgpro_scheduler уже запущен.

schedule.stop() #

Останавливает pgpro_scheduler для текущей подключённой базы данных.

Возвращаемые значения:

  • truepgpro_scheduler остановлен.

  • false — в случае сбоя команды или если pgpro_scheduler не работает.

schedule.status() #

Возвращает состояние фоновых рабочих процессов pgpro_scheduler:

  • pid — идентификатор фонового рабочего процесса. Если этот идентификатор равен NULL, фоновый рабочий процесс не работает.

  • database — имя базы данных, к которой подключён фоновый рабочий процесс.

  • type — тип фонового рабочего процесса:

    • supervisor — распределяет запланированные задания между базами данных.

    • database manager распределяет запланированные задания внутри базы данных.

    • cron job executor выполняет задания по графику.

    • at job executor выполняет разовые задания.

schedule.version() #

Возвращает версию pgpro_scheduler.

F.54.5.6.2. Функции для управления планируемыми заданиями #
schedule.create_job(options jsonb) #

Создаёт активное задание и возвращает его идентификатор.

Альтернативный синтаксис:

schedule.create_job(cron text, commands text [, node text])
schedule.create_job(cron text, commands text[] [, node text])
schedule.create_job(dates timestamp with time zone, commands text [, node text])
schedule.create_job(dates timestamp with time zone, commands text[] [, node text])
schedule.create_job(dates timestamp with time zone[], commands text [, node text])
schedule.create_job(dates timestamp with time zone[], commands text[] [, node text])

Аргументы:

  • options — объект jsonb, определяющий все свойства задания. Если задаётся параметр data, никакие другие параметры определять не нужно. Все поддерживаемые ключи jsonb перечислены в Таблице F.41.

    Type: jsonb

  • cron — строка в стиле crontab, задающая график выполнения.

    Тип: text

  • dates — точная дата или массив дат для выполнения задания.

    Тип: timestamp with time zone, timestamp with time zone[]

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

    Тип: text, text[]

  • node — имя узла, на котором выполняются запланированные задания. Этот аргумент может понадобиться при планировании заданий в кластере с несколькими ведущими серверами.

    Тип: text

Возвращаемые значения:

  • Идентификатор созданного задания.

Таблица F.41. Ключи jsonb, предназначенные для планирования заданий

КлючТипОписание
crontext

Строка в стиле crontab, определяющая график выполнения. Она может иметь традиционный формат crontab с пятью полями или расширенный, с шестью (в нём первое поле содержит секунду). Ключ cron можно комбинировать с ключами rule и dates, но нельзя опустить их все. Также вместо строки crontab можно указать одно из следующих слов, определяющих, когда будет запускаться задание:

  • @every_second — каждую секунду

  • @hourly — в начале каждого часа

  • @daily — в начале каждого дня

  • @midnight — в начале каждого дня

  • @weekly — в начале каждой недели

  • @monthly — в начале каждого месяца

  • @yearly — в начале каждого года

  • @annually — в начале каждого года

datestimestamp with time zone, timestamp with time zone[]Точная дата или массив дат, когда должно выполняться запланированное задание. Ключ dates можно комбинировать с ключами rule и cron, но нельзя опустить их все.
rulejsonb

Объект jsonb, определяющий расписание задания. Обязательный ключ, если ключи cron и dates не определены. Объект rule содержит один или несколько из следующих ключей:

  • seconds — секунды; массив целых чисел в диапазоне [0, 59]

  • minutes — минуты; массив целых чисел в диапазоне [0, 59]

  • hours — часы; массив целых чисел в диапазоне [0, 23]

  • days — дни месяца; массив целых чисел в диапазоне [1, 31]

  • months — месяцы; массив целых чисел в диапазоне [1, 12]

  • wdays — дни недели; массив целых чисел в диапазоне [0, 6], где 0 — воскресенье.

  • onstart — целое значение 0 или 1. Если для onstart задано значение 1, задание выполняется только один раз при запуске pgpro_scheduler.

commandstext, text[]SQL-операторы, которые будут выполняться. Вы можете передать в этом параметре один или несколько SQL-параметров через точку с запятой либо массив SQL-операторов. SQL-операторы, передаваемые в массиве, по умолчанию будут выполняться в отдельных транзакциях. Изменить это поведение позволяет ключ use_same_transaction.
nametextНеобязательное свойство. Имя задания.
nodetextНеобязательное свойство. Имя узла, на котором выполняются запланированные задания. Этот аргумент может понадобиться при планировании заданий в кластере с несколькими ведущими серверами.
commentstextНеобязательные комментарии к запланированному заданию.
run_astextНеобязательное свойство. Пользователь, от имени которого будет выполняться задание.
start_datetimestamp with time zoneНеобязательное свойство. Начало интервала, в котором возможно выполнение задания. Может содержать NULL.
end_datetimestamp with time zoneНеобязательное свойство. Конец интервала, в котором возможно выполнение задания. Может содержать NULL.
use_same_transactionbooleanНеобязательное свойство. Если равняется true, устанавливает, что SQL-операторы, переданные в массиве, будут выполняться в одной транзакции. По умолчанию: false
last_start_availableintervalНеобязательное свойство. Максимальное время, на которое может быть отложено выполнение задания, если в запланированный момент все рабочие процессы оказались заняты. Например, если задать в этом ключе '00:02:34', задание будет ждать выполнения 2 минуты 34 секунды. Если значение этого ключа — NULL, задание будет ожидать выполнения вечно. Значение по умолчанию: NULL.
max_instancesinteger

Необязательное свойство. Максимальное число экземпляров одного задания, которые могут выполняться одновременно. По умолчанию: 1.

Для заданий cron с установленным next_time_statement значение max_instances всегда должно быть равно 1.

max_run_timeintervalНеобязательное свойство. Максимальное время, в течение которого может выполняться запланированное задание. Если значение этого ключа — NULL или не установлено, ограничение по времени отсутствует. Значение по умолчанию: NULL.
onrollbacktextНеобязательное свойство. SQL-оператор, который будет выполняться при сбое основной транзакции.
next_time_statementtextНеобязательное свойство. SQL-оператор, который будет вычислять время следующего запуска задания. Подробнее об этом рассказывается в Подразделе F.54.4.1.3.

schedule.set_job_attributes(job_id integer, data jsonb) #

Изменяет свойства существующего задания.

Аргументы:

  • job_id — идентификатор существующего задания.

  • data — объект jsonb с набором изменяемых свойств. Список ключей с описанием их структуры приведён в Таблице F.41.

Возвращаемые значения:

  • true — свойства задания изменены успешно.

  • false — свойства задания не были изменены.

Чтобы изменить свойства задания, необходимо быть его владельцем или иметь права суперпользователя.

schedule.set_job_attribute(job_id integer, name text, value text || anyarray) #

Изменяет свойство существующего задания.

Аргументы:

  • job_id — идентификатор существующего задания.

  • name — имя свойства.

  • value — значение свойства.

Список изменяемых свойств заданий приведён в Таблице F.41. Некоторые свойства представляются массивами и они должны передаваться как массивы. Если передать для свойства значение неверного типа, будет выдано исключение.

Возвращаемые значения:

  • true — свойство задания изменено успешно.

  • false — свойство задания не было изменено.

Чтобы изменить свойства задания, необходимо быть его владельцем или иметь права суперпользователя.

schedule.deactivate_job(job_id integer) #

Деактивирует задание и приостанавливает его последующее выполнение.

Аргументы:

  • job_id — идентификатор существующего задания.

Возвращаемые значения:

  • true — задание было деактивировано успешно.

  • false — деактивировать задание не удалось.

schedule.activate_job(job_id integer) #

Активирует задание, в результате чего оно начинает выполняться по расписанию.

Аргументы:

  • job_id — идентификатор существующего задания.

Возвращаемые значения:

  • true — задание активировано успешно.

  • false — активировать задание не удалось.

schedule.drop_job(job_id integer) #

Удаляет задание.

Аргументы:

  • job_id — идентификатор существующего задания.

Возвращаемые значения:

  • true — задание было удалено успешно.

  • false — задание не было удалено.

schedule.get_job(job_id integer) #

Возвращает информацию об указанном задании.

Аргументы:

  • job_id — идентификатор существующего задания.

Возвращаемые значения:

  • Объект типа cron_rec.

Описание типа cron_rec можно найти в Подразделе F.54.5.3.

schedule.get_owned_cron(username text) #

Получает список заданий, принадлежащих указанному пользователю.

Аргументы:

  • username — имя пользователя, может отсутствовать.

Возвращаемые значения:

  • Набор записей типа cron_rec. Эти записи содержат информацию обо всех заданиях, принадлежащих указанному пользователю. Если параметр username опущен, подразумевается имя текущего пользователя сеанса. Получать задания, принадлежащие другому пользователю, может только суперпользователь.

Описание типа cron_rec можно найти в Подразделе F.54.5.3.

schedule.get_cron() #

Получает список заданий, выполняемых пользователем сеанса.

Возвращаемые значения:

  • Набор записей типа cron_rec. Эти записи содержат информацию обо всех заданиях, выполняемых пользователем сеанса. Получать задания может только суперпользователь.

Описание типа cron_rec можно найти в Подразделе F.54.5.3.

schedule.get_active_jobs(username text) #

Получает список заданий, в настоящее время выполняемых указанным пользователем.

Аргументы:

  • username — имя пользователя, может отсутствовать.

Если параметр username опущен, подразумевается имя текущего пользователя сеанса. Получать задания, выполняемые другим пользователем, может только суперпользователь.

Возвращаемые значения:

  • Набор записей типа cron_job.

Описание типа cron_job можно найти в Подразделе F.54.5.3.

schedule.get_active_jobs() #

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

Возвращаемые значения:

  • Набор записей типа cron_job.

Описание типа cron_job можно найти в Подразделе F.54.5.3.

schedule.get_log() #

Возвращает список всех завершённых заданий. Вызывать эту функцию может только суперпользователь.

Возвращаемые значения:

  • Набор записей типа cron_job.

Описание типа cron_job можно найти в Подразделе F.54.5.3.

schedule.get_user_log(username text) #

Возвращает список завершённых заданий, выполненных указанным пользователем.

Аргументы:

  • username — имя пользователя, может отсутствовать.

Если параметр username опущен, подразумевается имя текущего пользователя сеанса. Получать список заданий, выполненных другим пользователем, может только суперпользователь.

Возвращаемые значения:

  • Набор записей типа cron_job.

Описание типа cron_job можно найти в Подразделе F.54.5.3.

schedule.clean_log() #

Удаляет все записи с информацией о завершённых заданиях. Вызывать эту функцию может только суперпользователь.

Возвращаемые значения:

  • Число удалённых записей.

schedule.nodename() #

Возвращает имя текущего узла.

F.54.5.6.3. Функции для управления одноразовыми заданиями #
schedule.submit_job(query text [параметры...]) #

Назначает задания для немедленного или отложенного однократного выполнения. По умолчанию задание назначается для немедленного выполнения и оно может выполняться одновременно с другими запланированными заданиями. Чтобы назначить задание с отсроченным запуском, время запуска можно задать в аргументе run_after или передать в аргументе depends_on массив идентификаторов некоторых заданий для запуска данного задания сразу после их завершения.

Аргументы:

  • querySQL-команды, которые будут выполнены.

    Тип: text

  • params — массив параметров для SQL-запроса, которые могут подменять нумерованные местозаполнители в аргументе query, например, $1, $2 и т. д. По умолчанию: NULL

    Type: text[]

  • run_after — время, после которого начнётся выполнение задания. Если в этом аргументе передаётся NULL, задание будет выполнено немедленно. Чтобы отложить запуск задания, также можно задать аргумент depends_on. По умолчанию: NULL

    Тип: timestamp with time zone

  • node — имя узла, на котором будет выполняться задание. По умолчанию: NULL

    Тип: text

  • max_duration — максимальное время, в течение которого может выполняться это задание. Если заданное ограничение превышается, задание останавливается принудительно. Если в этом аргументе передаётся NULL или он опускается, продолжительность выполнения не ограничивается. По умолчанию: NULL

    Тип: interval

  • max_wait_interval — максимальное время, на которое может быть отложено выполнение задания, если в запланированный момент все рабочие процессы оказались заняты. Например, если задать в этом ключе '00:02:34', задание будет ждать выполнения 2 минуты 34 секунды. Если значение этого ключа — NULL или не определено, задание может ожидать выполнения вечно. По умолчанию: NULL

    Тип: interval

  • run_as — пользователь (или роль), права которого используются для выполнения задания. Если в run_as передаётся NULL, задание выполняется с правами текущего пользователя. Чтобы задать этот аргумент, необходимо иметь права суперпользователя. По умолчанию: NULL

    Тип: text

  • depends_on — массив идентификаторов заданий. Созданное задание будет запущено сразу после того, как будут завершены все указанные задания. Этот аргумент является альтернативой параметру run_after. По умолчанию: NULL

    Тип: bigint[]

  • name — имя задания. По умолчанию: NULL

    Тип: text

  • comments — комментарии к заданию.

    Тип: text

  • resubmit_limit — максимальное число раз, которое задание может назначаться повторно. За подробностями обратитесь к описанию функции schedule.resubmit(). По умолчанию: 100

    Тип: bigint

Возвращаемые значения:

  • Идентификатор созданного задания.

    Тип: bigint

schedule.get_self_id() #

Возвращает идентификатор задания, в контексте выполнения которого вызывается эта функция. Возвращаемый идентификатор имеет тип bigint. Эта функция должна вызываться в запросе, задаваемом в параметре query функции schedule.submit_job(). Если вызвать её иначе, возникает исключение.

Возвращаемые значения:

  • Идентификатор задания.

schedule.cancel_job(job_id bigint) #

Отменяет все последующие запуски указанного задания. Если задание уже выполняется, оно не будет прервано, но повторно назначить его будет нельзя. Чтобы вызывать эту функцию, необходимо быть владельцем задания или иметь права суперпользователя.

Аргументы:

  • job_id — идентификатор задания, которое нужно отменить.

Возвращаемые значения:

  • true, если операция завершена успешно.

  • false, если выполнить операцию не удалось.

schedule.resubmit(run_after interval default NULL) #

Задаёт время запуска для следующего выполнения задания, без прерывания текущего выполнения. Эта функция должна вызываться внутри запроса, задаваемого в аргументе query функции schedule.submit_job(). В другом контексте она выдаёт исключение. Если эта функция вызывается несколько раз в процессе выполнения одного задания, решающим будет последний вызов функции.

Аргументы:

  • run_after — интервал времени, после которого задание будет повторно назначено для выполнения. Если указан положительный временной интервал меньше секунды, то он округляется до 1 секунды. Интервалы более 1 секунды округляются до целых значений. Если передаётся 0, задание перезапускается сразу после выполнения. По умолчанию: 1 секунда

    Тип: interval

Возвращаемые значения:

  • Число секунд, после которого задание будет повторно назначено для выполнения.

F.54.5.6.4. Функции очистки #

При большом количестве одноразовых заданий таблица выполненных одноразовых заданий может стремительно разрастаться. Для очистки таблицы в pgpro_scheduler предусмотрены следующие одноимённые функции с разными типами аргументов:

schedule.clean_at_jobs_done(older_than interval, delete_failed_tasks boolean, default NULL)
schedule.clean_at_jobs_done(older_than timestamp with time zone, delete_failed_tasks boolean, default NULL)

Удалить все записи в таблице выполненных одноразовых заданий, которые старше либо указанной временной метки, либо заданного интервала относительно текущего времени.

Аргументы:

  • older_than — интервал или временная метка для очистки. Записи старше этого значения будут удалены.

    Тип: interval, timestamp with time zone

  • delete_failed_tasks определяет, нужно ли удалять задания, завершившиеся с ошибкой. Значение по умолчанию — false.

    Тип: boolean

Возвращаемые значения:

  • Число удалённых записей.

Эти функции можно вызвать вручную или запланировать их выполнение с помощью заданий cron в интерфейсе pgpro_scheduler.

F.54.5.6.5. Функции для управления планируемыми и одноразовыми заданиями #
schedule.timetable(start_time timestamp with time zone, end_timetimestamp with time zone) #

Возвращает таблицу, описывающую все запланированные выполнения заданий (многократно повторяемых и одноразовых), попадающие в заданный интервал.

Таблица F.42. Столбцы schedule.timetable

Имя столбцаТип столбцаОписание
idbigintИдентификатор задания, уникальный среди заданий этого типа.
typetimetable_job_type_tТип задания. За подробностями обратитесь к Подразделу F.54.5.3.5.
nodetextИмя узла, выбранного для выполнения задания.
nametextИмя задания.
commentstextКомментарии к заданию.
commandstext[]Массив SQL-команд, выполняемых заданием.
scheduled_attimestamp with time zoneВремя, на которое запланировано выполнение задания.
start_timetimestamp with time zoneВремя, когда началось выполнение задания.
done_timetimestamp with time zoneВремя, когда завершилось выполнение задания.
statustimetable_job_status_tСостояние задания. За подробностями обратитесь к Подразделу F.54.5.3.6.
errortextСообщение об ошибке.

F.54.6. Авторы #

Postgres Professional, Москва, Россия

F.54. pgpro_scheduler — scheduling, monitoring and managing job execution #

pgpro_scheduler is a built-in Postgres Pro Enterprise extension for scheduling, monitoring, and managing job execution within the Postgres Pro Enterprise database. With pgpro_scheduler, you can:

  • Set advanced schedules using jsonb objects or crontab strings.

  • Dynamically calculate the next execution time for repeated jobs.

  • Execute SQL commands of the job in a single transaction or in sequential transactions, if required.

  • Submit jobs for immediate or delayed one-time execution in parallel with the scheduled jobs.

Unlike external scheduling daemons, pgpro_scheduler offers the following benefits:

  • Any user can schedule jobs independently.

  • Job scheduling can be managed on the fly without restarting the database.

  • Scheduling is very lightweight since pgpro_scheduler uses background workers to schedule, monitor, and manage job execution. At the same time, pgpro_scheduler does not require any client connections for scheduling.

  • For enhanced stability, each database has its own supervisor scheduler, with each scheduled job executed by a separate background worker.

Note

pgpro_scheduler waits in the suspended state on a standby server to be started when the standby is promoted to a primary server.

Note

Note that for all the executed jobs, the pg_stat_activity view will still show the name of the database superuser, which is used by the background worker.

F.54.1. Installation and Setup #

The pgpro_scheduler extension is included into Postgres Pro Enterprise. Once you have Postgres Pro Enterprise installed, complete the following steps to enable pgpro_scheduler:

  1. Add pgpro_scheduler to the shared_preload_libraries parameter in the postgresql.conf file:

    shared_preload_libraries = 'pgpro_scheduler'
    
  2. Create the pgpro_scheduler extension using the following query:

    CREATE EXTENSION pgpro_scheduler;
    

    Make sure to create the pgpro_scheduler extension for each database you are planning to use.

Once you complete the installation and setup, configure pgpro_scheduler for your database.

F.54.2. Configuration #

You must have superuser rights to configure pgpro_scheduler.

To configure pgpro_scheduler, modify the following settings in the postgresql.conf file:

  1. Specify the names of the databases for which you need to schedule jobs, in the comma-separated format:

    schedule.database = 'database1,database2'
    

  2. To control the workload in your system, set the maximum number of background workers that can run simultaneously on each database:

    schedule.max_workers = 5
    
  3. Optionally, set the number of background workers available for one-time job execution:

    schedule.max_parallel_workers = 3
    

    By default, two background workers for one-time jobs are available. These workers are not included into the schedule.max_workers number. Thus, one-time jobs can run in parallel with the scheduled jobs even if all the schedule.max_workers workers are busy.

  4. Run pg_reload_conf() for the changes to take effect:

    SELECT pg_reload_conf();
    

Important

When setting the schedule.max_workers, schedule.max_parallel_workers, and schedule.database variables, make sure that enough background workers remain available from the total pool of workers established by max_worker_processes. Other Postgres Pro subsystems may also use background workers.

For detailed instructions on calculating the required number of background workers and for configuration examples, see Section F.54.3.

pgpro_scheduler background workers support resource prioritization. You can assign resource usage weight to scheduled jobs using specific configuration parameters. For more details, refer to pgpro_rp.

You can also dynamically configure pgpro_scheduler from the command line. In this case, you can set different number of workers for different databases:

ALTER SYSTEM SET schedule.database = 'database1,database2';
ALTER DATABASE database1 SET schedule.max_workers = 5;
ALTER DATABASE database2 SET schedule.max_workers = 3;
ALTER SYSTEM SET schedule.max_parallel_workers = 3;
SELECT pg_reload_conf();

Once pgpro_scheduler is configured, enable it on your system, as follows:

SELECT schedule.enable();

If this function returns true, pgpro_scheduler is ready to use, and you can start scheduling jobs as explained in Section F.54.4.1 and Section F.54.4.2.

Note

If you restart the server, pgpro_scheduler is not automatically restarted by default. To change this behavior, you can set the schedule.auto_enabled parameter to on.

See Also

Section F.54.5.1

F.54.3. Calculating Required Background Workers #

To calculate the maximum number of background workers used by the pgpro_scheduler extension, use the following formula:

1 + N * (1 + schedule.max_workers + schedule.max_parallel_workers)

  • 1: The global supervisor worker for the pgpro_scheduler extension.

  • N: The number of databases listed in the schedule.database parameter. Each database runs its own database manager and other background workers.

  • schedule.max_workers: The maximum number of background workers for scheduled jobs.

  • schedule.max_parallel_workers: The maximum number of background workers for one-time jobs.

Note that this formula calculates the total number of background workers required for the general configuration based on the global default values set using ALTER SYSTEM. To optimize performance and to meet task-specific requirements, tune the schedule.max_workers and schedule.max_parallel_workers parameters for each database listed in schedule.database and include these values in the total worker count.

The max_worker_processes parameter must provide worker processes for both pgpro_scheduler and other Postgres Pro subsystems. Before using pgpro_scheduler for the first time, increase max_worker_processes by the value obtained from the formula above. Adjust this parameter whenever you modify the pgpro_scheduler configuration.

For example, if you work with two databases and set schedule.max_workers to 5 and schedule.max_parallel_workers to 3, pgpro_scheduler may use up to 1 + 2 * (1 + 5 + 3) = 19 background workers. Consequently, you should increase the max_worker_processes value by 19.

Consider a more complex example: you decide to enable the extension for a third database. You configure the parameters as follows:

  • For the third database, set schedule.max_parallel_workers to 2 and keep its schedule.max_workers set to 5 (default).

  • For the second database, set schedule.max_workers to 2.

In this case, the total number of workers required for pgpro_scheduler would be:

1 + (1 + 5 + 3) + (1 + 2 + 3) + (1 + 5 + 2) = 24

You would also need to increase the max_worker_processes value by additional 5 workers (24 - 19 = 5).

If all background workers within this pool are busy, jobs will wait for the next available worker. This can lead to delays in the execution of scheduler jobs. Scheduled and one-time jobs are placed into separate queues to manage their execution.

If required, you can later change the number of workers. To check the extension status, use the schedule.status() function. If you see jobs in the submitted state, verify that enough background workers are allocated.

Changes to the schedule.max_workers and schedule.max_parallel_workers parameters do not affect the running jobs.

F.54.4. Usage #

F.54.4.1. Creating Scheduled Jobs #

To create and schedule a job, run the create_job() function that takes scheduling options as a jsonb object:

schedule.create_job(options jsonb)

In the jsonb object, you must specify one or more SQL commands in the commands key, and set the job schedule with at least one of the following keys:

  • dates — a single date or an array of dates, in the timestamp with time zone format

  • cron — a string, in the crontab format. A traditional five-field crontab format is used. The first field stands for minute, the second — for hour, the third — for day of the month, the fourth — for month, and the fifth — for day of the week.

    ┌── minute (0 - 59)
    │ ┌─── hour (0 - 23)
    │ │ ┌─── day of the month (1 - 31)
    │ │ │ ┌──── month (1 - 12)
    │ │ │ │ ┌──── day of the week (0 - 6) (Sunday to Saturday)
    │ │ │ │ │
    * * * * *
    

    A six-field crontab format can be used alongside the traditional five-field format. In this case the first field stands for second. When you use the six-field format and do not want to specify a second you have to put 0 in the first field.

    Alternatively, the following keywords can be used instead of a crontab string to specify when the job will be started:

    • @every_second — each second

    • @hourly — at the beginning of each hour

    • @daily — at the beginning of each day

    • @midnight — at the beginning of each day

    • @weekly — at the beginning of each week

    • @monthly — at the beginning of each month

    • @yearly — at the beginning of each year

    • @annually — at the beginning of each year

  • rule — a jsonb object that includes one or more of the following keys:

    • seconds — seconds; an array of integers in range [0, 59]

    • minutes — minutes; an array of integers in range [0, 59]

    • hours — hours; an array of integers in range [0, 23]

    • days — days of the month; an array of integers in range [1, 31]

    • months — months; an array of integers in range [1, 12]

    • wdays — days of the week; an array of integers in range [0, 6], where 0 is Sunday.

    • onstart — integer value 0 or 1. If onstart is set to 1, the job is executed only once when pgpro_scheduler is started.

You can combine dates, cron, and rule scheduling keys for advanced use cases.

As a result, pgpro_scheduler creates an active job with the specified schedule and returns the job ID.

Tip

For simple job schedules, you can use the following shortcut syntax:

schedule.create_job(cron, commands)
schedule.create_job(dates, commands)

For details, see schedule.create_job() function description.

If required, you can later modify one or more scheduling options with the set_job_attribute() or set_job_attributes() functions, respectively.

If all background workers are busy at the specified time, the job waits for the next available worker. By default, the job can wait forever. You can limit the maximum wait time by setting the last_start_available key, in the time interval format. If the timeout is reached, pgpro_scheduler cancels the job execution.

Examples:

To run the job every day at 3pm, and, additionally, on December 31, 2017 at 7pm , and on April 4, 2020 at 1pm:

SELECT schedule.create_job('{"commands": "SELECT 15", "cron": "0 15 * * *", "dates": [ "2017-12-31 19:00", "2020-04-04 13:00" ]}');

To limit the wait time for job execution to 30 seconds after the scheduled time:

SELECT schedule.create_job('{"commands": "SELECT pg_sleep(100)", "cron": "15 */2 * * *", "last_start_available": "30 seconds" }');

Note

Both for scheduled and one-time jobs, you cannot manage their main transactions, namely using COMMIT and ROLLBACK. However, you can create and manage autonomous transactions.

F.54.4.1.1. Specifying the Time Window for Job Execution #

In addition to the general schedule, you can specify the timeframe during which the scheduled job can be executed. To ensure that pgpro_scheduler only executes the job within the specified time window, define the start_date and end_date keys, in the timestamp with time zone format. You can set one of these keys only to limit the start or the end time, respectively. If you define a time window for the job, pgpro_scheduler will only schedule this job within this time window. If the started job is incomplete when the specified time window ends, pgpro_scheduler completes the job and then excludes the job from further scheduling.

Examples:

To start scheduling the job only after 11am on May 1, 2017:

SELECT schedule.create_job('{"commands": "SELECT now()", "cron": "2 17 * * *", "start_date": "2017-05-01 11:00" }');

To schedule the job in the timeframe from 11am on May 1 to 3pm on June 4, 2017:

SELECT schedule.create_job('{"commands": "SELECT now()", "cron": "2 17 * * *", "start_date": "2017-05-01 11:00", "end_date": "2017-06-04 15:00" }');

F.54.4.1.2. Running SQL Commands in Separate Transactions #

The commands key can have values of text and array types. If you specify several SQL commands as text separated by semicolons, the whole job is executed in a single transaction. If it is critical to perform each SQL command in a separate transaction, pass the SQL commands as an array. You can modify this behavior by setting the use_same_transaction key to true. In this case, SQL commands in the array are executed in a single transaction.

Examples:

To run the whole job in a single transaction:

SELECT schedule.create_job('{"commands": "SELECT 1; SELECT 2; SELECT 3;", "cron": "23 23 */2 * *" }');

To run commands in separate transactions:

SELECT schedule.create_job('{"commands": [ "SELECT 1", "SELECT 2", "SELECT 3" ], "cron": "23 23 */2 * *" }');

To run the whole job in a single transaction when passing the commands as an array:

SELECT schedule.create_job('{"commands": [ "SELECT 1", "SELECT 2", "SELECT 3" ], "cron": "23 23 */2 * *", "use_same_transaction": true }');

F.54.4.1.3. Calculating the Next Start Time of the Scheduled Job #

For repeated jobs, the next start time can be computed by an SQL statement specified in the next_time_statement key. In this case, the first job starts on schedule, while all the successive job runs occur at the computed times.

After the job run completes, pgpro_scheduler executes the SQL statement in the next_time_statement key to calculate the next start time and returns the result, in the timestamp with time zone type. If the return value is of a different type or an error occurs, pgpro_scheduler marks the job as broken and cancels any further execution. This process is repeated for each successive job run.

Tip

When the job run completes, pgpro_scheduler sets the transaction state in the schedule.transaction_state variable, in the text format. You can use this variable in your next_time_statement to dynamically calculate the next start time depending on the transaction state. At the time of the next_time_statement execution, the schedule.transaction_state variable must contain either success or failure state values for the main transaction. Other values may indicate an internal pgpro_scheduler error.

Examples:

To run the job first at 10:45, and then in a day after the job completes:

SELECT schedule.create_job('{"commands": "SELECT random()", "cron": "45 10 * * *", "next_time_statement": "SELECT now() + ''1 day''::interval" }');

F.54.4.1.4. Setting Additional Conditions for Job Execution #

The pgpro_scheduler extension enables you to define additional conditions for task execution:

  • Set time limits for job execution with the max_run_time key. If the execution time is exceeded, pgpro_scheduler cancels the job.

  • Define the maximum time a scheduled job can wait for execution using the last_start_available key. If the timeout is reached, pgpro_scheduler cancels the job.

  • Schedule a job to be executed with the rights of another user by specifying the run_as key. You must have superuser rights to use this key.

  • Define an SQL command to execute if the main command fails using the onrollback key.

Examples:

To limit job execution to 5 seconds:

SELECT schedule.create_job('{"commands": "SELECT pg_sleep(10)", "cron": "15 */10 * * *", "max_run_time": "5 seconds" }');

To limit the wait time for job execution to 30 seconds after the scheduled time:

SELECT schedule.create_job('{"commands": "SELECT pg_sleep(100)", "cron": "15 */2 * * *", "last_start_available": "30 seconds" }');

To start the job with the rights of the robot user:

SELECT schedule.create_job('{"commands": "SELECT session_user", "cron": "5 */5 * * *", "run_as": "robot" }');

To define a fallback SQL command in case the main command fails:

SELECT schedule.create_job('{"commands": "SELECT ''zzz''", "cron": "55 */12 * * *", "onrollback": "SELECT ''Cannot select zzz''" }');

F.54.4.2. Submitting One-Time Jobs #

You can submit jobs for one-time execution using the schedule.submit_job() function. Such jobs use a separate pool of background workers defined by the schedule.max_parallel_workers variable, and can run in parallel with the scheduled jobs. By default, two one-time jobs can run concurrently. If you submit more jobs, they will wait in the queue for the next available background worker.

To execute a one-time job immediately, pass SQL commands in the query argument. For example:

schedule.submit_job(query := 'select 1');

Instead of passing SQL query parameters directly, you can define numbered placeholders in the query argument, such as $1 and $2, and pass an array of parameters in the params argument, with each array element corresponding to a placeholder. For brevity, you can omit the query and params names:

schedule.submit_job(query := 'select $1, $2', params := '{"text 1", "text 2"}')

To start a one-time job at the specified time, use the run_after argument:

schedule.submit_job('select ''flowers''', run_after := '2017-03-08 08:00:01');

Alternatively, you can delay the job start until the specified jobs are complete using the depends_on argument. For example, to run a job after completing the jobs with 23, 15, and 334 IDs, run:

schedule.submit_job('select ''well done''', depends_on := '{23, 15, 334}')

If required, you can repeat the job execution by passing the schedule.resubmit() function as part of the query argument. For example:

schedule.submit_job('select 1, schedule.resubmit(run_after := ''5'')');

The run_after argument specifies the time interval before the job is restarted, in seconds. By default, the interval is 1 second.

The resubmitted job cannot be executed more than the number of times set in the resubmit_limit argument. If this limit is reached, the job receives the done status, with the corresponding error message.

If you want to cancel a resubmitted job, run:

schedule.cancel_job(job_id bigint);

To monitor one-time jobs, use the job_status and all_job_status pgpro_scheduler views.

For details on all the functions available for managing one-time jobs, see Section F.54.5.6.3.

F.54.4.3. Changing and Removing Scheduled Jobs #

When you create a new job with the create_job() function, the job becomes active and waits for execution based on the specified schedule. Using the job ID returned by the create_job() function, you can change the scheduling settings or remove the job from the schedule. To change the specified schedule for the jobs, use set_job_attribute() or set_job_attributes() functions:

  • To modify a single property of the job, run the set_job_attribute() function with the job ID, the property name to change, and the new value for this property.

  • To modify more than one property of the job, run the set_job_attributes() function instead. In this case, you can specify all the job properties at once in a jsonb object. For details on all the keys available for job scheduling, see the create_job() function description.

To temporarily exclude the job from scheduling, run the deactivate_job() function:

schedule.deactivate_job(job_id integer)

You can re-activate the job later by running the activate_job() function:

schedule.activate_job(job_id integer)

To permanently remove the job from the schedule, run the drop_job() function:

schedule.drop_job(job_id integer)

F.54.4.4. Monitoring Scheduled Jobs #

You must have superuser rights to monitor job execution for the whole system. Otherwise, you can only monitor the jobs that you own. To monitor scheduled jobs, pgpro_scheduler provides multiple functions that return cron_rec or cron_job records:

  • get_job() — retrieves information about the job.

  • get_owned_cron() — retrieves the list of jobs owned by user.

  • get_cron() — retrieves the list of jobs executed by user.

  • get_active_jobs() — returns the list of jobs executed at the moment of the function call.

  • get_log() — returns the list of all completed jobs.

  • get_user_log() — returns list of the completed jobs executed by the specified user.

  • clean_log() — deletes all records with information about completed jobs.

To learn more about each function, see Section F.54.5.6.

F.54.4.5. Auditing Job Scheduling #

pgpro_scheduler enables you to audit job scheduling to rule out human error if you observe unexpected changes in scheduled job execution.

By default, pgpro_scheduler does not store information on schedule changes. To enable this feature, set the schedule.enable_history parameter to true. Once this parameter is enabled, pgpro_scheduler stores schedule modifications in the schedule.cron__history table, and logs all deleted jobs in the schedule.cron__deleted table. Logged history is never deleted from these tables, so a superuser can review schedule changes introduced by all users at any time.

For details on logged information, see Section F.54.5.5.

F.54.4.6. Scheduling Jobs on a Multi-Master Cluster #

Using pgpro_scheduler, you can manage scheduled and one-time jobs on a cluster configured with multimaster. pgpro_scheduler can only manage jobs on the node on which it is installed. Thus, you must install and enable pgpro_scheduler on all nodes on which you would like to schedule jobs. pgpro_scheduler instances will manage jobs on different nodes independently, but the executed jobs will be replicated to other nodes.

Even if you are planning to schedule jobs on a single node only, it is recommended to enable pgpro_scheduler on several nodes. In this case, if a node with scheduled jobs fails, another pgpro_scheduler instance picks up these jobs. If pgpro_scheduler is running on more than one node, the node with the smallest node ID is selected. The naming pattern of node IDs is defined by the schedule.nodename GUC variable.

F.54.5. Reference #

F.54.5.1. GUC Variables #

schedule.enabled (boolean) #

Deprecated. Specifies whether pgpro_scheduler is enabled on your system.

Default: false.

For pgpro_scheduler 2.5 or higher, you can set the schedule.auto_enabled parameter to control whether pgpro_scheduler is enabled at the server start, or use schedule.enable()/schedule.disable() functions to enable/disable pgpro_scheduler on demand. To check if pgpro_scheduler is currently running, use the schedule.is_enabled() function.

schedule.auto_enabled (boolean) #

Specifies whether to enable pgpro_scheduler at the server start.

Default: false.

schedule.database (text) #

Specifies the databases for which pgpro_scheduler is enabled. Database names must be separated by commas.

Default: empty string.

schedule.database_to_connect (text) #

The database to which pgpro_scheduler gets connected to receive Postgres Pro Enterprise cluster metadata. The specified database cannot be dropped while pgpro_scheduler is running. You can change this parameter only when restarting the server.

Default: postgres.

schedule.schema (text) #

Deprecated. Specifies the name of a schema where the scheduler stores its tables and functions. If you need to change the default schema, use ALTER EXTENSION.

Default: schedule.

schedule.nodename (text) #

Specifies the name of the cluster node on which pgpro_scheduler is running. Do not change or use this variable if you run a single-server cluster configuration.

On a cluster configured with multimaster, the node name is derived from the node ID provided by multimaster. For example, if the node ID is 3, the schedule.nodename variable is set to mtm-node-3. However, if you explicitly set the schedule.nodename variable by editing the postgresql.conf file or running the ALTER command, pgpro_scheduler will ignore the node ID and use the provided value instead.

Default: primary.

schedule.max_workers (integer) #

Specifies the maximum number of simultaneously running scheduled jobs in one database.

Default: 2.

schedule.max_parallel_workers (integer) #

Specifies the maximum number of parallel threads that can be used for executing one-time jobs.

Default: 2.

schedule.transaction_state (text) #

An internal variable containing the state of the executed job. pgpro_scheduler uses this variable when calculating the next job start time. Possible values are:

  • success — transaction has finished successfully.

  • failure — transaction has failed to finish.

  • running — transaction is in progress.

  • undefined — transaction has not started yet.

At the time of the next_time_statement execution, the schedule.transaction_state variable must contain either success or failure state values. Other values may indicate an internal pgpro_scheduler error.

schedule.enable_history (boolean) #

Log all schedule changes, including the name of the user who initiated the change and the time when this change occurred. If a new job is added, or the schedule of an existing job is modified, this information is stored in the schedule.cron__history table. If a job is deleted, this information is stored in the schedule.cron__deleted table. If you later disable the schedule.enable_history parameter, the history of the already recorded changes is preserved.

Default: false

F.54.5.2. SQL Schema #

To store its internal tables and functions, pgpro_scheduler uses the schedule SQL schema. Direct access to tables is not recommended and should not be attempted. To manage job scheduling, use the functions defined by the pgpro_scheduler extension.

F.54.5.3. SQL Types #

pgpro_scheduler defines the following types that are used by some of the pgpro_scheduler functions.

F.54.5.3.1. cron_rec #

This type contains information about the scheduled job.

CREATE TYPE schedule.cron_rec AS(
    id integer,             -- job ID
    node text,              -- name of the node
                            -- on which to execute the job
    name text,              -- job name
    comments text,          -- comments about the job
    rule jsonb,             -- scheduling rules
    commands text[],        -- SQL commands to be executed
    run_as text,            -- username of the job executor
    owner text,             -- username of the job owner
    start_date timestamptz,   -- lower bound of the execution window;
                            -- NULL if unbound
    end_date timestamptz,     -- upper bound of the execution window;
                            -- NULL if unbound
    use_same_transaction boolean,   -- true if an array of SQL 
                                    -- commands will be executed 
                                    -- in a single transaction
    last_start_available interval,  -- maximum wait time for 
                                    -- the scheduled job if all 
                                    -- allowed workers are busy
    max_run_time interval,  -- maximum execution time
    onrollback text,        -- SQL statement to execute 
                            -- if the main transaction fails
    max_instances int,      -- maximum number of simultaneously 
                            -- running job instances
    next_time_statement text,   -- SQL statement to calculate 
                                -- the next start time
    active boolean,         -- true if job is scheduled 
                            -- successfully
    broken boolean          -- true if job has errors in 
                            -- configuration that prevented 
                            -- its further execution
);

F.54.5.3.2. cron_job #

This type contains information about a particular job execution.

CREATE TYPE schedule.cron_job AS(
    cron integer,           -- job id
    node text,              -- name of the node
                            -- on which to execute the job
    scheduled_at timestamptz, -- scheduled execution time
    name text,              -- job name
    comments text,          -- comments about the job
    commands text[],        -- SQL statement to be executed
    run_as text,            -- username of the job executor
    owner text,             -- username of the job owner
    use_same_transaction boolean,   -- true if an array of SQL 
                                    -- commands will be executed
                                    -- in a single transaction
    started timestamptz,      -- timestamp of the job execution start
    last_start_available timestamp, -- maximum wait time for 
                                    -- the scheduled job if all 
                                    -- allowed workers are busy
    finished timestamptz,     -- timestamp of the job
                            -- execution finish
    max_run_time interval,  -- maximum execution time
    onrollback text,        -- SQL statement to execute if the main
                            -- transaction fails
    next_time_statement text,   -- SQL statement to calculate 
                                -- the next start time
    max_instances int,      -- the number of simultaneously 
                            -- running job instances 
    status job_status_t,    -- status of the task:
                            -- working, done, or error
    message text            -- error message
);

F.54.5.3.3. job_status_t #

Enumerated type. Can take the following values:

  • working — the job is being executed.

  • done — job execution is complete.

  • error — job execution has failed.

F.54.5.3.4. job_at_status_t #

Enumerated type. Can take the following values:

  • submitted — the job is submitted into the queue, but the execution has not started yet.

  • processing — the job is being executed.

  • done — job execution is complete.

F.54.5.3.5. timetable_job_type_t #

Enumerated type. Can take the following values:

  • periodical — a scheduled job.

  • onetime — a one-time job.

F.54.5.3.6. timetable_job_status_t #

Enumerated type. Can take the following values:

  • inprogress — the job is being executed.

  • done — job execution is complete.

  • error — job execution has failed.

  • submitted — the job is submitted into the queue, but the execution has not started yet.

F.54.5.4. Views #

pgpro_scheduler provides several views for monitoring execution status of one-time jobs.

F.54.5.4.1. job_status View #

Shows the status of one-time jobs belonging to the current user.

Table F.39. job_status View

Column Name Column Type Description
idbigint Job ID.
nodetext Name of the node on which the job is being executed.
nametext Name of the job.
commentstext Comments about the job.
run_aftertimestamp with time zone Timestamp after which the job execution must start.
querytextSQL commands executed by the job.
paramstext[] An array of parameters for the SQL query.
depends_onbigint[] An array of job IDs on which the job execution depends.
run_astext User or role whose rights are used to execute the job.
attemptbigint The number of execution attempts.
resubmit_limitbigint The maximum number of allowed job resubmissions.
max_wait_intervalinterval The maximum time interval to postpone the job execution if all background workers are busy at the scheduled moment.
max_durationinterval Time interval during which the job can be executed.
submit_timetimestamp with time zone Time when the job was submitted to the execution queue.
canceledboolean Specifies whether the job was canceled by user.
start_timetimestamp with time zone Job execution start time.
is_successboolean
  • true — job execution completed successfully.

  • false — job execution completed with errors.

errortextError message.
done_timetimestamp with time zoneTime when the job execution completed.
statusjob_at_status_tJob status. See the Section F.54.5.3.4 for details.

F.54.5.4.2. all_job_status View #

Shows the status of all one-time jobs. You must have superuser rights to access this view.

Table F.40. all_job_status View

Column Name Column Type Description
idbigint Job ID.
nodetext Name of the node on which the job is being executed.
nametext Name of the job.
commentstext Comments about the job.
run_aftertimestamp with time zone Timestamp after which the job execution must start.
querytextSQL commands executed by the job.
paramstext[] An array of parameters for the SQL query.
depends_onbigint[] An array of job IDs on which the job execution depends.
run_astext User or role whose rights are used to execute the job.
ownertext The user who created the job.
attemptbigint The number of execution attempts.
resubmit_limitbigint The maximum number of allowed job resubmissions.
max_wait_intervalinterval The maximum time interval to postpone the job execution for if all background workers are busy at the scheduled moment.
max_durationinterval Time interval during which the job can be executed.
submit_timetimestamp with time zone Time when the job was submitted to the execution queue.
canceledboolean Specifies whether the job was canceled by user.
start_timetimestamp with time zone Job execution start time.
is_successboolean
  • true — job execution completed successfully.

  • false — job execution completed with errors.

errortextError message.
done_timetimestamp with time zoneTime when the job execution completed.
statusjob_at_status_tJob status. See the Section F.54.5.3.4 for details.

F.54.5.5. Audit Tables #

The following tables store all schedule changes if the schedule.enable_history parameter is set to true. If you later disable the schedule.enable_history parameter, the history of the already recorded changes is preserved.

F.54.5.5.1. schedule.cron__history Table #

Registers job scheduling changes. Whenever a new job is scheduled, or the schedule for an existing job is changed, a new row is inserted into this table to record the following information:

  • All details about the scheduled job, as defined by the cron_rec data type. For details on the cron_rec type, see Section F.54.5.3.

  • submitter — name of the user who updated the schedule.

  • version_id — a unique ID for each registered change in the schedule.

  • submit_time — time when the schedule was updated.

F.54.5.5.2. schedule.cron__deleted Table #

Registers all jobs that were removed from the schedule:

  • cron — ID of the deleted job.

  • submitter — name of the user who deleted the job.

  • submit_time — time when the job was deleted.

F.54.5.6. Functions #

pgpro_scheduler provides two separate sets of functions for managing scheduled and one-time jobs, as well as several common functions that can toggle pgpro_scheduler on and off for your database and show the current status of the extension:

Important

With each job, you can only use the function specifically tailored for this job type.

F.54.5.6.1. Common Functions #

These functions facilitate pgpro_scheduler management.

schedule.enable() #

Enables pgpro_scheduler for the current Postgres Pro Enterprise instance.

Return values:

  • true if pgpro_scheduler is enabled and ready to use.

  • false if the command has failed.

schedule.is_enabled() #

Checks whether pgpro_scheduler is enabled.

Return values:

  • true if pgpro_scheduler is enabled and ready to use.

  • false if pgpro_scheduler is not currently running.

schedule.disable() #

Disables pgpro_scheduler for the current Postgres Pro Enterprise instance.

Return values:

  • true if pgpro_scheduler is disabled.

  • false if the command has failed.

schedule.start() #

Launches pgpro_scheduler for the currently connected database.

Return values:

  • truepgpro_scheduler started successfully.

  • false — if the command has failed, or pgpro_scheduler is already started.

schedule.stop() #

Stops pgpro_scheduler for the currently connected database.

Return values:

  • truepgpro_scheduler is stopped.

  • false — if the command has failed, or pgpro_scheduler is not running.

schedule.status() #

Returns the status of pgpro_scheduler background workers:

  • pid — process ID of the background worker. If the process ID is NULL, the background worker is not running.

  • database — name of the database to which the background worker is connected.

  • type — type of the background worker:

    • supervisor — distributes the scheduled jobs between the databases.

    • database manager distributes the scheduled jobs within the database.

    • cron job executor executes a scheduled job.

    • at job executor executes a one-time job.

schedule.version() #

Returns pgpro_scheduler version.

F.54.5.6.2. Functions for Managing Scheduled Jobs #
schedule.create_job(options jsonb) #

Creates an active job and returns the job ID.

Alternative Syntax:

schedule.create_job(cron text, commands text [, node text])
schedule.create_job(cron text, commands text[] [, node text])
schedule.create_job(dates timestamp with time zone, commands text [, node text])
schedule.create_job(dates timestamp with time zone, commands text[] [, node text])
schedule.create_job(dates timestamp with time zone[], commands text [, node text])
schedule.create_job(dates timestamp with time zone[], commands text[] [, node text])

Arguments:

  • options — a jsonb object defining all the job properties. You do not need to define other parameters if the data is set. All the available jsonb keys are listed in Table F.41.

    Type: jsonb

  • cron — a crontab-like string defining the job schedule.

    Type: text

  • dates — the exact date or an array of dates for job execution.

    Type: timestamp with time zone, timestamp with time zone[]

  • commandsSQL statement to execute. You can pass one or more SQL commands separated by semicolons, or an array of SQL commands. When passed as an array, SQL commands are executed in separate transactions.

    Type: text, text[]

  • node — the name of the node on which the scheduled jobs run. Optional. You may need to specify this argument if you are scheduling jobs on a multi-master cluster.

    Type: text

Return values:

  • ID of the created job.

Table F.41. jsonb Keys for Job Scheduling

Key Type Description
crontext

A crontab-like string defining the job schedule. A traditional five-field or nonstandard six-field (seconds in the first field) crontab format may be used. You can combine cron with rule and dates keys, but at least one of them is mandatory. Alternatively, the following keywords can be used instead of a crontab string to specify when the job will be started:

  • @every_second — each second

  • @hourly — at the beginning of each hour

  • @daily — at the beginning of each day

  • @midnight — at the beginning of each day

  • @weekly — at the beginning of each week

  • @monthly — at the beginning of each month

  • @yearly — at the beginning of each year

  • @annually — at the beginning of each year

datestimestamp with time zone, timestamp with time zone[] The exact date or an array of dates when the scheduled job will be executed. You can combine dates with rule and cron keys, but at least one of them is mandatory.
rulejsonb

A jsonb object defining the job schedule. Mandatory, if both cron and dates keys are undefined. The rule object includes one or more of the following keys:

  • seconds — seconds; an array of integers in range [0, 59]

  • minutes — minutes; an array of integers in range [0, 59]

  • hours — hours; an array of integers in range [0, 23]

  • days — days of the month; an array of integers in range [1, 31]

  • months — months; an array of integers in range [1, 12]

  • wdays — days of the week; an array of integers in range [0, 6], where 0 is Sunday.

  • onstart — integer value 0 or 1. If onstart is set to 1, the job is executed only once when pgpro_scheduler is started.

commandstext, text[]SQL statements to execute. You can pass one or more SQL statements separated by semicolons, or an array of SQL statements. When passed as an array, SQL statements are executed in separate transactions by default. You can change this behavior by setting the use_same_transaction key.
nametext Optional. Job name.
nodetext Optional. The name of the node on which the scheduled jobs run. You may need to specify this argument if you are scheduling jobs on a multi-master cluster.
commentstext Optional. Comments about the scheduled job.
run_astext Optional. The user whose rights are used to execute the job.
start_datetimestamp with time zone Optional. The start of the timeframe when the scheduled job can be executed. This key can be NULL.
end_datetimestamp with time zone Optional. The end of the timeframe when the scheduled job can be executed. This key can be NULL.
use_same_transactionboolean Optional. If set to true, forces an array of SQL statements to be executed in a single transaction. Default: false
last_start_availableinterval Optional. The maximum time interval to postpone the job execution for if all background workers are busy at the scheduled moment. For example, if this key is set to '00:02:34', the job will wait for 2 minutes 34 seconds. If this key is NULL or not set, the job can wait forever. Default: NULL.
max_instancesinteger

Optional. The maximum number of job instances that can be executed simultaneously. Default: 1.

For cron jobs where next_time_statement is set, the max_instances value must always be 1.

max_run_timeinterval Optional. The maximum time interval during which the scheduled job can be executed. If this key is NULL or not set, there are no time limits. Default: NULL.
onrollbacktext Optional. SQL statement to be executed if the main transaction fails.
next_time_statementtext Optional. SQL statement to calculate the start time for the next job execution. For details, see Section F.54.4.1.3.

schedule.set_job_attributes(job_id integer, data jsonb) #

Updates properties of the existing job.

Arguments:

  • job_id — identifier of the existing job.

  • data — a jsonb object with properties to be edited. For the list of keys and their structure, see Table F.41.

Return values:

  • true — job properties were updated successfully.

  • false — job properties were not updated.

To update the job properties, you must be the owner of the job or have superuser rights.

schedule.set_job_attribute(job_id integer, name text, value text || anyarray) #

Updates a property of the existing job.

Arguments:

  • job_id — identifier of the existing job.

  • name — property name.

  • value — property value.

See Table F.41 for the list of job properties you can update. Some values are of array types. They should be passed as an array. If a value of a wrong type is passed, an exception is raised.

Return values:

  • true — job property was updated successfully.

  • false — job property was not updated.

To update the job properties, you must be the owner of the job or have superuser rights.

schedule.deactivate_job(job_id integer) #

Deactivates the job and suspends its further scheduling and execution.

Arguments:

  • job_id — identifier of the existing job.

Return values:

  • true — the job is deactivated successfully.

  • false — job deactivation failed.

schedule.activate_job(job_id integer) #

Activates a job and starts its scheduling and execution.

Arguments:

  • job_id — identifier of the existing job.

Return values:

  • true — the job was activated successfully.

  • false — job activation failed.

schedule.drop_job(job_id integer) #

Deletes a job.

Arguments:

  • job_id — identifier of the existing job.

Return values:

  • true — the job was deleted successfully.

  • false — job was not deleted.

schedule.get_job(job_id integer) #

Returns information about the specified job.

Arguments:

  • job_id — identifier of the existing job.

Return values:

  • An object of type cron_rec.

For details on the cron_rec type, see Section F.54.5.3.

schedule.get_owned_cron(username text) #

Retrieves the list of jobs owned by the specified user.

Arguments:

  • username — username, optional.

Return values:

  • A set of records of type cron_rec. These records contain information about all jobs owned by the specified user. If the username is omitted, the session username is used. You must have superuser rights to retrieve jobs owned by another user.

For details on the cron_rec type, see Section F.54.5.3.

schedule.get_cron() #

Retrieves the list of jobs executed by the session user.

Return values:

  • A set of records of type cron_rec. These records contain information about all jobs executed by the session user. You must have superuser rights to retrieve the jobs.

For details on the cron_rec type, see Section F.54.5.3.

schedule.get_active_jobs(username text) #

Returns the list of jobs currently being executed by the specified user.

Arguments:

  • username — username, optional.

If username is omitted, the session username is used. You must have superuser rights to retrieve jobs executed by another user.

Return values:

  • A set of records of type cron_job.

For details on the cron_job type, see Section F.54.5.3.

schedule.get_active_jobs() #

Returns the list of jobs being currently executed. You must have superuser rights to call this function.

Return values:

  • A set of records of type cron_job.

For details on the cron_job type, see Section F.54.5.3.

schedule.get_log() #

Returns the list of all completed jobs. You must have superuser rights to call this function.

Return values:

  • A set of records of type cron_job.

For details on the cron_job type, see Section F.54.5.3.

schedule.get_user_log(username text) #

Returns the list of completed jobs executed by the specified user.

Arguments:

  • username — username, optional.

If username is omitted, the session username is used. You must have superuser rights to retrieve the list of jobs executed by another user.

Return values:

  • A set of records of type cron_job.

For details on the cron_job type, see Section F.54.5.3.

schedule.clean_log() #

Deletes all records with information about the completed jobs. You must have superuser rights to call this function.

Return values:

  • The number of records deleted.

schedule.nodename() #

Returns the current node name.

F.54.5.6.3. Functions for Managing One-Time Jobs #
schedule.submit_job(query text [options...]) #

Submits a job for immediate or delayed one-time execution. By default, the job is scheduled for immediate execution and can run in parallel with other scheduled jobs. To submit a job with a delayed start, you can set the execution start time using the run_after argument, or pass an array of job IDs in the depends_on argument to schedule job execution right after these jobs are complete.

Arguments:

  • querySQL commands to execute.

    Type: text

  • params — an array of parameters for the SQL query that can substitute numbered placeholders in the query argument, such as $1, $2, etc. Default: NULL

    Type: text[]

  • run_after — a timestamp after which the job execution starts. If this argument is set to NULL, the job is scheduled for immediate execution. You can also use the depends_on argument to delay the job start. Default: NULL

    Type: timestamp with time zone

  • node — the name of the node on which to execute the job. Default: NULL

    Type: text

  • max_duration — the maximum time interval during which the job can be executed. If this time is exceeded, the job is forced to stop. If this argument is NULL or not set, there are no time limits. Default: NULL

    Type: interval

  • max_wait_interval — the maximum time interval to postpone the job execution for if all background workers are busy at the scheduled moment. For example, if this key is set to '00:02:34', the job will wait for 2 minutes 34 seconds. If this key is NULL or not set, the job can wait forever. Default: NULL

    Type: interval

  • run_as — user or role whose rights are used to execute the job. If run_as is set to NULL, the job is executed with the rights of the current user. You must have superuser rights to set this argument. Default: NULL

    Type: text

  • depends_on — an array of job IDs. The created job starts immediately after the specified jobs complete the execution. This argument is an alternative to run_after. Default: NULL

    Type: bigint[]

  • name — name of the job. Default: NULL

    Type: text

  • comments — comments about the job.

    Type: text

  • resubmit_limit — maximum number of times the job can be resubmitted for execution. See the schedule.resubmit() function for details. Default: 100

    Type: bigint

Return values:

  • ID of the created job.

    Type: bigint

schedule.get_self_id() #

Returns the ID of the job, in the context of which it was called. The returned ID is of the bigint type. This function must be called inside the query of the schedule.submit_job() function. Otherwise, an exception is raised.

Return values:

  • Job ID.

schedule.cancel_job(job_id bigint) #

Cancels all subsequent runs of the specified job. If the job is currently being executed, it will not be interrupted, but cannot be resubmitted. You must have superuser rights or be the owner of the job to call this function.

Arguments:

  • job_id — identifier of the job to cancel.

Return values:

  • true if the operation completed successfully.

  • false if the operation failed.

schedule.resubmit(run_after interval default NULL) #

Sets the start time for the next execution of the job, without interrupting the current job run. This function must be called inside the query argument of the schedule.submit_job() function. Otherwise, an exception is raised. If this function is called several times within a single job execution, only the last function call is taken into account.

Arguments:

  • run_after — time interval after which the job will be resubmitted for execution. If the time interval is less than a second but greater than zero, it is rounded to 1 second. Intervals longer than 1 second are rounded to integral values. If 0 is passed, the job is resubmitted immediately after execution. Default: 1 second

    Type: interval

Return values:

  • The number of seconds after which the job will be resubmitted for execution.

F.54.5.6.4. Cleanup Functions #

When many one-time jobs are submitted, the table that stores completed one-time jobs may grow rapidly. To clean up this table, pgpro_scheduler provides the following functions with the same name but different argument types:

schedule.clean_at_jobs_done(older_than interval, delete_failed_tasks boolean, default NULL)
schedule.clean_at_jobs_done(older_than timestamp with time zone, delete_failed_tasks boolean, default NULL)

Delete all records from the table with completed one-time jobs that are older than either a specified timestamp or a specified interval relative to the current time.

Arguments:

  • older_than — an interval or a timestamp for cleanup. Records older than this value will be deleted.

    Type: interval, timestamp with time zone

  • delete_failed_tasks — specifies whether to delete failed jobs. Default: false.

    Type: boolean

Return values:

  • The number of deleted records.

These functions can be called manually or scheduled using cron jobs in the pgpro_scheduler interface.

F.54.5.6.5. Functions for Managing Scheduled and One-Time Jobs #
schedule.timetable(start_time timestamp with time zone, end_timetimestamp with time zone) #

Returns a table, which describes all the jobs, both repeated and one-time, that are scheduled to execute within the specified time interval.

Table F.42. schedule.timetable Columns

Column Name Column Type Description
idbigint Job ID, which is unique for the jobs of this type.
typetimetable_job_type_t Job type. See Section F.54.5.3.5 for details.
nodetext Name of the node on which the job is being executed.
nametext Name of the job.
commentstext Comments about the job.
commandstext[] An array of SQL commands executed by the job.
scheduled_attimestamp with time zone Scheduled job execution time.
start_timetimestamp with time zone Job execution start time.
done_timetimestamp with time zoneTime when the job execution completed.
statustimetable_job_status_tJob status. See Section F.54.5.3.6 for details.
errortextError message.

F.54.6. Authors #

Postgres Professional, Moscow, Russia

FAQ