×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

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

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

Глава 5.11. Фоновые рабочие процессы

Digital Q.DataBase может быть расширена для запуска пользовательского кода в отдельных процессах. Такие процессы запускаются, останавливаются и отслеживаются процессом postgres, что позволяет обеспечить их жизненный цикл, тесно связанный со статусом сервера. Эти процессы подключаются к Digital Q.DataBaseобласти разделяемой памяти и имеют возможность внутреннего подключения к базам данных; они также могут последовательно выполнять несколько транзакций, подобно обычному серверному процессу, обслуживающему клиентское соединение. Кроме того, благодаря связыванию с libpq они могут подключаться к серверу и функционировать как обычное клиентское приложение.

Предупреждение

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

Фоновые рабочие процессы могут быть инициализированы в момент, когда запускается Digital Q.DataBase, путем включения имени модуля в shared_preload_libraries. Модуль, предназначенный для запуска фонового рабочего процесса, может зарегистрировать его, вызвав RegisterBackgroundWorker(BackgroundWorker *worker) из своей _PG_init() . Фоновые рабочие процессы также могут быть запущены после того, как система уже работает, путем вызова RegisterDynamicBackgroundWorker(BackgroundWorker *worker, BackgroundWorkerHandle **handle). В отличие от RegisterBackgroundWorker, которая может быть вызвана только из процесса postmaster, RegisterDynamicBackgroundWorker должна быть вызвана из обычного обслуживающего процесса или другого фонового рабочего процесса.

Структура BackgroundWorker определяется следующим образом:

typedef void (*bgworker_main_type)(Datum main_arg);
typedef struct BackgroundWorker
{
    char        bgw_name[BGW_MAXLEN];
    char        bgw_type[BGW_MAXLEN];
    int         bgw_flags;
    BgWorkerStartTime bgw_start_time;
    int         bgw_restart_time;       /* в секундах или BGW_NEVER_RESTART */
    char        bgw_library_name[MAXPGPATH];
    char        bgw_function_name[BGW_MAXLEN];
    Datum       bgw_main_arg;
    char        bgw_extra[BGW_EXTRALEN];
    pid_t       bgw_notify_pid;
} BackgroundWorker;

bgw_name и bgw_type — это строки, используемые в сообщениях журналов, списках процессов и аналогичных контекстах. bgw_type должно быть одинаковым для всех фоновых рабочих процессов одного типа, чтобы их можно было, например, сгруппировать в списке процессов. bgw_name напротив, может содержать дополнительную информацию о конкретном процессе. (Обычно строка для bgw_name будет так или иначе содержать тип, хотя это не является строго обязательным.)

bgw_flags представляет собой битовую маску, полученную побитовым ИЛИ и указывающую на возможности, необходимые модулю. Допустимые значения:

BGWORKER_SHMEM_ACCESS

Запрашивает доступ к разделяемой памяти. Данный флаг является обязательным.

BGWORKER_BACKEND_DATABASE_CONNECTION

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

bgw_start_time определяет состояние сервера, при котором postgres должен запустить процесс; это может быть одно из BgWorkerStart_PostmasterStart (запуск сразу после того, как postgres завершит собственную инициализацию; процессы, запрашивающие данный режим, не могут подключаться к базам данных), BgWorkerStart_ConsistentState (запуск сразу после достижения согласованного состояния в режиме горячего резерва, что позволяет процессам подключаться к базам данных и выполнять запросы только для чтения), и BgWorkerStart_RecoveryFinished (запуск сразу после перехода системы в обычный режим чтения-записи). Обратите внимание, что последние два значения эквивалентны для сервера, не находящегося в режиме горячего резерва. Обратите внимание, что данный параметр определяет только время запуска процессов; они не прекращают работу при переходе системы в другое состояние.

bgw_restart_time это интервал в секундах, который postgres должен выждать перед перезапуском процесса в случае его аварийного завершения. Это может быть любое положительное значение или BGW_NEVER_RESTART, указывающее на то, что процесс не следует перезапускать в случае аварийного завершения.

bgw_library_name — это имя библиотеки, в которой следует искать начальную точку входа для фонового рабочего процесса. Указанная библиотека будет динамически загружена рабочим процессом, и bgw_function_name будет использоваться для идентификации вызываемой функции. При вызове функции из основного кода это значение должно быть установлено в "postgres".

bgw_function_name это имя функции, используемой в качестве начальной точки входа для нового фонового рабочего процесса. Если эта функция находится в динамически загружаемой библиотеке, она должна быть помечена PGDLLEXPORT (а не static).

bgw_main_arg — это Datum аргумент основной функции фонового рабочего процесса. Эта основная функция должна принимать единственный аргумент типа Datum и возвращать void. bgw_main_arg будет передано в качестве аргумента. Кроме того, глобальная переменная MyBgworkerEntry указывает на копию BackgroundWorker структуры, переданной во время регистрации; фоновому рабочему процессу может быть полезно изучить эту структуру.

В Windows (и везде, где EXEC_BACKEND определено), а в динамических фоновых рабочих процессах передача данных небезопасна Datum по ссылке, только по значению. Если требуется передать аргумент, наиболее безопасным способом является передача значения типа int32 или другого значения небольшого размера для его использования в качестве индекса в массиве, размещенном в разделяемой памяти. Если значение типа cstring или text передается напрямую, то соответствующий указатель не будет действителен в новом фоновом рабочем процессе.

bgw_extra может содержать дополнительные данные для передачи фоновому рабочему процессу. В отличие от bgw_main_arg, эти данные не передаются в качестве аргумента основной функции рабочего процесса, но к ним можно получить доступ через MyBgworkerEntry, как было указано выше.

bgw_notify_pid представляет собой PID серверного процесса Digital Q.DataBase, которому postmaster должен отправить сигнал SIGUSR1 при запуске или завершении процесса. Значение этого поля должно быть равно 0 для фоновых рабочих процессов, зарегистрированных во время запуска postmaster, а также когда серверный процесс, регистрирующий рабочий процесс, не должен ожидать его запуска. В противном случае поле должно быть инициализировано значением MyProcPid.

После запуска процесс может подключиться к базе данных, вызвав функцию BackgroundWorkerInitializeConnection(char *dbname, char *username, uint32 flags) или BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags). Это позволяет процессу выполнять транзакции и запросы посредством SPI интерфейса. Если dbname имеет значение NULL или dboid имеет значение InvalidOid, сеанс не подключен к какой-либо конкретной базе данных, но допускается доступ к общим каталогам. Если username имеет значение NULL или useroid имеет значение InvalidOid, процесс будет запущен от имени суперпользователя, созданного в ходе initdb. Если BGWORKER_BYPASS_ALLOWCONN указано как flags предусмотрена возможность обхода ограничения на подключение к базам данных, не допускающим пользовательские соединения. Если BGWORKER_BYPASS_ROLELOGINCHECK указано как flags можно обойти проверку входа для роли, используемой при подключении к базам данных. Фоновый рабочий процесс может вызвать только одну из этих двух функций и только один раз. Переключение между базами данных невозможно.

Сигналы изначально заблокированы в момент передачи управления основной функции фонового рабочего процесса и должны быть разблокированы им самостоятельно; это позволяет процессу при необходимости настроить собственные обработчики сигналов. Сигналы в новом процессе можно разблокировать путем вызова функции BackgroundWorkerUnblockSignals и заблокировать, вызвав функцию BackgroundWorkerBlockSignals.

Если bgw_restart_time для фонового рабочего процесса настроено как BGW_NEVER_RESTART, или если он завершается с кодом выхода 0, либо принудительно останавливается функцией TerminateBackgroundWorker, он будет автоматически разрегистрирован процессом postmaster при выходе. В противном случае он будет перезапущен по истечении периода времени, заданного через параметр bgw_restart_time, или немедленно, если postmaster выполняет повторную инициализацию кластера из-за сбоя обслуживающего процесса. Обслуживающим процессам, которым требуется лишь временная приостановка выполнения, следует использовать прерываемую задержку (sleep) вместо завершения работы; этого можно достичь путём вызова функции WaitLatch(). Убедитесь, что флаг WL_POSTMASTER_DEATH установлен при вызове этой функции, и проверьте код возврата для обеспечения немедленного выхода в экстренном случае, когда процесс postgres сам прекратил работу.

Когда фоновый рабочий процесс регистрируется с помощью функции RegisterDynamicBackgroundWorker , обслуживающий процесс, выполняющий регистрацию, может получать сведения о состоянии этого рабочего процесса. Бэкенды, желающие выполнить это действие, должны передать адрес структуры BackgroundWorkerHandle * в качестве второго аргумента функции RegisterDynamicBackgroundWorker. Если фоновый рабочий процесс успешно зарегистрирован, этот указатель будет инициализирован непрозрачным дескриптором, который впоследствии можно передать в функции GetBackgroundWorkerPid(BackgroundWorkerHandle *, pid_t *) или TerminateBackgroundWorker(BackgroundWorkerHandle *). GetBackgroundWorkerPid может использоваться для опроса статуса фонового рабочего процесса: возвращаемое значение BGWH_NOT_YET_STARTED указывает на то, что фоновый рабочий процесс еще не был запущен постмастером; BGWH_STOPPED указывает на то, что он был запущен, но более не выполняется; и BGWH_STARTED указывает на то, что он выполняется в данный момент. В последнем случае значение PID также будет возвращено через второй аргумент. TerminateBackgroundWorker заставляет постмастер отправить сигнал SIGTERM фоновому рабочему процессу, если он выполняется, и отменить его регистрацию, как только он завершится.

В некоторых случаях процесс, регистрирующий фоновый рабочий процесс, может использовать режим ожидания запуска этого процесса. Этого можно добиться путем инициализации bgw_notify_pid в MyProcPid и затем передав BackgroundWorkerHandle * полученный во время регистрации, в WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *) . Данная функция будет заблокирована до тех пор, пока процесс postmaster не предпримет попытку запуска фонового рабочего процесса или пока процесс postmaster не завершит работу. Если фоновый рабочий процесс запущен, возвращаемым значением будет BGWH_STARTED, а PID будет записан по указанному адресу. В противном случае возвращаемое значение будет BGWH_STOPPED или BGWH_POSTMASTER_DIED.

Процесс также может ожидать завершения работы фонового рабочего процесса, используя WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *handle) и передав BackgroundWorkerHandle * полученный при регистрации. Эта функция будет заблокирована до тех пор, пока фоновый рабочий процесс не завершит работу или пока не завершится процесс postmaster. Когда фоновый рабочий процесс завершается, возвращаемое значение — BGWH_STOPPED, если процесс postmaster завершится, она вернет BGWH_POSTMASTER_DIED.

Фоновые рабочие процессы могут отправлять асинхронные уведомления либо с помощью команды NOTIFY команды с помощью SPI, или напрямую через Async_Notify(). Такие уведомления будут отправлены при фиксации транзакции. Фоновые рабочие процессы не должны регистрироваться для получения асинхронных уведомлений с помощью LISTEN , так как инфраструктура для обработки таких уведомлений рабочим процессом отсутствует.

В src/test/modules/worker_spi модуле содержится рабочий пример, демонстрирующий ряд полезных приемов.

Максимальное количество зарегистрированных фоновых рабочих процессов ограничено параметром max_worker_processes.

Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению