Координатор пулов
Координатор пулов ограничивает суммарное число серверных соединений к одной базе по всем пользователям пула. Когда лимит выбран, он может освободить слот: закрыть свободное соединение у пользователя с запасом и отдать этот слот тому, кто сейчас ждёт подключение к PostgreSQL.
Эта страница объясняет модель и сценарии применения. Рецепты настройки и разбор вывода SHOW POOL_COORDINATOR смотрите в Пуле под нагрузкой.
Какую задачу решает
Без координатора каждый пользовательский пул независим. pool_size равный 40 у пяти пользователей означает до 200 серверных соединений, и PostgreSQL приходится защищать свои лимиты уже на своей стороне.
max_db_connections в PgBouncer ограничивает общую сумму, но как только лимит достигнут, новые клиенты просто становятся в очередь. Соединения освобождаются только тогда, когда их текущий владелец сам закроет их по server_idle_timeout. Кто первым занял слоты, тот и удерживает их независимо от интенсивности использования, а медленные нагрузки никогда не уступают быстрым.
Координатор в pg_doorman ограничивает сумму и:
- Вытесняет свободные соединения у пользователей с запасом, когда другому пользователю нужно вырасти.
- Ранжирует пользователей по p95 времени транзакции, чтобы самые медленные пулы уступали слоты первыми. Пулы с быстрыми транзакциями сохраняют преимущество переиспользования; пулы с длинными транзакциями простаивают большую долю времени, поэтому забрать у них слот стоит дешевле.
- Резервирует небольшое переполнение для коротких всплесков. Настраивается отдельно от основного лимита.
- Защищает минимальный размер пула на пользователя. Соединения ниже этого минимума не вытесняются.
Когда использовать
Включайте координатор, когда:
- На одной базе работают разные приложения или пользователи, и нужен верхний предел числа серверных соединений (
max_connectionsPostgreSQL, RAM, файловые дескрипторы). - Одна нагрузка приходит всплесками и должна временно забирать простаивающие слоты у других, не закрепляя их за собой навсегда.
- Вы работаете рядом с потолком соединений PostgreSQL и хотите управляемую деградацию вместо зависимости от того, кто первым занял слоты.
Координатор не нужен, когда:
pool_sizeкаждого пользователя достаточно мал, чтобы их сумма укладывалась вmax_connectionsPostgreSQL с запасом.- Нагрузки предсказуемы и заранее размечены.
- Вы хотите простоту уровня PgBouncer.
max_db_connectionsбез вытеснения поддерживается, но не рекомендуется для общих баз.
Конфигурация
pools:
shared_db:
server_host: "127.0.0.1"
server_port: 5432
pool_mode: "transaction"
# Общий лимит на всех пользователей этого пула.
max_db_connections: 80
# Резерв сверх max_db_connections для коротких всплесков.
# Захватывается, только если в течение reserve_pool_timeout не нашлось свободного соединения.
reserve_pool_size: 16
reserve_pool_timeout: "3s"
# Страховка для пользователя: соединения никогда не вытесняются у него, даже под давлением.
# Сумма по пользователям должна быть <= max_db_connections.
min_guaranteed_pool_size: 5
# Льготный период для вытеснения: соединения младше этого возраста не вытесняются.
# Защищает от колебания, когда нагрузка кратковременно простаивает.
min_connection_lifetime: "30s"
users:
- username: "fast_app"
password: "md5..."
pool_size: 40
- username: "batch_job"
password: "md5..."
pool_size: 60
Эффективный потолок: max_db_connections + reserve_pool_size = 96. Резерв поглощает короткие пики; если пик затягивается, включается вытеснение.
Как выбирается донор
Когда пользователь запрашивает новое серверное соединение, а лимит уже достигнут:
- Найти кандидатов со свободными соединениями. Пользователь, у которого все соединения активны, не может стать донором: его работа ещё выполняется.
- Пропустить защищённых. Пользователь ниже
min_guaranteed_pool_sizeисключается. - Пропустить недавно созданные соединения. Соединения младше
min_connection_lifetimeне вытесняются; это снижает колебания при коротких простоях. - Ранжировать по излишку. Пользователи с наибольшим числом свободных соединений сверх
min_guaranteed_pool_sizeполучают высший ранг. - Разрешить ничью по p95 времени транзакции. Среди пулов с одинаковым излишком первым уступает тот, у кого выше p95. Высокий p95 означает, что каждая транзакция дольше держит соединение, а значит одно вытеснение ломает меньше повторных выдач.
Выбранное свободное соединение закрывается; запрашивающий пользователь получает новое соединение из PostgreSQL.
Мониторинг
SHOW POOL_COORDINATOR показывает текущее состояние по каждой базе:
database | max_db_conn | current | reserve_size | reserve_used | evictions | reserve_acq | exhaustions
shared_db | 80 | 78 | 16 | 2 | 142 | 18 | 0
evictionsбыстро растёт — один пользователь регулярно остаётся без слотов. Поднимитеmax_db_connectionsили задайте этому пользователюmin_guaranteed_pool_size.reserve_acqвысокий — всплески нормальны, но размер занижен; рассмотрите повышениеmax_db_connectionsвместо опоры на резерв.exhaustionsненулевой — резерв тоже был полным. Клиенты упёрлись вquery_wait_timeout, ожидая бэкенд. Поднимите лимит.
Prometheus: pg_doorman_pool_coordinator{type="..."} (gauge) и pg_doorman_pool_coordinator_total{type="evictions|reserve_acquisitions|exhaustions"} (counter). Смотрите Команды администратора и Справочник Prometheus.
Оговорки
- Координатор работает только внутри одного пула (одной базы). Кросс-пуловые / кросс-баз ограничения не поддерживаются.
- Вытеснение выбирает только свободные соединения. Пользователь, удерживающий все соединения в длинных транзакциях, не может стать донором, и другие пользователи могут ждать. Если ваша нагрузка устроена именно так, поднимите
max_db_connectionsили разделите её по пулам. min_guaranteed_pool_size— это нижняя граница для вытеснения, а неmin_pool_sizeдля прогрева. Эти соединения пул всё равно создаёт по требованию.- Задавать
max_db_connectionsбезmin_guaranteed_pool_size— это режим PgBouncer: работает, но мелкие пользователи голодают под давлением. Для общих баз всегда задавайте оба.
Куда дальше
- Как подобрать размер пула с разобранными примерами: Пул под нагрузкой → Согласование лимита с PostgreSQL.
- Тюнинг под нагрузкой: Пул под нагрузкой → Параметры тюнинга.
- Чтение вывода администратора: Команды администратора → SHOW POOL_COORDINATOR.
- Режимы пула (транзакционный против сессионного): Режимы пула.