Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

postgrespro/postgres_cluster

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pgpro_scheduler - расширение PostgreSQL для управления расписанием задач

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, если количество одновременно исполняемых задач в обоих базах одинаково:

shared_preload_libraries = 'pgpro_scheduler'
schedule.enable = on
schedule.database = 'database1,database2'
schedule.max_workers = 5

Планировщик задач работает с помощью Background Worker'ов. Поэтому должно быть правильно установлено значение переменной max_worker_processes. Минимальное значение переменной может быть расcчитано по следующей формуле:

Nmin = 1 + Ndatabases + MAX_WORKERS1 + ... + MAX_WORKERSn

Где:

  • 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,   -- нижняя граница временного периода, во время
							-- которого допускается выполнение задачи,
							-- граница считается открытой, если значение NULL
	end_date timestamp,     -- верхняя граница временного периода, во время
							-- которого допускается выполнение задачи,
							-- граница считается открытой, если значение NULL
	use_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			-- сообщение, это может быть сообщение об
							-- ошибке, так и какая-то служебная информация
);

Функции управления

schedule.create_job(cron text, sql text, node text)

Создает задачу и делает ее активной.

Агрументы:

  • cron - crontab-like строка для задания расписания выполнения
  • sql - строка, SQL команда для выполнения
  • node - название узла, опционально

Возвращает идентификатор созданной задачи.

schedule.create_job(cron text, sqls text[], node 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 для вычисления следующего времени запускается в случае удачного и не удачного завершения транзакции. О том как завершилась транзакция можно узнать из значения переменной PostgreSQL schedule.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()

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

Возвращает количество удаленных записей

About

Various experiments with PostgreSQL clustering

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 38