34.2. Как это работает
Работая в обычном режиме, Postgres Pro запускает отдельный обслуживающий процесс для каждого входящего подключения. При включении пула соединений число обслуживающих процессов, которые могут использоваться для отдельно взятой базы данных, ограничивается значением session_pool_size. При достижении этого ограничения главный процесс postmaster
перестаёт запускать новые обслуживающие процессы для соответствующих сеансов и передаёт последующие подключения одному из уже запущенных процессов. Так как один обслуживающий процесс Postgres Pro может работать только с одной базой данных, во встроенном пуле приходится поддерживать отдельные пулы соединений для каждой отдельной базы данных. Число таких пулов неограниченно: при появлении подключения к новой базе добавляется новый пул.
Для назначения сеанса соответствующему пулу postmaster
должен узнать целевую базу данных, запрошенную клиентом, а для этого требуется получить и разобрать поступающий от клиента стартовый пакет. Чтобы эта процедура не стала узким местом, postmaster
делегирует её одному из процессов-приёмников. Приёмник обрабатывает стартовый пакет и возвращает результат главному процессу. В зависимости от полученной информации, postmaster
выбирает подходящий для этого клиента пул и передаёт в него соединение, используя механизм передачи дескрипторов файлов.
Примечание
Пул соединений можно отключить для некоторых пользователей или баз данных, перечислив их имена в параметрах dedicated_users и dedicated_databases, соответственно. Для таких пользователей и баз данных будут использоваться выделенные обслуживающие процессы в неограниченном количестве, то есть у этих соединений будет приоритет с точки зрения доступа к системным ресурсам.
Так как реализация пула на более низком уровне потребовала бы кардинально изменить механизм блокировок Postgres Pro, пул функционирует только на уровне транзакций. Это означает, что обслуживающий процесс может переключиться на выполнение другого сеанса только после завершения текущей транзакции. Однако встроенный пул сохраняет окружения сеансов для соединений, так что все изменения в контексте сеанса, производимые клиентским приложением, например, модифицированные параметры конфигурации сеанса, подготовленные операторы или временные таблицы, сохраняются/восстанавливаются при переключении обслуживающего процесса с одного сеанса на другой. Пул pgbouncer, напротив, поддерживает семантику сеансов только в сеансовом режиме, в котором число запускаемых обслуживающих процессов не ограничивается.
Сеансы, обслуживаемые пулом, привязываются к своим процессам и не могут перемещаться от одного к другому, так как для переноса потребовалось бы сериализовать и передать весь контекст сеанса, что является весьма нетривиальной задачей. По умолчанию обслуживающие процессы продолжают работать, даже когда все назначенные им сеансы завершаются. Для изменения этого поведения вы можете воспользоваться параметрами конфигурации restart_pooler_on_reload и idle_pool_worker_timeout.