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

Имя столбца

Тип

Описание

datid

oid

OID базы данных

datname

name

Имя базы данных

pid

integer

Идентификатор процесса

leader_pid

integer

Идентификатор ведущего процесса

usesysid

oid

OID пользователя

usename

name

Имя пользователя

application_name

text

Название приложения

backend_start

timestamptz

Время запуска процесса

xact_start

timestamptz

Время начала текущей транзакции или NULL при отсутствии активной транзакции

query_start

timestamptz

Время начала выполнения запроса, активного в момент сохранения данных, или, если поле state не active, то время начала выполнения последнего запроса

state_change

timestamptz

Время последнего изменения состояния (поле state)

wait_event_type

text

Тип события, который ждет обслуживающий процесс, если это ожидание имеет место, в противном случае — NULL

wait_event

text

Имя ожидаемого события, если обслуживающий процесс находится в состоянии ожидания, в противном случае — NULL

state

text

Общее текущее состояние этого серверного процесса

backend_xid

xid

Идентификатор верхнего уровня транзакции этого серверного процесса или любой другой

backend_xmin

xid

Текущая граница xmin для серверного процесса

query

text

Текст последнего запроса этого серверного процесса. Если поле state имеет значение active, то в этом поле отображается запрос, который выполняется в настоящий момент. Если процесс находится в любом другом состоянии, то в этом поле отображается последний выполненный запрос

Доработка#

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

Ограничения#

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

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

Установка#

Установка расширения для ALT SP8, AstraLinux:

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