#Что означает ошибка
too many connections
Сообщения too many connections for role и remaining connection slots are reserved означают, что новый сеанс не допускается из-за ограничения роли либо нехватки доступных слотов PostgreSQL. deadlock detected — отдельная ошибка взаимной блокировки, её здесь не разбираем.
Сначала измерьте число соединений, найдите источник их роста и проверьте ограничения; пул подключений — один из возможных способов исправления.
Эта статья посвящена только ошибкам лимита соединений.
Не закрывайте массово активные сеансы. Приоритет — диагностика пула, утечек и ограничений.
#Причины и решения
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Много клиентовЛимит. | Запрос показывает много соединений разных приложений/ролей | Подсчитайте потребность, настройте повторное использование соединений и пул. |
| Утечка соединенийКод. | Число сессий постепенно растёт и не уменьшается после завершения запросов | Исправьте освобождение соединений в приложении; проверьте его пул. |
| Малый max_connectionsЛимит. | Предел max_connections или CONNECTION LIMIT роли достигнут | Сравните значения с количеством активных сессий; меняйте по плану обслуживания. |
| Простаивающие сессииIdle. | Есть долго живущие idle / idle in transaction | Найдите источник сессий и корректно завершайте транзакции в коде; не убивайте процессы массово. |
#Пошаговое решение
- Проверьте число подключенийЭта проверка нужна администратору PostgreSQL. Если приложение выдаёт
too many connections for roleилиremaining connection slots are reserved, найдите доступный административный сеанс psql (на Linux иногдаsudo -u postgres psql -d postgres; при полностью исчерпанном лимите даже он может не подключиться). В psql выполнитеSHOW max_connections; SHOW superuser_reserved_connections; SELECT usename, state, count(*) FROM pg_stat_activity GROUP BY usename, state ORDER BY count(*) DESC;. Сопоставьте число соединений с ограничениями конкретной роли, а не только общим пределом. Эти запросы ничего не завершают; если вход закрыт, проверьте журналы и метрики на сервере. - Подключите пулЕсли соединения создаются слишком часто или веб-приложение открывает по одному подключению на запрос, сначала проверьте настройки пула в самом приложении: максимальное число соединений *на процесс* и число процессов. PgBouncer — отдельное средство, требующее настройки доступа, аутентификации, базы и режима pooling; устанавливайте его по согласованной схеме с тестированием на копии, так как режим transaction pooling несовместим с некоторыми особенностями сессий. После подключения пула повторите группирующий запрос к
pg_stat_activityи нагрузочную проверку. Не считайте установку PgBouncer обязательным шагом для единичной ошибки. - Закройте idle in transactionЕсли в запросе из шага 1 много соединений
idle in transaction, выясните поpid,application_name,state_changeиqueryисточник незакрытой транзакции. Попросите разработчика явно выполнять COMMIT/ROLLBACK и возвращать соединение в пул. При необходимости администратор может установитьidle_in_transaction_session_timeoutдля конкретной роли после проверки влияния на приложение; это прерывает долго простаивающие транзакции. Не выполняйте массовоеpg_terminate_backend: незавершённые операции будут отменены, а пользователи увидят сбой. - Найдите процессы-блокировщикиЕсли приложение дополнительно жалуется на долгие запросы, откройте второй сеанс psql с правами просмотра статистики и выполните запрос к
pg_stat_activity: столбцыpid,wait_event_type,wait_event,pg_blocking_pids(pid)помогают найти блокировщиков. Само по себе ожидание блокировки не равно исчерпанию лимита подключений. Не завершайте чужой процесс без проверки, что это за транзакция и кто её запустил; при отсутствии доступа запросите помощь администратора. - Упорядочьте обновленияЕсли число подключений стабильно выше допустимого даже после исправления утечек, настройте пределы одновременно на уровне приложения и базы.
max_connectionsтребует перезапуска PostgreSQL, увеличивает потребление ресурсов и не должен повышаться «на всякий случай»; проверьте оперативную память, резервные подключения и пределCONNECTION LIMITу роли через\duв psql. После согласованного обслуживания проверьте, что новое значение действует, и повторите попытку подключения. Оптимизация порядка блокировок относится к другой ошибке —deadlock detected.
#Too many connections
Администратор сравнивает SELECT usename, state, count(*) FROM pg_stat_activity GROUP BY usename, state; и параметры SHOW max_connections; с лимитами конкретной роли. Утечки соединений устраняются на стороне приложения, а PgBouncer и тайм-ауты требуют предварительных тестов. Изменять max_connections без оценки памяти и перезапуска нельзя.
#Deadlock
Ошибка deadlock detected (SQLSTATE 40P01) связана с взаимной блокировкой, а не с превышением числа соединений. При такой ошибке нужна отдельная диагностика транзакций; способы её устранения здесь не рассматриваются.
#Диагностика
Если одновременно присутствуют ожидания блокировок, для диагностики администратор может просматривать pg_stat_activity, pg_locks и pg_blocking_pids(pid). Не вызывайте pg_terminate_backend(pid) без согласования: это отменит работу сеанса. Настройка log_lock_waits относится к сбору сведений и требует оценки нагрузки.
SELECT count(*) FROM pg_stat_activity;SHOW max_connections;SELECT pid, state, query FROM pg_stat_activity WHERE state = 'idle in transaction';