You signed in with another tab or window.Reload to refresh your session.You signed out in another tab or window.Reload to refresh your session.You switched accounts on another tab or window.Reload to refresh your session.Dismiss alert
pgpro_scheduler это планировщик задач для СУБД PostgreSQL, который позволяетпланировать выполнение задач в базе и контролировать их исполнение.
Задачи это наборы SQL команд. Расписание выполнения задач задается либо строкойcron, либо указанием конкретных дат запуска, либо JSON объектом, в которомуказывается в какие дни часы и минуты задача должна быть запущена. Возможнакомбинация методов описания расписания.
Каждая задача имеет возможность для вычисления времени следующего своегозапуска. Набор SQL команд в задаче может обрабатываться в одной транзакции илиже каждая команда может использовать свою индивидуальную транзакцию.Имеется возможность задания SQL команды, которая будет выполняться в случаеаварийного завершения транзакции.
Installation
pgpro_scheduler это расширение PostgreSQL и не требует никаких специальныхпререквизитов.
Перед сборкой расширения из исходного кода убедитесь, что переменнаяокружения PATH содержит путь к командеpg_config. Так же убедитесь,что у вас установлена версия PostgresSQL для разработчиков или PostgreSQLсобран из исходного кода.
Процедура установки выглядит следующим образом:
$ cd pgpro_scheduler$ make USE_PGXS=1$ sudo make USE_PGXS=1 install$ psql <DBNAME> -c "CREATE EXTNESION pgpro_scheduler"
Конфигурация
Расширение определяет ряд переменных в PostgreSQL (GUC), которые позволяютуправлять его конфигурацией.
schedule.enable - двоичная переменная, которая определяет разрешено ливыполнение расширения. По умолчанию: false.
schedule.database - строковая переменная, указывает с какими базам можетработать планировщик. Что бы указать несколько баз, нужно перечислить ихимена через запятую. По умолчанию - пустая строка.
schedule.nodename - строковая переменная, содержит название узла.По умолчанию - master. Если расширение используется на одной машине,то переменная не имеет смысла.
schedule.max_workers - целочисленная переменная, содержит максимальноеколичество одновременно работающих задач для одной базы. По умолчанию - 2.
schedule.transaction_state - строковая переменная, устанавливаетсярасширением в процессе работы. По умолчанию - undefined. Переменнаяиспользуется для определения статуса завершения транзакции при вычисленииследующего времени выполнения задачи. Возможные значения:
success - транзакция завершилась успешно
failure - транзакция завершилась аварийно
running - транзакция в процессе исполнения
undefined - транзакция не началась
Последние два значения не должны попадать в процедуру определения следующегозначения. Это будет означать какую-то внутреннюю ошибку в работепланировщика.
Управление
Управление работой планировщика задач осуществляется через переменныеPostgreSQL, которые описаны в предыдущем разделе.
Например, у вас существует свежая инсталляция PostgreSQL с установленнымрасширением планировщика. И вам требуется запустить планировщик на двухбазах database1 и database2. При этом вы хотите что бы планировщик длябазы database1 мог исполнять 5 задач одновременно, а для базы database2 - 3.
В$DATADIR/postgresql.conf должна присутствовать строка:
shared_preload_libraries = 'pgpro_scheduler'
Далее вpsql введите следующие команды:
# ALTER SYSTEM SET schedule.enable = true;# ALTER SYSTEM SET schedule.database = 'database1,database2';# ALTER DATABASE database1 SET schedule.max_workers = 5;# ALTER DATABASE database2 SET schedule.max_workers = 3;# SELECT pg_reload_conf();
Если вам не нужны указания различных значений для разных баз данных, то все этоможно занести в конфигурационный файл PostgreSQL, и перечитать конфигурацию.Перезапуска не требуется.
Пример записей в$DATADIR/postgresql.conf, если количество одновременноисполняемых задач в обоих базах одинаково:
Планировщик задач работает с помощью Background Worker'ов. Поэтому должно бытьправильно установлено значение переменнойmax_worker_processes. Минимальноезначение переменной может быть расcчитано по следующей формуле:
Nmin - это минимальное значение переменной, котороетребуется для работы конфигурации. Имейте в виду, что Background Workes'ымогут требоваться для работы других систем, например, параллельных запросов.
Ndatabases - это количество баз данных, для которыхзапускается планировщик.
MAX_WORKERSn - это значение переменнойschedule.max_workersв контексте каждой базы данных, для которой запускается планировщик.
SQL Схема
При установке расширения создается SQL схемаschedule. Все функции дляработы с планировщиком и служебные таблицы создаются в ней.
Прямой доступ к внутренним таблицам запрещен. Все управление осуществляетсянабором SQL функций, о котором будет рассказано далее.
SQL Типы
Планировщик определяет 2 SQL типа, которые он использует в качестве типоввозвращаемых значений для своих функций.
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 timestamp, -- нижняя граница временного периода, во время-- которого допускается выполнение задачи,-- граница считается открытой, если значение NULLend_date timestamp, -- верхняя граница временного периода, во время-- которого допускается выполнение задачи,-- граница считается открытой, если значение NULLuse_same_transaction boolean, -- если true, то набор команд будет -- выполняться в одной транзакцииlast_start_available interval, -- максимальное время, на которое может -- быть отложен запуск задачи, если -- нет свободных workers для ее-- выполнения во время по расписаниюmax_instances int,-- максимальное количество копий задачи, которые-- могут быть запущенны одновременноmax_run_time interval, -- максимальное время выполнения задачиonrollback text, -- SQL команда, которая будет выполнена в случае-- аварийного завершения транзакцииnext_time_statement text, -- SQL команда, которая будет выполнена -- после завершения основного набора SQL -- команд, которая возвращает следующее-- время выполнения задачиactive boolean, -- true - если задача доступна для запуску по -- расписаниюbroken boolean -- true - задача имеет ошибки в конфигурации,-- которые не позволяют ее выполнять далее);
###cron_job
Тип используется для информации о конкретном исполнении задачи.
CREATE TYPE schedule.cron_job AS(cron integer, -- идентификатор задачиnode text, -- имя узла, на котором она выполнятьсяscheduled_at timestamp, -- запланированное время выполненияname text, -- имя задачиcomments text, -- комментарий к задачеcommands text[], -- sql команды для выполненияrun_as text, -- имя пользователя, с правами которого будет-- выполнен набор командowner text, -- имя пользователя, создавшего задачуuse_same_transaction boolean,-- если true, то набор команд -- выполняется в одной транзакцииstarted timestamp, -- время, когда задача была запущенаlast_start_available timestamp,-- время, до которого задача должна-- быть запущенаfinished timestamp, -- время, когда задача была завершенаmax_run_time interval, -- время, за которое задача должна выполнится,-- иначе она будет аварийно остановленаmax_instances int,-- количество возможных одновременных сущностей-- задачи, которые могут работать одновременноonrollback text, -- SQL, который будет выполнен при аварийном -- завершении транзакцииnext_time_statement text,-- SQL для вычисления следующего времени запускаstatus text,-- статус задачи: working, done, error message text-- сообщение, это может быть сообщение об-- ошибке, так и какая-то служебная информация);
cron - crontab-like строка для задания расписания выполнения
sqls - набор SQL команд для выполнения в виде массива строк
node - название узла, опционально
Возвращает идентификатор созданной задачи.
schedule.create_job(date timestamp with time zone, sql text, node text)
Создает задачу и делает ее активной.
Агрументы:
date - время исполнения задачи
sql - строка, SQL команда для выполнения
node - название узла, опционально
Возвращает идентификатор созданной задачи.
schedule.create_job(date timestamp with time zone, sqls text[], node text)
Создает задачу и делает ее активной.
Агрументы:
date - время исполнения задачи
sqls - набор SQL команд для выполнения в виде массива строк
node - название узла, опционально
Возвращает идентификатор созданной задачи.
schedule.create_job(dates timestamp with time zone[], sql text, node text)
Создает задачу и делает ее активной.
Агрументы:
dates - набор дат для выполнения команды в виде массива
sql - строка, SQL команда для выполнения
node - название узла, опционально
Возвращает идентификатор созданной задачи.
schedule.create_job(dates timestamp with time zone[], sqls text[], node text)
Создает задачу и делает ее активной.
Агрументы:
dates - набор дат для выполнения команды в виде массива
sqls - набор SQL команд для выполнения в виде массива строк
node - название узла, опционально
Возвращает идентификатор созданной задачи.
schedule.create_job(data jsonb)
Создает задачу и делает ее активной.
Единтвенный принимаемый параметр является объектом JSONB, который содержитинформацию о создаваемой задаче.
JSONB объект может содержать следующие ключи, не все они являются обязательными:
name - имя задачи;
node - имя узла, на котором будет выполняться задача;
comments - комментарии к задаче;
cron - строка cron-like, для описания расписания выполнения;
rule - расписание в виде JSONB объекта (смотри далее);
command - SQL команда для выполнения;
commands - набор SQL команд для выполнения в виде массива;
run_as - пользователь, с правами которого будет выполняться задача
start_date - начало временного периода, во время которого возможензапуск выполнения задачи, если не указано, то нижняя граница не определена;
end_date - окончание временного периода, во время которого возможензапуск выполнения задачи, если не указано, то верхняя граница не определена;
date - конкретная дата запуска задачи;
dates - набор дат запуска задачи;
use_same_transaction - устанавливает будет ли набор команд выполнятьсяв рамках одной транзакции. По умолчанию: false;
last_start_available - на какое количество времени может быть отложеновыполнение задачи, если в момент запуска по расписанию уже запущеномаксимально возможное количество задач. Время задается в форматетипаinterval. Например, '00:02:34' - две минуты тридцать четыре секунды.Если время не определено, то ожидание будет бесконечным. По умолчаниювремя не определено;
max_run_time - определяет максимально возможное время выполнениязадачи. Время задается в формате типаinterval. Если время не определено,то время исполнения не ограничено. По умолчанию время не определено;
onrollback - SQL команда, которая будет выполнена, если транзакциязавершится аварийно. По умолчанию неопределенна;
next_time_statement - SQL команда, которая будет выполнена дляопределения следующего времени запуска задачи.
Правила для вычисления расписания выполнения задачи могут быть заданы в видестроки cron (ключcron), а так же в виде JSONВ объекта (ключrule).
Данный объект может содержать следующие поля:
minutes - минуты, целочисленный массив со значениями в диапазоне 0-59
hours - часы, целочисленный массив со значениями в диапазоне 0-23
days - дни месяца, целочисленный массив со значениями в диапазоне 1-31
months - месяцы, целочисленный массив со значениями в диапазоне 1-12
wdays - дни недели, целочисленный массив со значениями в диапазоне 0-6,где 0 - Воскресенье
onstart - целое число, со значением 0 или 1, если 1, то задает выполнениезадачи на старте планировщика
Так же расписание может быть задано на конкретную дату или на набор конкретныхдат. Для этого используйте ключиdate илиdates соответственно.
Все вышеописанные методы задания расписания могут быть скомбинированы междусобой. Но использование хотя бы одного из них обязательно.
Ключnext_time_statement используется для того, что бы вычислить следующеевремя выполнения задачи. Если он определен, то первое время выполнения задачибудет рассчитано с помощью методов приведенных выше, а последующие запуски будутпоставлены в расписание в то время, которое вернет SQL команда, указаннаяв данном ключе. Команда должна возвращать запись, в первом поле которогодолжно содержаться значение следующего времени запуска типаtimestamp with time zone. Если значение будет другого типа или выполнение данного SQL вызоветошибку, то задача будет помечена как сломанная, и дальнейшее ее выполнениебудет запрещено.
SQL для вычисления следующего времени запускается в случае удачного и неудачного завершения транзакции. О том как завершилась транзакция можно узнатьиз значения переменной PostgreSQLschedule.transaction_state.
Значение переменной может быть:
success - транзакция завершилась успешно
failure - транзакция завершилась с ошибкой
running - транзакция в процессе выполнения
undefined - неопределенна
Последние два значения не должны появляться внутри выполненияnext_time_statement. Если они появились там, то это скорее всего означаеткакую-то внутреннюю ошибку планировщика.
Сами SQL команды задаются либо ключомcommand, либо ключомcommands.Первый это одна SQL команда, второй набор команд. На самом деле в ключcommand можно передать несколько команд, разделенных точкой с запятой. Тогдаони все исполнятся в одной транзакции. Предпочтительно для набора командиспользовать ключcommands, так как в сочетании с ключомuse_same_transaction, вы можете задавать исполнение команд в одной транзакцииили выполнять каждую команду в отдельной транзакции, что позволит сохранитьрезультат успешно выполненных команд, если последующая завершается сошибкой. Так же в сообщении об ошибке будет более точная информация.
Функция возвращает идентификатор созданной задачи.
schedule.set_job_attributes(job_id integer, data jsonb)
Данная функция позволяет редактировать свойства уже созданной задачи.
Аргументы:
job_id - идентификатор задачи
data - JSONB объект, описывающий изменяемые свойства. Описание ключей иих структуру вы можете найти в описании функцииschedule.create_job.
Функция возвращает значение типа boolean - true - в случае удачи, false -в случае, если не удалось изменить свойства.
Пользователю, если он не суперпользователь, позволено менять свойства толькотех задач, владельцем которых он является.
schedule.set_job_attribute(job_id integer, name text, value text || anyarray)
Функция редактирует какое-то одно конкретное свойство существующей задачи.
Аргументы:
job_id - идентификатор задачи
name - название свойства
value - значение свойства
Полный список свойств вы можете найти в описании функцииschedule.create_job.Значения некоторых свойств являются массивами, в этом случае вы можетепередавать аргументvalue как массив. Если свойство не массив, а значениепередано как массив, возникнет ошибка.
Функция возвращает двоичное значение, true, если изменение успешное, false -в случае неуспеха.
Пользователю, если он не суперпользователь, позволено менять свойства толькотех задач, владельцем которых он является.
schedule.deactivate_job(job_id integer)
Функция деактивирует задачу и приостанавливает ее последующее выполнение.
Аргументы:
job_id - идентификатор задачи
Возвращает true в случае успеха.
schedule.activate_job(integer)
Функция активирует задачу. После чего задача начинает выполняться по расписанию.
Аргументы:
job_id - идентификатор задачи
Возвращает true в случае успеха.
schedule.drop_job(jobId integer)
Функция удаляет задачу.
Аргументы:
job_id - идентификатор задачи
Возвращает true в случае успеха.
schedule.get_job(job_id integer)
Функция возвращает информацию о задаче.
Аргументы:
job_id - идентификатор задачи
Возвращает информацию о задаче в виде записи типаcron_rec. Описание выможете найти в разделеSQL типы.
schedule.get_user_owned_cron(username text)
Функция возвращает список задач, принадлежащих пользователю.
Аргументы:
username - имя пользователя, опционально
Возвращает набор записей типаcron_rec, которые принадлежат пользователю,указанному в аргументах. Если пользователь не указан, то возвращаютсязадачи, принадлежащие пользователю сессии.
Просматривать задачи, принадлежащие другим пользователям, может толькосуперпользователь.
Описание типаcron_rec смотрие в разделеSQL типы.
schedule.get_user_cron(username text)
Функция возвращает список задач, которые будут выполнены с правами пользователя.
Аргументы:
username - имя пользователя, опционально
Возвращает набор записей типаcron_rec, которые описывают задачи, которыебудут выполняться с правами пользователя, указанного в аргументах.Если пользователь не указан, то то будет использоваться имя пользователя сессии.
Просматривать задачи, исполняемые другими пользователями, может толькосуперпользователь.
Описание типаcron_rec смотрите в разделеSQL типы.
schedule.get_user_active_jobs(username text)
Функция возвращает список задач, которые исполняются в данный момент с правамипользователя переданного в аргументах.
Аргументы:
username - имя пользователя, опционально
Если не указано имя пользователя, то берется имя пользователя сессии. Чужие ззадачи может просматривать только суперпользователь.
Задачи возвращаются в виде набора записей типаcron_job. Описание типа выможете найти в разделеSQL типы.
schedule.get_active_jobs()
Функция возвращает список всех задач, которые исполняются в данный момент.Может быть выполнена только пользователем с правами суперпользователя.
Задачи возвращаются в виде набора записей типаcron_job. Описание типа выможете найти в разделеSQL типы.
schedule.get_log()
Функция возвращает список всех выполненых задач.Может быть выполнена только пользователем с правами суперпользователя.
Задачи возвращаются в виде набора записей типаcron_job. Описание типа выможете найти в разделеSQL типы.
schedule.get_user_log(username text)
Функция возвращает список всех выполненых задач, которые выполнялись с правамипользователя, переданного в аргументах.
Аргументы:
username - имя пользователя, опционально
Если не указано имя пользователя, то используется имя пользователя сессии.Чужие задачи может просматривать только суперпользователь.
Задачи возвращаются в виде набора записей типаcron_job. Описание типа выможете найти в разделеSQL типы.
schedule.clean_log()
Удаляет все записи о выполненных задачах. Может быть выполнена только с правамисуперпользователя.