pg_background

Запуск команд в фоновом режиме.
Схема размещения: 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
oidOID базы данных
datname
nameИмя базы данных
pid
integerИдентификатор процесса
leader_pid
integerИдентификатор ведущего процесса
usesysid
oidOID пользователя
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, то в этом поле отображается запрос, который выполняется в настоящий момент. Если процесс находится в любом другом состоянии, то в этом поле отображается последний выполненный запрос

Ограничения

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

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

Пользователь, который запустил команду в фоновом процессе, может отменить ее выполнение при помощи стандартной функции pg_cancel_backend (pid integer) или удалить фоновый процесс, используя стандартный вызов pg_terminate_backend (pid integer). Здесь pid - pid фонового процесса, полученный ранее в результате pg_background_launch. Оба действия разрешены:
  • самому пользователю;
  • ролям, являющимся членами роли, для которой отменяется команда / удаляется процесс;
  • если команда запущена не от суперпользователя, то суперпользователям и ролям, которым выдано право pg_signal_backend;
  • если команда запущена от суперпользователя, то остальным суперпользователям.
Для функции, возвращающей 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('SELECT ... ') )
При каждом использовании такой функции тип результата необходимо объявить отдельно. При этом важно заранее задать структуру записи так, чтобы она соответствовала фактическим записям результата или хотя бы допускала неявное преобразование типов полей. При несовместимости объявленной структуры записи с фактической структурой результата возникнет другая ошибка:
Раскрыть type=sql
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
Исправить ошибку можно так:
Раскрыть type=sql
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, но это не отменяет инициализации типа результата перед вызовом функции.
Предыдущий раздел
pageinspect
Следующий раздел
pg_buffercache
Была ли страница полезной?