Перейти к основному содержимому

pg_background. Запуск команд в фоновом режиме

Версия: 1.0.

В исходном дистрибутиве установлено по умолчанию: нет.

Связанные компоненты: отсутствуют.

Схема размещения: ext.

Модуль дает возможность:

  1. Занимать пользовательскими вызовами фоновые процессы-обработчики.
  2. Размещать в этих процессах sql-команды: предложения, вызовы функций, процедур, анонимных блоков кода. При размещении вызова отводить область памяти сессии заданного размера для результатов вызова, получать pid выделенного процесса.
  3. В памяти dsm отводить дескрипторы запущенных процессов, обращаться к ним по ранее полученным pid.
  4. Ожидать завершения вызова.
  5. По завершении вызова получать результаты различных типов: выбранные данные, результаты процедур и функций, коды ошибок и подробные сообщения.
  6. Отсоединять процессы-обработчики без завершения текущего вызова и без контроля его результата.

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

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

Описание функций

ФункцияВозвращаемое значениеОписаниеАргументы
pg_background_launch (sql TEXT, queue_size INT4 DEFAULT 65536)int4Запускает фоновый обработчик, обрабатывающий указанную sql команду и возвращает pid обработчикаsql - sql команда;
queue_size - размер буфера для получения результата
pg_background_result (pid INT4)recordВозвращается множество записей, включающих в себя результат вызова в случае успеха или подробности ошибки в случае сбоя. Тип record - не подлинный тип данных записи (коллекции значений других типов). Это только лишь заполнитель, который при каждом использовании требует явного объявления структуры записейpidpid обработчика
pg_background_detach (pid INT4)voidОтсоединяет фоновый обработчик, результат работы обработчика будут удалены из памяти без ожидания их обработкиpidpid обработчика

Описание представлений

Представление pg_stat_bg_activity

Представление строится на основе представления pg_stat_activity по процессам с типом pg_background

Имя столбцаТипОписание
datidoidOID базы данных
datnamenameИмя базы данных
pidintegerИдентификатор процесса
leader_pidintegerИдентификатор ведущего процесса
usesysidoidOID пользователя
usenamenameИмя пользователя
application_nametextНазвание приложения
backend_starttimestamptzВремя запуска процесса
xact_starttimestamptzВремя начала текущей транзакции или NULL при отсутствии активной транзакции
query_starttimestamptzВремя начала выполнения запроса, активного в момент сохранения данных, или, если поле state не active, то время начала выполнения последнего запроса
state_changetimestamptzВремя последнего изменения состояния (поле state)
wait_event_typetextТип события, который ждет обслуживающий процесс, если это ожидание имеет место, в противном случае — NULL
wait_eventtextИмя ожидаемого события, если обслуживающий процесс находится в состоянии ожидания, в противном случае — NULL
statetextОбщее текущее состояние этого серверного процесса
backend_xidxidИдентификатор верхнего уровня транзакции этого серверного процесса или любой другой
backend_xminxidТекущая граница xmin для серверного процесса
querytextТекст последнего запроса этого серверного процесса. Если поле state имеет значение active, то в этом поле отображается запрос, который выполняется в настоящий момент. Если процесс находится в любом другом состоянии, то в этом поле отображается последний выполненный запрос

Доработка

Добавлено представление pg_stat_bg_activity. В поле leader_pid представления pg_stat_activity отображается pid ведущего процесса для процессов с типом pg_background. Исправлено аварийное закрытие сервера при вызове pg_background_launch из функции SECURITY DEFINER.

Ограничения

По умолчанию использование модуля разрешено только суперпользователям; предоставить доступ можно с помощью инструкции GRANT.

Не допускается запуск в фоновых обработчиках команд CREATE INDEX и REINDEX: это может привести к зависанию фонового обработчика и процесса (или цепочки процессов), которые их породили.

Установка

Установка расширения для ОС «Альт» и Astra Linux:

sudo apt-get install /usr/pangolin-6.3/3rdparty/pg_background/pangolin-pg-background-1.0-{OS}.x86_64.rpm -y

Для других ОС:

sudo dnf install /usr/pangolin-6.3/3rdparty/pg_background/pangolin-pg-background-1.0-{OS}.x86_64.rpm -y

Далее вручную, при наличии прав администратора СУБД:

CREATE EXTENSION pg_background SCHEMA ext;

Настройка

Настройка не требуется.

Использование модуля

Пользователь, который запустил команду в фоновом процессе, может отменить ее выполнение при помощи стандартной функции pg_cancel_backend (pid integer) или удалить фоновый процесс, используя стандартный вызов pg_terminate_backend (pid integer). Здесь pid - pid фонового процесса, полученный ранее в результате pg_background_launch. Оба действия разрешены:

  • самому пользователю;
  • ролям, являющимся членами роли, для которой отменяется команда / удаляется процесс;
  • если команда запущена не от суперпользователя, то суперпользователям и ролям, которым выдано право pg_signal_backend;
  • если команда запущена от суперпользователя, то остальным суперпользователям.

Подробно о функциях с типом результата RECORD

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

First_db=> SELECT * FROM pg_background_result(pg_background_launch('SELECT true'));
ERROR: a column definition list is required for functions returning "record"
LINE 1: SELECT * FROM pg_background_result(pg_background_launch('SEL...

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

First_db=> SELECT * FROM pg_background_result(pg_background_launch('SELECT true')) AS (col1 INTEGER);
ERROR: remote query result rowtype does not match the specified FROM clause rowtype

Исправить ошибку можно так:

First_db=> SELECT * FROM pg_background_result(pg_background_launch('SELECT true')) AS (col1 BOOLEAN);
col1
------
t
(1 row)

Наилучший способ для pg_background_result - использовать text для команд, которые не предполагают выборку записей и объявлять фактический тип результата тогда, когда предстоит выбирать результат:

First_db=> SELECT * FROM pg_background_result(pg_background_launch('INSERT INTO log VALUES (1, ''Шаг 01'', ''Начало обработки'')')) as (result TEXT);
result
------------
INSERT 0 1
(1 row)
First_db=> \d log
Table "sch1.log"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
i | integer | | |
step | text | | |
result | text | | |
First_db=> SELECT * FROM pg_background_result(pg_background_launch('SELECT i, step, result FROM log')) AS (i integer, step text, result text);
i | step | result
---+--------+------------------
1 | Шаг 01 | Начало обработки
(1 row)

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

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

Ссылки на документацию разработчика

Дополнительно поставляемый модуль pg_background: https://github.com/vibhorkum/pg_background/blob/master/README.md