PgDoorman vs PgBouncer vs Odyssey

Сравнительная матрица фич для выбора пулера соединений PostgreSQL. Каждое утверждение про PgBouncer привязано к config reference и changelog; каждое утверждение про Odyssey — к docs проекта.

PgCat намеренно опущен: у него центр тяжести — шардинг и балансировка, а не drop-in замена PgBouncer, поэтому построчное сравнение вводит в заблуждение. Если нужен горизонтальный шардинг, см. репозиторий PgCat.

Цифры из бенчмарков — Бенчмарки.

Аутентификация

ВозможностьPgDoormanPgBouncerOdyssey
MD5 passwordДаДаДа
SCRAM-SHA-256 (клиент → пулер)ДаДаДа
Сквозной SCRAM-SHA-256 (без открытого пароля в конфиге)Да (ClientKey извлекается из proof клиента)Да (с 1.14, encrypted SCRAM secret в auth_query / userlist.txt)Да
Сквозной MD5ДаДаДа
auth_query (динамические пользователи)ДаДаДа
Сквозной режим auth_query (своя идентичность PostgreSQL для каждого пользователя)ДаНет (один auth_user на все lookup-запросы)Да
Файл в формате pg_hba.confДа (файл или inline)Да (auth_hba_file)Да (с 1.4)
PAMДа (Linux)Да (auth_type=pam или через HBA)Да
JWT (RSA-SHA256)ДаНетНет
Talos (custom JWT с извлечением роли)Да (специфика Ozon)НетНет
LDAPНетДа (с 1.25)Да
SCRAM channel binding (scram-sha-256-plus)НетДаДа
User-name maps (cert/peer → DB user)НетДа (с 1.23)Да
Тонкая настройка scram_iterationsНетДа (с 1.25)Нет

См. Аутентификация.

TLS

ВозможностьPgDoormanPgBouncerOdyssey
Client-side TLS (режимы: disable, allow, require, verify-full)ДаДа (disable, allow, prefer, require, verify-ca, verify-full)Да
Server-side TLS к PostgreSQL (disable, allow, require, verify-ca, verify-full)Да (5 режимов)Да (server_tls_*, 6 режимов вкл. prefer)Нет
mTLS к PostgreSQL (отправка клиентского сертификата на backend)Да (server_tls_certificate + server_tls_private_key)Да (server_tls_key_file + server_tls_cert_file)Нет
Hot reload server-side TLS-сертификатовДа (SIGHUP)Да (через RELOAD / SIGHUP, "new file contents will be used for new connections")Нет
Hot reload client-facing TLS-сертификатовНет (требуется restart или горячая замена процесса)Да (через RELOAD / SIGHUP)Нет
Минимальная версия TLS настраиваетсяДа (по умолчанию TLS 1.2)Да (tls_protocols, default tlsv1.2,tlsv1.3)Настраивается, дефолты другие
Direct TLS handshake (PostgreSQL 17, без SSLRequest)НетДа (с 1.25)Нет
Контроль TLS 1.3 cipher suitesНетДа (с 1.25, client_tls13_ciphers/server_tls13_ciphers)Нет
Миграция TLS-сессии при горячей замене процессаДа (сборка tls-migration, Linux, по запросу)Нет (TLS-соединения отбрасываются при online restart)Нет

См. TLS.

Маршрутизация и высокая доступность

ВозможностьPgDoormanPgBouncerOdyssey
Fallback через Patroni (встроенный lookup /cluster)ДаНетНет
Bundled TCP-прокси с маршрутизацией по ролям (patroni_proxy)ДаНетНет
Защита от лага репликДа (max_lag_in_bytes в patroni_proxy)НетДа (watchdog_lag_query + catchup_timeout)
Несколько хостов PostgreSQL с балансировкойДа (patroni_proxy)Да (с 1.24, load_balance_hosts)Да
target_session_attrs (read-write / read-only routing)Да (через роли patroni_proxy)НетДа
Sequential routing rules (правило-в-порядке-первое-совпадение)НетНетДа
Маршрутизация по типу соединения (TCP vs UNIX)НетНетДа
Выбор хоста с учётом availability zoneНетНетДа

См. Fallback через Patroni, patroni_proxy.

Пулинг

ВозможностьPgDoormanPgBouncerOdyssey
Режимы пулаsession, transactionsession, transaction, statementsession, transaction
Координатор пулов (лимит на базу с приоритетным вытеснением)Да (max_db_connections + вытеснение по p95)Нет (max_db_connections ставит клиентов в очередь, пока существующие соединения не закроются по idle timeout)Нет
Резервный пулДа (reserve_pool_size)Да (reserve_pool_size)Нет
Per-user min_guaranteed_pool_sizeДаНетНет
Опережающая замена при истечении server_lifetime (warm-up до экспирации старого)Да (порог 95%, до 3 параллельных)НетНет
Упреждающее ожидание и ограничение всплеска (scaling_warm_pool_ratio, быстрые повторы)ДаНетНет
Прямая передача (возвращающееся соединение уходит самому давно ждущему клиенту через in-process oneshot-канал)ДаНетНет
Строгий FIFO порядок ожидающихДаНет (LIFO через server_round_robin = 0)Нет
min_pool_size (warm connections)ДаНетДа
Prepared statements в transaction modeДа (именованные и анонимные, двухуровневый кеш, query interner)Да (именованные, с 1.21, max_prepared_statements)Да (именованные, pool_reserve_prepared_statement)
Кеш анонимного Parse для производительностиДа (DOORMAN_N, переиспользование между клиентами пула)Нет (анонимный Parse проходит без изменений)Нет (требуются именованные prepared statements)
Умная очистка при возврате соединения (пропустить DEALLOCATE ALL, если кеш не менялся)Да (RESET ALL / DEALLOCATE ALL по факту мутаций)Нет (всегда DISCARD ALL, если задан server_reset_query)Да (auto)
LISTEN / NOTIFY pinning в transaction modeНетНетЭкспериментально
Cross-rule connection cap (shared_pool)НетНетДа (с 1.5.1)
Команды администратора PAUSE / RESUME / RECONNECTДаДаДа (с 1.4.1)
GUC PostgreSQL на уровне пула в backend StartupMessageДа (startup_parameters: general → пул → passthrough auth_query; клиентские RESET ALL / DISCARD ALL возвращают эти значения; ошибки PG при запуске бэкенда доходят до клиента без переписывания)Нет эквивалентных операторских значений по умолчанию; отдельные клиентские startup-параметры можно отслеживать или игнорироватьНет (maintain_params сохраняет клиентские параметры при rebind; операторских GUC нет)

См. Координатор пулов, Пул под нагрузкой.

Лимиты и таймауты

ВозможностьPgDoormanPgBouncerOdyssey
server_idle_check_timeout (probe перед checkout)ДаНетНет
idle_timeout (server-side)Да (idle_timeout)Да (server_idle_timeout)Да
server_lifetimeДаДаДа
query_wait_timeoutДаДаДа
client_idle_timeoutНетДа (с 1.24)Нет
transaction_timeout (enforced пулером)НетДа (с 1.25)Нет
max_user_client_connectionsНетДа (с 1.24)Нет
max_db_client_connectionsНетДа (с 1.24)Нет
Per-user query_timeoutНетДа (с 1.24)Нет
Per-user reserve_pool_sizeНетДа (с 1.24)Нет
Уведомление клиента, пока тот ждёт серверное соединениеНетДа (с 1.25, query_wait_notify)Да (pool_notice_after_waiting_ms)

См. Справочник по general-настройкам, Справочник по pool-настройкам.

Наблюдаемость

ВозможностьPgDoormanPgBouncerOdyssey
Встроенная веб-консоль администратораДа (HTML-консоль на том же порту, что и /metrics, включается через [web].ui)Нет (только psql admin-консоль)Нет (только psql admin-консоль)
Prometheus-эндпоинтВстроенный /metricsВнешний (pgbouncer_exporter)Внешний (Go-exporter sidecar, опрашивает admin-консоль)
Перцентили задержки на пул (p50, p90, p95, p99)Да (HDR Histogram)Нет (только средние в SHOW STATS)Да через exporter (TDigest, требует rule-опцию quantiles)
Счётчики prepared statements в SHOW STATSДаДа (с 1.24)Нет
Структурированные JSON-логиДа (--log-format structured)НетДа (log_format "json")
Управление уровнем логов в рантайме (SET log_level)ДаНетНет
SHOW POOL_COORDINATOR / SHOW POOL_SCALING / SHOW SOCKETSДаНетНет
SHOW PREPARED_STATEMENTSДаНетНет
SHOW INTERNER (записи / байты / предпросмотр по половинам)ДаНетНет
Ограниченный prepared-кеш (TTL у анонимных, клиентский LRU с разделением Named/Anonymous)ДаТолько named, с лимитом max_prepared_statements; анонимного кеша нетНет
SHOW HOSTS (CPU/память хоста)НетНетДа
SHOW RULES (дамп активной маршрутизации)НетНетДа
Метрики server-side TLS-соединений (длительность handshake, ошибки, активные)ДаНетНет
Метрики Patroni APIДаНетНет
Метрики fallback (active flag, текущий хост, hits)ДаНетНет

См. Справочник Prometheus-метрик, Команды администратора.

Эксплуатация

ВозможностьPgDoormanPgBouncerOdyssey
Горячая замена процесса с миграцией сессий (TCP-сокет, cancel keys, prepared cache)Да (SCM_RIGHTS, плюс TLS state со сборкой tls-migration)Нет: -R deprecated с 1.20; rolling restart через so_reuseport оставляет старые сессии на старом процессеНет: SIGUSR2 + bindwith_reuseport оставляет старые сессии на старом процессе
Формат конфигаYAML или TOMLINIСвой формат (lex/yacc)
Человекочитаемые длительности и размеры (30s, 1h, 256MB)ДаНет (целые микросекунды / байты)Нет
Режим проверки конфига (pg_doorman -t)ДаНетНет
Авто-конфиг из PostgreSQL (pg_doorman generate --host)ДаНетНет
Перезагрузка по SIGHUPДа (серверные TLS-сертификаты включены; клиентский TLS требует рестарта)Да (auth_file, auth_hba_file, server и client TLS certs)Да
systemd sd-notify (Type=notify)ДаНетНет
Лимит памяти (max_memory_usage)ДаНетНет
Лимит TCP-буферовДа (tcp_socket_buffer_size для клиентских TCP-сокетов и TCP-сокетов к PostgreSQL)Да (tcp_socket_buffer)Нет

См. Горячая замена процесса с переносом сессий, Сигналы.

Протокол

ВозможностьPgDoormanPgBouncerOdyssey
Simple queryДаДаДа
Extended queryДаДаЧастично
Pipelined batchesДаДаЧастично
Async FlushДаДаНет
Cancel requests поверх TLSДаДаДа
COPY IN / COPY OUTДаДаДа
Replication passthrough (replication=true startup)НетДа (с 1.23)Нет
Согласование версии протокола (3.2)НетДа (с 1.23)Нет
server_drop_on_cached_plan_errorНетНетДа (с 1.5.1)

Когда PgDoorman не подойдёт

  • Нужна LDAP-аутентификация. Используйте Odyssey или PgBouncer 1.25+.
  • Нужен replication passthrough для logical replication tools. Используйте PgBouncer 1.23+.
  • Нужен transaction_timeout, который применяет сам пулер. Используйте PgBouncer 1.25+.
  • Нужен горизонтальный шардинг внутри пулера. Используйте PgCat.

Если нужны prepared statements в transaction mode, Patroni HA без внешних прокси, многопоточная пропускная способность с одним общим пулом и горячая замена процесса с миграцией живых сессий — PgDoorman ближе по профилю.