Настройки

Формат конфигурационного файла

pg_doorman поддерживает два формата конфигурационного файла:

  • YAML (.yaml, .yml) — основной и рекомендуемый формат для новых конфигураций.
  • TOML (.toml) — поддерживается для обратной совместимости с уже существующими конфигурациями.

Формат определяется автоматически по расширению файла. Оба формата поддерживают одни и те же опции конфигурации и могут использоваться взаимозаменяемо.

Пример конфигурации YAML (рекомендуется)

general:
  host: "0.0.0.0"
  port: 6432
  admin_username: "admin"
  admin_password: "change_me_to_a_long_random_secret"

pools:
  mydb:
    server_host: "localhost"
    server_port: 5432
    pool_mode: "transaction"
    users:
      - username: "myuser"
        password: "md5..."  # хеш из pg_shadow / pg_authid
        pool_size: 40

Пример конфигурации TOML (для совместимости)

[general]
host = "0.0.0.0"
port = 6432
admin_username = "admin"
admin_password = "change_me_to_a_long_random_secret"

[pools.mydb]
server_host = "localhost"
server_port = 5432
pool_mode = "transaction"

[[pools.mydb.users]]
username = "myuser"
password = "md5..."  # хеш из pg_shadow / pg_authid
pool_size = 40

Команда generate

Команда generate может выводить конфигурацию в любом из форматов. Формат определяется по расширению выходного файла. По умолчанию сгенерированная конфигурация содержит подробные inline-комментарии, поясняющие каждый параметр.

# Сгенерировать конфигурацию YAML (рекомендуется)
pg_doorman generate --output config.yaml

# Сгенерировать конфигурацию TOML (для обратной совместимости)
pg_doorman generate --output config.toml

# Сгенерировать полную справочную конфигурацию без подключения к PG
pg_doorman generate --reference --output config.yaml

# Сгенерировать справочную конфигурацию с комментариями на русском
pg_doorman generate --reference --ru --output config.yaml

# Сгенерировать конфигурацию без комментариев (только сериализация)
pg_doorman generate --no-comments --output config.yaml
ФлагОписание
--no-commentsОтключить inline-комментарии в сгенерированной конфигурации (по умолчанию комментарии включены)
--referenceСгенерировать полную справочную конфигурацию с примерами значений, без подключения к PostgreSQL
--russian-comments, --ruГенерировать комментарии на русском языке для быстрого старта
--format, -fФормат вывода: yaml (по умолчанию) или toml. Если задан --output, формат определяется по расширению файла. Этот флаг переопределяет автоопределение

Подключаемые файлы

Подключаемые файлы могут быть в любом из форматов, форматы можно смешивать. Например, основная конфигурация в YAML может подключать TOML-файлы и наоборот:

include:
  files:
    - "pools.yaml"
    - "users.toml"

Человекочитаемые значения

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

Формат продолжительности

Значения продолжительности можно задавать как:

  • Простые числа: интерпретируются как миллисекунды (например, 5000 = 5 секунд)
  • Строка с суффиксом:
    • ms — миллисекунды (например, "100ms")
    • s — секунды (например, "5s" = 5000 миллисекунд)
    • m — минуты (например, "5m" = 300000 миллисекунд)
    • h — часы (например, "1h" = 3600000 миллисекунд)
    • d — дни (например, "1d" = 86400000 миллисекунд)

Примеры:

general:
  # Все эти варианты эквивалентны (3 секунды):
  # connect_timeout: 3000      # обратная совместимость (миллисекунды)
  # connect_timeout: "3s"      # человекочитаемый формат
  # connect_timeout: "3000ms"  # явные миллисекунды
  connect_timeout: "3s"
  idle_timeout: "10m"        # 10 минут
  server_lifetime: "1h"      # 1 час

Формат размера в байтах

Значения размера в байтах можно задавать как:

  • Простые числа: интерпретируются как байты (например, 1048576 = 1 MB)
  • Строка с суффиксом (регистр не важен):
    • B — байты (например, "1024B")
    • K или KB — килобайты (например, "1K" или "1KB" = 1024 байта)
    • M или MB — мегабайты (например, "1M" или "1MB" = 1048576 байт)
    • G или GB — гигабайты (например, "1G" или "1GB" = 1073741824 байт)

Примечание: используются двоичные префиксы (1 KB = 1024 байта, не 1000 байт).

Примеры:

general:
  # Все эти варианты эквивалентны (256 MB):
  # max_memory_usage: 268435456  # обратная совместимость (байты)
  # max_memory_usage: "256MB"    # человекочитаемый формат
  # max_memory_usage: "256M"     # короткая форма
  max_memory_usage: "256MB"
  unix_socket_buffer_size: "1MB" # 1 MB
  worker_stack_size: "8MB"       # 8 MB

Общие настройки

host

Хост, на котором сервер будет принимать соединения (только TCP v4).

По умолчанию: "0.0.0.0".

port

Порт для входящих соединений.

По умолчанию: 5432.

backlog

TCP backlog для входящих соединений. При значении ноль в качестве TCP backlog используется значение max_connections.

По умолчанию: 0.

max_connections

Максимальное число клиентов, которые могут одновременно подключиться к пулеру. При достижении лимита:

  • Клиент, подключающийся без SSL, получит ожидаемую ошибку (код: 53300, сообщение: sorry, too many clients already).
  • Клиент, подключающийся через SSL, увидит сообщение о том, что сервер не поддерживает протокол SSL.

По умолчанию: 8192.

max_concurrent_creates

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

Большие значения ускоряют прогрев пула, но могут увеличить нагрузку на сервер PostgreSQL во время штормов соединений. Меньшие значения дают более плавное создание соединений.

По умолчанию: 4.

tls_mode

Режим TLS для входящих соединений. Может принимать одно из следующих значений:

  • allow — TLS-соединения разрешены, но не обязательны. pg_doorman попытается установить TLS-соединение, если клиент его запросит.
  • disable — TLS-соединения запрещены. Все соединения устанавливаются без шифрования TLS.
  • require — TLS-соединения обязательны. pg_doorman принимает только соединения, использующие TLS-шифрование.
  • verify-full — TLS-соединения обязательны, и pg_doorman проверяет клиентский сертификат. Этот режим обеспечивает максимальный уровень безопасности.

По умолчанию: "allow".

tls_ca_cert

Файл с CA-сертификатом для проверки клиентского сертификата. Обязателен, когда tls_mode установлен в verify-full.

По умолчанию: None.

tls_private_key

Путь к файлу приватного ключа для TLS-соединений. Требуется для включения TLS для входящих клиентских соединений. Должен использоваться вместе с tls_certificate.

По умолчанию: None.

tls_certificate

Путь к файлу сертификата для TLS-соединений. Требуется для включения TLS для входящих клиентских соединений. Должен использоваться вместе с tls_private_key.

По умолчанию: None.

tls_rate_limit_per_second

Ограничение числа одновременных попыток создания TLS-сессии. Любое значение, отличное от нуля, означает, что клиенты должны проходить через очередь для установки TLS-соединения. В некоторых случаях это необходимо, чтобы запустить приложение, которое открывает много соединений при старте (так называемый «горячий старт»).

По умолчанию: 0.

daemon_pid_file

Включение этого параметра активирует режим демона. Закомментируйте, если хотите запускать pg_doorman в foreground с флагом -d.

По умолчанию: "/tmp/pg_doorman.pid".

syslog_prog_name

Если задан, pg_doorman начинает отправлять сообщения в syslog (через /dev/log или /var/run/syslog). Закомментируйте, если хотите логировать в stdout.

По умолчанию: None.

log_client_connections

Логировать подключения клиентов для мониторинга.

По умолчанию: true.

log_client_disconnections

Логировать отключения клиентов для мониторинга.

По умолчанию: true.

worker_threads

Число worker-потоков Tokio runtime (потоков ОС) для обслуживания клиентских соединений. Производительность масштабируется линейно до числа ядер CPU. Также определяет число шардов для внутренних concurrent hash maps (worker_threads * 4, округлённо до ближайшей степени двойки, минимум 4). В Kubernetes задавайте этот параметр явно — автоматическое определение CPU может вернуть число ядер хоста, а не лимит контейнера.

По умолчанию: 4.

worker_cpu_affinity_pinning

Привязывать каждый worker-поток к отдельному ядру CPU (sched_setaffinity). Отключается, если доступно меньше 3 ядер.

По умолчанию: false.

tokio_global_queue_interval

Настройки Tokio runtime. Задаёт, как часто шедулер проверяет глобальную очередь задач. Параметры группы tokio_* и worker_stack_size, max_blocking_threads опциональны: на современных версиях tokio дефолты разумны, и их обычно не нужно трогать.

По умолчанию: not set (uses tokio's default).

tokio_event_interval

Настройки Tokio runtime. Задаёт, как часто шедулер проверяет внешние события (I/O, таймеры).

По умолчанию: not set (uses tokio's default).

worker_stack_size

Настройки Tokio runtime. Размер стека для worker-потоков.

По умолчанию: not set (uses tokio's default).

max_blocking_threads

Настройки Tokio runtime. Максимальное число потоков для блокирующих операций.

По умолчанию: not set (uses tokio's default).

connect_timeout

Максимальное время ожидания при установке нового соединения с сервером PostgreSQL. Если соединение не удаётся установить за это время, попытка прерывается. Аналог server_connect_timeout из PgBouncer.

По умолчанию: 3000 (3 sec).

query_wait_timeout

Максимальное время ожидания клиентом серверного соединения, когда пул полностью занят. Если за это время серверное соединение не освобождается, клиент получает ошибку. Аналог query_wait_timeout из PgBouncer.

По умолчанию: 5000 (5 sec).

idle_timeout

Закрывать серверное соединение, которое простаивает (не выдано ни одному клиенту) дольше этого значения. Применяется только к соединениям, обслужившим хотя бы один клиентский запрос. Прогретые или дополненные соединения, никогда не выдававшиеся клиенту, под действие idle_timeout не попадают — они закрываются только по истечении server_lifetime. Каждое соединение получает джиттер ±20%, чтобы избежать синхронных массовых закрытий. Установите 0, чтобы отключить. Аналог server_idle_timeout из PgBouncer.

По умолчанию: 600000 (10 min).

server_lifetime

Максимальный возраст серверного соединения. Когда соединение превышает этот возраст и переходит в idle, оно закрывается на ближайшем цикле retain. Активные транзакции не прерываются. Применяется ко всем соединениям, включая прогретые, которые никогда не выдавались клиенту. Каждое соединение получает джиттер ±20%, чтобы избежать лавины одновременных закрытий. Установите 0, чтобы отключить. Аналог server_lifetime из PgBouncer.

По умолчанию: 1200000 (20 min).

retain_connections_time

Интервал проверки и закрытия idle-соединений, превысивших idle_timeout или server_lifetime. Задача retain выполняется периодически с этим интервалом и удаляет просроченные соединения.

По умолчанию: 30000 (30 sec).

retain_connections_max

Максимальное число idle-соединений, закрываемых за один цикл retain. При значении 0 все idle-соединения, превысившие idle_timeout или server_lifetime, закрываются немедленно. При положительном значении за цикл по всем пулам закрывается не более указанного числа соединений.

Этот параметр управляет агрессивностью закрытия idle-соединений в pg_doorman. При значении по умолчанию 3 за цикл retain закрывается до 3 соединений, что обеспечивает контролируемую очистку. Если нужна более быстрая очистка просроченных соединений, установите 0 (без ограничений), чтобы закрывать все просроченные соединения за каждый цикл retain.

По умолчанию: 3.

server_idle_check_timeout

Время, после которого idle-серверное соединение должно быть проверено перед выдачей клиенту. Это помогает обнаружить мёртвые соединения, возникшие из-за рестарта PostgreSQL, сетевых проблем или серверных idle-таймаутов.

Когда соединение простояло в пуле дольше этого таймаута, pg_doorman отправляет минимальный запрос (;), чтобы проверить, что соединение живо, прежде чем выдать его клиенту. Если проверка не проходит, соединение отбрасывается и берётся новое.

Установите 0, чтобы отключить проверку (не рекомендуется для промышленной эксплуатации с возможной сетевой нестабильностью или рестартами PostgreSQL).

По умолчанию: 60s (60 seconds).

server_round_robin

Задаёт, какое idle-серверное соединение выбирается для следующей транзакции. false (MRU, LIFO): берётся последнее возвращённое в пул соединение. Горячих соединений меньше, локальность shared buffer в PostgreSQL выше. true (Round Robin): равномерная ротация по всем idle-соединениям. Аналог server_round_robin из PgBouncer.

По умолчанию: false.

sync_server_parameters

В транзакционном режиме разные транзакции одного клиента могут выполняться на разных серверных соединениях. Если включить sync_server_parameters, pg_doorman перед началом транзакции применяет к выбранному серверному соединению параметры сессии, которые запросил клиент.

Есть два источника таких параметров:

  1. Сообщения PostgreSQL ParameterStatus: client_encoding, DateStyle, IntervalStyle, TimeZone, standard_conforming_strings, application_name. PostgreSQL сам сообщает об изменении этих параметров по протоколу.

  2. Параметры из клиентского StartupMessage (начиная с pg_doorman 3.10): любой безопасный параметр, который клиент прислал при подключении. pg_doorman отбрасывает служебные имена и имена только для чтения (is_superuser, server_version, lc_collate, transaction_isolation, ...) и префикс _pq_.. Так клиент может задать search_path, default_transaction_isolation, role и другие параметры, важные для планировщика, один раз при подключении. После этого pg_doorman применит их к любому серверному соединению, на котором окажется транзакция. Значения из операторской настройки startup_parameters всегда имеют приоритет над клиентским пакетом.

Ограничения, которые важно учитывать:

  • pg_doorman отслеживает только параметры, заданные при подключении, и параметры, о которых PostgreSQL сам присылает ParameterStatus. Если клиент после подключения выполнит SET search_path = ... или изменит другой параметр планировщика, о котором PostgreSQL не сообщает, pg_doorman не узнает об этом изменении. В таком случае повторное использование prepared statement может попасть на план, построенный при старом состоянии. Для таких клиентов лучше задавать параметры в StartupMessage, после изменения выполнять DISCARD ALL или переподключаться, либо отключить prepared_statements для пула.

  • В ключ кэша prepared statement входят текст запроса, OID параметров и отпечаток только этих параметров планировщика из StartupMessage: search_path, default_transaction_isolation, default_transaction_read_only, default_text_search_config, role. Другие параметры, которые тоже могут влиять на план (TimeZone, DateStyle, plan_cache_mode, enable_*, настройки стоимости JIT, параметры расширений), в ключ не входят. Если один и тот же запрос готовится под разными значениями таких параметров, отключите prepared_statements для пула или закрепите эти параметры на уровне роли или базы.

Когда состояние серверного соединения отличается от состояния клиента, pg_doorman делает дополнительный обмен с PostgreSQL для SET или RESET. Если вам нужна только видимость application_name в pg_stat_activity, проще задать application_name на уровне пула.

По умолчанию: false.

tcp_so_linger

По умолчанию pg_doorman отправляет RST вместо того, чтобы держать соединение открытым долгое время.

По умолчанию: 0.

tcp_no_delay

TCP_NODELAY для отключения алгоритма Нэйгла ради более низкой задержки.

По умолчанию: true.

tcp_keepalives_count

Число неподтверждённых TCP keepalive probes, после которого соединение считается мёртвым и закрывается.

По умолчанию: 5.

tcp_keepalives_idle

Keepalive включён по умолчанию и переопределяет дефолты ОС.

По умолчанию: 5.

tcp_keepalives_interval

Интервал в секундах между отдельными TCP keepalive probes после прохождения начального периода простоя (tcp_keepalives_idle).

По умолчанию: 5.

tcp_user_timeout

Задаёт опцию сокета TCP_USER_TIMEOUT для клиентских соединений (в секундах). Эта опция указывает максимальное время, в течение которого переданные данные могут оставаться неподтверждёнными, прежде чем TCP принудительно закроет соединение. Это помогает быстрее обнаруживать мёртвые клиентские соединения, чем keepalive probes, когда соединение активно отправляет данные, но удалённый конец стал недоступен (например, сбой сети, падение клиента).

При ненулевом значении, если данные остаются неподтверждёнными в течение указанного времени, соединение будет разорвано. Это особенно полезно, чтобы избежать задержек в 15–16 минут, вызванных TCP retransmission timeout, когда keepalive не помогает (например, при активной передаче данных).

Примечание: опция поддерживается только в Linux. На других ОС параметр игнорируется.

Установите 0, чтобы отключить (использовать значение по умолчанию ОС).

По умолчанию: 60.

tcp_socket_buffer_size

Лимиты буферов ядра SO_RCVBUF и SO_SNDBUF для принятых клиентских TCP-сокетов и исходящих TCP-сокетов к PostgreSQL.

При значении по умолчанию 0 pg_doorman не вызывает setsockopt(SO_RCVBUF/SO_SNDBUF), поэтому буферами управляет автонастройка TCP в Linux. Буфер приёма каждого соединения может расти по требованию до net.ipv4.tcp_rmem[2] (обычно 6 MiB в Ubuntu/RHEL). Эта память не входит в RSS процесса; в зависимости от ядра и режима cgroup она может отображаться отдельно как socket memory, например как sock в cgroup v2 memory.stat, или быть заметна в основном как память ядра на хосте. Если MemFree заметно растёт после рестарта pg_doorman, проверьте источник через ss -m, /proc/net/sockstat, cgroup v2 memory.current и ключ sock в memory.stat.

Ненулевое значение вызывает setsockopt(SO_RCVBUF/SO_SNDBUF) один раз для каждого настраиваемого TCP-сокета. Это отключает автонастройку для этого сокета и задаёт фиксированные лимиты буферов отправки и приёма. Linux внутренне удваивает запрошенные значения — см. man 7 socket — и может ограничить их через net.core.rmem_max / net.core.wmem_max. Перед настройкой значений выше системного дефолта проверьте /proc/sys/net/core/rmem_max и /proc/sys/net/core/wmem_max. Применённые ядром значения видны через getsockopt, ss -m и DEBUG-логи pg_doorman.

Примерная верхняя граница в Linux: 4 * tcp_socket_buffer_size * число_TCP_сокетов. Pg_doorman задаёт буферы отправки и приёма, а Linux внутренне удваивает каждое значение. Например, tcp_socket_buffer_size = 65536 даёт около 256 KiB лимитов на один TCP-сокет, то есть примерно 15 MiB на 60 TCP-сокетов без учёта накладных расходов sk_buff. Считайте и клиентские TCP-сокеты, и TCP-сокеты к PostgreSQL. Фактически занятая память всё равно зависит от данных в очередях.

Этот параметр в первую очередь ограничивает память. Стартовый диапазон для OLTP внутри одного датацентра: 64 KiB – 256 KiB. Не ставьте меньше 64 KiB без замеров. Для WAN, межзонального трафика, больших результатов запроса и массовой передачи данных может понадобиться большее значение или поведение по умолчанию с автонастройкой TCP.

Значение применяется, когда pg_doorman настраивает TCP-сокет: к новым клиентским подключениям, новым TCP-соединениям к PostgreSQL и клиентским сокетам, восстановленным в новом процессе через SCM_RIGHTS. SIGHUP не пересматривает уже открытые сокеты. Чтобы применить новое значение к существующим сессиям, используйте горячую замену процесса для мигрирующих клиентов, RECONNECT/дренирование пулов для backend-сокетов или обычный рестарт, если переподключения допустимы.

Это аналог параметра tcp_socket_buffer в PgBouncer. В Odyssey и PgCat аналога нет, они наследуют поведение автонастройки TCP в Linux.

По умолчанию: 0.

unix_socket_buffer_size

Размер буфера для операций чтения и записи при подключении к PostgreSQL через unix-сокет.

По умолчанию: 1048576.

admin_username

Имя пользователя для виртуальной admin-базы.

По умолчанию: "admin".

admin_password

Пароль для виртуальной admin-базы. Замените на свой секрет.

По умолчанию: "admin".

prepared_statements

Включает подмену и кеширование prepared statements. Когда параметр выключен, pg_doorman передаёт Parse и Bind без переписывания через пуловый кеш prepared statements.

Если значение true, prepared_statements_cache_size должен быть больше 0.

По умолчанию: true.

prepared_statements_cache_size

Размер кеша prepared statements на уровне пула (общий для всех клиентов, подключающихся к одному пулу). Кеш хранит соответствие между хешем запроса и переписанным именем prepared statement.

Это не выключатель. Чтобы отключить подмену prepared statements, задайте prepared_statements: false; pg_doorman отклоняет общее значение prepared_statements_cache_size = 0, пока prepared_statements включён.

Полная картина того, как этот параметр взаимодействует с server_prepared_statements_cache_size, client_anonymous_prepared_cache_size и query interner — в туториале Кеширование анонимных prepared statements.

По умолчанию: 8192.

server_prepared_statements_cache_size

Размер LRU DOORMAN_<N> на каждое серверное соединение, независимо от кеша уровня пула. Если параметр не задан, наследуется итоговый prepared_statements_cache_size для пула: сначала проверяется per-pool override, затем общее значение. Per-pool override этого параметра имеет приоритет над общим.

Уменьшайте значение ниже размера пула, когда бэкенды накапливают слишком много DOORMAN_<N> (pg_prepared_statements упирается в лимит, плановая память растёт) или когда нужна более быстрая утилизация через Close без уменьшения hit rate на уровне пула. При prepared_statements: false принудительно равен 0.

По умолчанию: not set (наследует prepared_statements_cache_size).

client_anonymous_prepared_cache_size

Ограничивает Anonymous-часть per-client кеша prepared statements. Анонимные statements отправляются без явного имени и обычно короткоживущие; LRU задаёт верхнюю границу того, сколько таких записей один клиент может накопить, прежде чем будет выселена самая старая.

Если параметр не задан, наследуется итоговый prepared_statements_cache_size для пула. Установите 0, чтобы отключить LRU и хранить Anonymous в неограниченной хеш-таблице; задайте число, чтобы ограничить кеш на каждого клиента независимо от размера пула.

Named-часть per-client кеша (statements, созданные с явным именем через PREPARE или extended-query Parse) всегда без ограничения — этот параметр на неё не влияет. Named statements живут в кеше до закрытия клиентского соединения.

По умолчанию: not set (наследует prepared_statements_cache_size).

query_interner_gc_interval_seconds

Интернер запросов запускает двухцикловый mark-and-sweep сборщик. Named-записи вытесняются, когда вне интернера никто не держит Arc<str>; анонимные — когда простаивают дольше query_interner_anon_idle_ttl_seconds.

Этот параметр задаёт, как часто запускается коллектор. Реальный sweep тикает gc_interval / 4, поэтому помеченная на цикле N запись имеет примерно четверть интервала, чтобы её прочитали (и сняли пометку), пока цикл N+1 её не вытеснит.

Меньшие значения быстрее уменьшают интернер после волн отключений ценой большей нагрузки на CPU. Значение 0 отклоняется при старте.

Restart-only: изменения подхватываются только после рестарта; config reload не меняет частоту проходов работающего процесса.

По умолчанию: 60.

query_interner_anon_idle_ttl_seconds

Ограничивает верхнюю границу памяти, которую pg_doorman тратит на хранение SQL-текста анонимного prepared statement после последнего Bind или Parse, ссылающегося на тот же hash. Когда анонимная запись простаивает дольше указанных секунд, она помечается и вытесняется на следующем проходе, который всё ещё видит её бездействующей.

Значение 0 полностью отключает TTL: анонимные записи живут до перезапуска процесса. Это соответствует поведению до 3.7 и нужно для старых развёртываний, которые опираются на кросс-batch unnamed prepared statements; в остальных случаях оставляйте значение по умолчанию.

Live-reloadable: перечитывается на каждом проходе, поэтому config reload меняет эффективный TTL без рестарта.

По умолчанию: 60.

message_size_to_be_stream

Когда сообщение DataRow PostgreSQL превышает этот порог, pg_doorman переключается в потоковый режим: данные пересылаются клиенту чанками по 4 KB вместо буферизации всего сообщения целиком. Это предотвращает OOM на запросах, возвращающих очень большие строки (например, таблицы с большими колонками bytea/text). Сам порог по умолчанию равен 1 MB.

По умолчанию: 1048576 (1 MB).

scaling_warm_pool_ratio

Доля прогретого пула в процентах (0–100). Когда размер пула ниже этого порога от max_size, новые соединения создаются немедленно. Выше порога пул сначала крутится через быстрые ретраи, затем переходит в event-driven цикл упреждающего ожидания, который ждёт возврата idle-соединения. Цикл ограничен оставшимся query_wait_timeout клиента минус резерв 500 ms на путь создания, поэтому он не может вытолкнуть вызывающего за его собственный дедлайн ожидания.

По умолчанию: 20.

scaling_fast_retries

Число быстрых ретраев через yield_now() для ожидания с низкой задержкой при выдаче соединений выше порога прогрева пула. Каждый ретрай занимает примерно 1–5 мкс. После исчерпания быстрых ретраев пул переходит в event-driven цикл упреждающего ожидания, ограниченный оставшимся query_wait_timeout клиента.

По умолчанию: 10.

scaling_max_parallel_creates

Ограничитель всплесков для создания соединений. Без этого лимита N параллельных вызывающих timeout_get, не нашедших соединения в idle-пуле, независимо инициируют подключение к PostgreSQL, создавая лавину подключений под нагрузкой. С лимитом одновременно выполняется не больше указанного числа creates на пул; остальные кратко ждут на Notify и затем либо подхватывают только что возвращённое idle-соединение, либо занимают следующий слот для create. Значение по умолчанию 2 — компромисс между пропускной способностью и сглаживанием всплесков.

По умолчанию: 2.

max_memory_usage

Общий бюджет памяти для внутренних буферов, хранящих данные in-flight запросов по всем клиентским соединениям. При достижении лимита pg_doorman отклоняет новые запросы с ошибкой, пока существующие запросы не завершатся и не освободят свои буферы. Защищает процесс пулера от OOM при тяжёлой нагрузке или больших результирующих наборах.

По умолчанию: 268435456 (256 MB).

shutdown_timeout

При graceful shutdown (SIGTERM) pg_doorman ждёт до этого времени завершения in-flight транзакций перед принудительным закрытием соединений.

По умолчанию: 10000 (10 sec).

proxy_copy_data_timeout

Максимальное время ожидания операций копирования данных при проксировании, в миллисекундах.

По умолчанию: 15000 (15 sec).

server_tls_mode

Режим TLS для исходящих соединений к серверам PostgreSQL.

  • allow — Сначала пробовать без TLS; если сервер отказывает, повторить с TLS. Соответствует libpq sslmode=allow (по умолчанию).
  • disable — TLS не используется.
  • prefer — TLS используется, если сервер его поддерживает; иначе обычное соединение.
  • require — TLS обязателен, но сертификат сервера не проверяется.
  • verify-ca — TLS обязателен, и сертификат сервера проверяется по server_tls_ca_cert.
  • verify-full — TLS обязателен, сертификат проверяется, и hostname сервера должен совпадать с сертификатом.

По умолчанию: "allow".

server_tls_ca_cert

CA-сертификат для проверки сертификатов серверов PostgreSQL. Обязателен, когда server_tls_mode равен verify-ca или verify-full.

По умолчанию: None.

server_tls_certificate

Клиентский сертификат для mTLS с серверами PostgreSQL. Используйте в паре с server_tls_private_key.

По умолчанию: None.

server_tls_private_key

Приватный ключ для клиентского сертификата mTLS. Используйте в паре с server_tls_certificate.

По умолчанию: None.

hba

Список IP-сетей в нотации CIDR, с которых разрешено подключение к pg_doorman. Для тонкого контроля доступа per-database и per-user используйте pg_hba (см. ниже).

По умолчанию: [].

pg_hba

Новый стиль контроля доступа клиентов в формате pg_hba.conf PostgreSQL. Позволяет задавать тонкие правила доступа аналогично PostgreSQL: per-database, per-user, диапазоны адресов, требования TLS.

Указать general.pg_hba можно тремя способами:

  • Как многострочную строку с содержимым файла pg_hba.conf
  • Как объект с path, указывающий на файл на диске
  • Как объект с content, содержащий правила в виде строки

Примеры:

[general]
# Inline-содержимое (TOML-строка в тройных кавычках)
pg_hba = """
# type   database  user   address         method
host     all       all    10.0.0.0/8      md5
hostssl  all       all    0.0.0.0/0       scram-sha-256
hostnossl all      all    192.168.1.0/24  trust
"""

# Или загрузить из файла
# pg_hba = { path = "./pg_hba.conf" }

# Или встроить как однострочную строку
# pg_hba = { content = "host all all 127.0.0.1/32 trust" }

Поддерживаемые поля и методы:

  • Типы соединений: local, host, hostssl, hostnossl (TLS-зависимое сопоставление учитывается)
  • Сопоставитель базы: имя или all
  • Сопоставитель пользователя: имя или all
  • Адрес: CIDR-форма вроде 1.2.3.4/32 или ::1/128 (обязателен для правил, отличных от local)
  • Методы: trust, md5, scram-sha-256 (неизвестные методы парсятся, но трактуются проверяющим как «не разрешено»)

Приоритет и совместимость:

  • general.pg_hba имеет приоритет над устаревшим списком general.hba. Нельзя задавать оба одновременно; валидация конфигурации отклонит такую комбинацию.
  • Правила вычисляются по порядку; первое совпавшее правило определяет результат.

Поведение method = trust:

  • Когда совпавшее правило имеет trust, PgDoorman принимает соединение без запроса пароля. Это повторяет поведение PostgreSQL.
  • В частности, при срабатывании trust PgDoorman пропускает проверку пароля, даже если у пользователя сохранён пароль md5 или scram-sha-256. Это распространяется и на MD5, и на SCRAM-потоки.
  • TLS-ограничения правила соблюдаются: hostssl требует TLS, hostnossl запрещает TLS.

Доступ к admin-консоли:

  • Правила general.pg_hba применяются и к специальной admin-базе pgdoorman.
  • Это означает, что admin-доступ можно разрешить методом trust при наличии совпавшего правила, например:
    host  pgdoorman  admin  127.0.0.1/32  trust
    

Замечания и ограничения:

  • Поддерживается только минимальное подмножество pg_hba.conf, достаточное для большинства proxy-сценариев (type, database, user, address, method). Дополнительные опции (вроде clientcert) сейчас игнорируются.
  • Для методов аутентификации, отличных от trust, PgDoorman выполняет соответствующий challenge/response с клиентом.
  • Для потоков Talos/JWT/PAM, настроенных на уровне пула или пользователя, trust всё равно обходит запрос пароля у клиента; однако эти режимы могут использоваться, если trust не совпал.

startup_parameters

Базовые параметры PostgreSQL, которые pg_doorman добавляет в StartupMessage каждого нового бэкенда. startup_parameters уровня пула переопределяют эти значения по ключу, а passthrough auth_query может переопределить их для конкретного пользователя.

При загрузке конфигурации pg_doorman проверяет зарезервированные протокольные ключи (user, database, replication, options, _pq_.*), имена GUC, нулевые байты и размер этого уровня. Перед каждым запуском бэкенда объединённый набор параметров снова проверяется по лимиту MAX_STARTUP_PACKET_LENGTH PostgreSQL (10 000 байт). Любое переполнение отклоняет запуск бэкенда с SQLSTATE 53400 (configuration_limit_exceeded), вместо отправки частичного или пустого StartupMessage.

Если PostgreSQL отвергает параметр при запуске бэкенда, pg_doorman возвращает клиенту ErrorResponse PostgreSQL без изменений: повторной попытки без этого ключа не будет, сам ключ автоматически не отключается. Накопительный счётчик отказов экспортируется как pg_doorman_backend_startup_parameter_errors_total{pool, sqlstate}; имя параметра и пользователя остаются в строке лога уровня warn. Итоговые параметры по каждому пулу видны через SHOW STARTUP_PARAMETERS в административной SQL-консоли и через /api/pools в веб-интерфейсе.

По умолчанию: {}.

pooler_check_query

Когда клиент отправляет ровно этот запрос как SimpleQuery, pg_doorman обслуживает его через кеш ответа на уровне пула. Первая совпадающая проба за время жизни каждого пула отправляется в PostgreSQL, и полный ответ сохраняется. Последующие совпадающие пробы отвечаются из кеша без обращения к бэкенду.

Кеш индексируется по строке запроса. RELOAD с другим значением pooler_check_query инвалидирует кеш на следующей пробе; новое значение вызывает одну свежую пробу к бэкенду и затем обслуживается из кеша, пока значение снова не изменится. RELOAD с тем же значением не сбрасывает кеш. ErrorResponse от бэкенда передаётся клиенту без изменений и не кешируется, поэтому следующая проба снова идёт в PostgreSQL.

Поведение на холодном пуле изменилось: первая проба в каждом пуле теперь делает один round-trip к PostgreSQL даже для значения по умолчанию ;. Если PostgreSQL в этот момент недоступен, клиент-пробер увидит ошибку пробы вместо безусловного OK. Прежний хардкод локального ответа сообщал, что пулер здоров, даже когда PostgreSQL лежал, и для непустых значений вроде select 1 возвращал пустой ответ.

Контракт для оператора. Запрос должен быть детерминированным: один и тот же ввод обязан давать один и тот же набор байт, без побочных эффектов. Безопасные значения: ;, select 1, select 'pg_doorman', select version().

Небезопасные значения, которые кеш молча заморозит:

  • select now(), select clock_timestamp() — закешированный timestamp перестанет идти вперёд.
  • select pg_is_in_recovery() — failover поменяет роль на PostgreSQL, но закешированный ответ всё ещё будет показывать прежнюю роль.
  • select count(*) from <table> — закешированное число останется тем, что увидела первая проба.
  • UPDATE, INSERT, DELETE, CALL, DO — побочный эффект выполнится один раз, а ответ об успехе закешируется навсегда.

Доля попаданий в кеш экспортируется двумя счётчиками без меток: pg_doorman_pooler_check_query_backend_total (пробы, отправленные в PostgreSQL) и pg_doorman_pooler_check_query_cache_total (пробы, обслуженные из кеша). Отношение cache_total / (cache_total + backend_total) — это hit rate.

По умолчанию: ";".