awesome-everything EN
↑ Обратно к восхождению

Базы данных

Миграция на transaction mode: план развёртывания и prepared statements в PgBouncer 1.21

Суть Пятишаговый план развёртывания transaction mode — аудит, размер, настройка GUC, canary, мониторинг — и прорыв PgBouncer 1.21 в 2024 году, снявший ограничение prepared statements в transaction mode.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 14 min

У команды PgBouncer в session mode. Они хотят transaction mode — мультиплексирование 10×, — но боятся поломок. Аудит и canary-развёртывание занимают одну неделю, а не год; опасения по prepared statements были обоснованы до марта 2024 года и теперь решены.

Пятишаговое развёртывание

Проследи
1/5

Первое развёртывание PgBouncer в transaction mode. Пройдите план.

1
Step 1 of 5
Шаг 1: аудит приложения на использование состояния сессии.
2
Locked
Шаг 2: расчёт размера backend-пула.
3
Locked
Шаг 3: настройка GUC и таймаутов.
4
Locked
Шаг 4: canary-развёртывание.
5
Locked
Шаг 5: настройка постоянного мониторинга.

PgBouncer 1.21 и прорыв с prepared statements

До марта 2024 года операционный компромисс звучал так: transaction mode (мультиплексирование 10–100×) ИЛИ prepared statements (10–30% прирост пропускной способности на повторяющихся запросах) — не оба вместе.

Почему они конфликтовали: prepared statements на уровне проводного протокола Postgres привязывают именованный оператор к конкретной backend-сессии (PrepareStatement/PQprepare → слот на том backend’е). PgBouncer в transaction mode направляет следующий EXECUTE на любой свободный backend — если это другой backend, оператор там неизвестен. Драйверы случайным образом возвращали ошибку prepared statement does not exist. Обходное решение: отключить prepared statements на уровне драйвера — теряя выигрыш в производительности.

Что исправил PgBouncer 1.21 (март 2024): отслеживание prepared statements на уровне протокола. PgBouncer перехватывает wire-сообщения Parse/Bind/Execute, ведёт глобальный реестр на логического клиента и повторно подготавливает на любом назначенном backend’е. Приложение видит согласованное поведение prepared statements при всех checkout’ах пула.

Требует max_prepared_statements > 0 (типично: 1000) в pgbouncer.ini.

PostgreSQL 17 (сентябрь 2024) добавил DEALLOCATE на уровне протокола, позволяя PgBouncer чисто закрывать prepared statements на backend’е при отключении клиента — устраняя утечку ресурсов.

В 2026 году production-дефолт: PgBouncer 1.21+ + max_prepared_statements = 1000 + prepared statements под управлением драйвера + transaction mode. Все три выигрыша одновременно. Командам на PgBouncer 1.20 или старше следует обновиться в следующем окне обслуживания.

ЭраTransaction modePrepared statements
До PgBouncer 1.21 (до 2024)РаботаетНужно отключить в драйвере — потеря 10–30% пропускной способности
PgBouncer 1.21+ (2024+)РаботаетРаботает — PgBouncer повторно подготавливает прозрачно
PgBouncer 1.21+ + Postgres 17РаботаетРаботает + чистое освобождение через протокол

Проверка стека

Команде, переходящей на transaction mode + prepared statements в 2026 году, следует проверить:

  1. Версия PgBouncer: 1.21.0 или новее. Проверить через pgbouncer -V или SHOW VERSION в admin-консоли.
  2. max_prepared_statements: ненулевое значение в pgbouncer.ini (типично: 1000). Проверить через SHOW CONFIG.
  3. Версия Postgres: 14+ для стабильной работы; 17+ для DEALLOCATE на уровне протокола.
  4. Поведение драйвера: убедиться, что используются prepared statements на уровне протокола (JDBC prepareThreshold > 0, node-postgres аргумент name:, pgx Prepare, asyncpg — все по умолчанию используют prepared).
  5. Нагрузочный тест: нагрузить prepared-запросами 30 минут; проверить логи PgBouncer на ошибки “prepared statement does not exist”.
Почему это работает

Почему это ограничение существовало так долго? PgBouncer — это лёгкий C-прокси, намеренно избегающий разбора SQL. Отслеживание prepared statements на уровне протокола потребовало от PgBouncer перехватывать и понимать конкретные wire-protocol сообщения (Parse, Bind, Execute, Close) — существенное изменение кодовой базы, созданной быть минималистичной. Функция запрашивалась годами перед реализацией в 1.21.

Чеклист развёртывания transaction mode
Аудит: SET без LOCAL
→ ALTER ROLE
Аудит: LISTEN/NOTIFY
→ выделенное session-соединение
Аудит: SQL PREPARE
→ уровень протокола (драйвер)
Аудит: pg_advisory_lock
→ pg_advisory_xact_lock
idle_in_transaction_session_timeout
60 с
max_prepared_statements
1000 (PgBouncer 1.21+)
Продолжительность canary перед рампингом
24 ч
Викторина

До PgBouncer 1.21 почему prepared statements, управляемые драйвером, вызывали ошибки в transaction mode?

Викторина

Какая опция конфигурации PgBouncer включает поддержку prepared statements на уровне протокола в transaction mode?

Вспомните перед уходом
  1. 01
    Каков правильный порядок развёртывания при миграции на transaction mode и почему важен canary-шаг?
  2. 02
    Что добавил PgBouncer 1.21 и почему это важно для production-производительности?
  3. 03
    Что делает server_reset_query = DISCARD ALL и когда он необходим?
Итог

Миграция с session на transaction mode требует сначала аудита кодовой базы: найти и заменить SET на ALTER ROLE, изолировать LISTEN на выделенном session-соединении, переключить SQL-level PREPARE на prepared statements на уровне протокола драйвера, заменить pg_advisory_lock на pg_advisory_xact_lock. Затем рассчитать размер пула (ядра × 2) + шпиндели, настроить safety GUC (idle_in_transaction_session_timeout = 60s, query_wait_timeout = 30s) и провести canary-развёртывание на 24 часа до полного рампинга. Опасения по prepared statements до 2024 года решены: PgBouncer 1.21+ с max_prepared_statements = 1000 отслеживает prepared statements на логического клиента и прозрачно повторно подготавливает на любом назначенном backend’е — transaction mode и полная производительность prepared statements теперь совместимы по умолчанию.

Связанные уроки
встречается в258
Продолжить восхождение ↑Процессная модель Postgres и почему увеличение max_connections снижает производительность
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources4
expand
  1. 01
  2. 02
  3. 03
  4. 04

Trademarks belong to their respective owners. Editorial reference only.