MAATRIX / Блог / PgBouncer на сервере: частые ошибки и решения

PgBouncer на сервере: частые ошибки и решения

PgBouncer на сервере: частые ошибки и решения

MAATRIX

pgBouncer на сервере обычно работает незаметно, но когда что-то ломается, ошибки выглядят загадочно, потому что причина часто в тонкостях режима пулинга. Ниже — разбор частых проблем: не проходит авторизация, «prepared statement does not exist», пул переполнен, клиентам не хватает соединений и странные сбои в режиме transaction. Для каждой сначала решение, потом причина — чтобы починить быстро и понять, как избежать повторов. Большинство ошибок pgBouncer сводятся к двум темам: авторизация и особенности transaction pooling.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Auth failed при подключении через pgBouncer

Клиент подключается напрямую к PostgreSQL нормально, а через pgBouncer получает password authentication failed. Причина почти всегда в файле userlist.txt или несоответствии метода аутентификации. Проверьте три вещи. Первое — метод: auth_type в конфиге pgBouncer должен соответствовать формату паролей. Если PostgreSQL использует scram-sha-256, ставьте тот же auth_type = scram-sha-256.

Второе — сам файл userlist.txt. В нём должны быть имя пользователя и корректный хеш пароля в кавычках. Хеш проще всего взять из PostgreSQL:

sudo -u postgres psql -t -c "SELECT '\"'||rolname||'\" \"'||rolpassword||'\"' FROM pg_authid WHERE rolname='appuser';"

Скопируйте результат в userlist.txt. Третье — если пароль в базе меняли, а в userlist.txt остался старый хеш, авторизация не пройдёт. Синхронизируйте их. Более удобный вариант для многих пользователей — режим auth_query, когда pgBouncer сам запрашивает хеши из базы, и файл вести не нужно, но для него требуется отдельный служебный пользователь с доступом к системным таблицам.

Prepared statement does not exist

Одна из самых частых и сбивающих с толку ошибок: prepared statement "S_1" does not exist или похожая. Приложение работало напрямую с PostgreSQL, а через pgBouncer начало падать. Это классический симптом несовместимости с режимом transaction. В нём соединение отдаётся клиенту только на одну транзакцию и возвращается в пул, поэтому подготовленное на уровне сессии выражение, созданное в одной транзакции, исчезает для следующей — она попадает уже на другое серверное соединение.

Решений несколько. Идеальное — включить в драйвере или ORM режим совместимости с transaction pooling: многие библиотеки умеют работать без сессионных prepared statements или используют протокол так, что pgBouncer справляется. В новых версиях pgBouncer появилась поддержка prepared statements в transaction-режиме — обновитесь и включите её параметром max_prepared_statements. Если приложение никак не хочет дружить с transaction pooling, переключите базу на pool_mode = session — тогда сессионные фичи работают, но выигрыш от пулинга меньше. Выбор между эффективностью и совместимостью — это осознанное инженерное решение, а не поломка.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.

Арендовать VPS под PostgreSQL

Pool is full / no more connections allowed

Ошибка no more connections allowed (max_client_conn) или сообщения о переполнении пула. Первый вариант — упёрлись в max_client_conn, общий лимит клиентов, которых pgBouncer готов принять. Если клиентов реально много, поднимите его. Но чаще причина в том, что клиенты не отпускают соединения: приложение держит коннекты открытыми, не закрывая, и они копятся.

Второй вариант — исчерпан default_pool_size, и клиенты выстроились в очередь за реальными соединениями к базе. Посмотрите картину через административную консоль:

psql -h 127.0.0.1 -p 6432 -U pgbouncer pgbouncer -c "SHOW POOLS;"

Колонка cl_waiting показывает клиентов, ждущих соединения, а sv_active — занятые серверные коннекты. Если много ждущих, а серверные все заняты долгими запросами, проблема не в pgBouncer, а в медленных запросах, которые держат соединения. Оптимизируйте запросы или аккуратно увеличьте default_pool_size, но помните: он не должен превышать разумную долю max_connections самой PostgreSQL, иначе вы просто перенесёте упор в лимит на уровень базы.

Server login has been failing

В логе pgBouncer повторяется server login has been failing, cached error — pgBouncer не может подключиться к самой PostgreSQL. Тут pgBouncer ни при чём, проблема между ним и базой. Проверьте, что PostgreSQL запущена и слушает нужный адрес, что данные в секции [databases] конфига верны (host, port, dbname), и что пользователь, под которым pgBouncer ходит в базу, имеет право входа в pg_hba.conf PostgreSQL.

Частая деталь: pgBouncer подключается к PostgreSQL по локальному адресу, и в pg_hba.conf должна быть разрешающая строка для этого подключения с правильным методом. Если pgBouncer и база на одном сервере, разрешите вход с 127.0.0.1. Ошибка кешируется, поэтому после исправления сделайте RELOAD в административной консоли или перезапустите pgBouncer, чтобы он забыл про старую неудачу и попробовал заново.

Изменения в конфиге не применяются

Отредактировали pgbouncer.ini, а поведение не изменилось. pgBouncer не перечитывает конфиг сам. Большинство параметров подхватываются командой RELOAD в административной консоли, но некоторые — например, listen_port или auth_type — требуют полного перезапуска службы. Если не уверены, перезапустите:

sudo systemctl restart pgbouncer

Учтите, что при перезапуске все текущие клиентские соединения обрываются, поэтому на боевом сервере делайте это осознанно. Для мягкого применения без разрыва соединений используйте RELOAD из консоли pgbouncer. В административной консоли есть и щадящие команды управления: PAUSE временно приостанавливает выдачу новых соединений, дожидаясь завершения текущих транзакций, а RESUME возобновляет работу — это позволяет, например, спокойно перезапустить саму PostgreSQL, не обрывая клиентов pgBouncer грубо. Такой приём удобен при плановом обслуживании базы: клиенты недолго ждут, но их соединения не рвутся с ошибками. Ещё частая мелочь — правки внесли не в тот файл: убедитесь, что редактируете именно тот конфиг, который указан в юните systemd.

Правильно настроенный pgBouncer способен вытянуть тысячи клиентов на скромном сервере, но и сама база должна стоять на надёжном железе. В MAATRIX можно арендовать VPS под PostgreSQL и pgBouncer в России, США или Великобритании и оплатить картой РФ, по СБП, криптой или токеном MAAT — иностранная карта не требуется.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.

Арендовать VPS под PostgreSQL

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Частые вопросы

Почему auth failed только через pgBouncer?

Несоответствие auth_type методу паролей PostgreSQL или устаревший/неверный хеш в userlist.txt. Синхронизируйте хеш из базы или используйте auth_query, чтобы pgBouncer брал пароли сам.

Откуда ошибка prepared statement does not exist?

Это несовместимость с transaction pooling: сессионные подготовленные выражения не переживают возврат соединения в пул. Включите совместимость в драйвере, обновите pgBouncer с поддержкой prepared statements или перейдите на session.

Клиентам не хватает соединений, что делать?

Смотрите SHOW POOLS: если много cl_waiting при занятых серверных коннектах, виноваты медленные запросы, а не pgBouncer. Оптимизируйте их или увеличьте default_pool_size в разумных пределах.

Изменения в конфиге не работают?

pgBouncer не перечитывает конфиг автоматически. Сделайте RELOAD в административной консоли, а для параметров вроде порта или метода авторизации перезапустите службу.

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.