PostgreSQL LinuxWindowsmacOS

Как устранить too many connections (53300) в PostgreSQL без потери запросов

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

SQLSTATE 53300 означает, что подключений к PostgreSQL стало больше допустимого количества для новой сессии. Веб-приложение может накапливать соединения из-за утечки, большого числа процессов или отсутствия пула. Увеличивать max_connections наугад нельзя: каждая сессия расходует память, а изменение обычно требует перезапуска сервера.

В этой статье
  1. Что означает ошибка
  2. Как различить причины
  3. Пошаговая диагностика и устранение
  4. Воспроизведение и проверка только в отдельной тестовой базе
  5. Как убедиться в исправлении и что делать дальше

#Что означает ошибка

SQLSTATE 53300 означает, что подключений к PostgreSQL стало больше допустимого количества для новой сессии. Веб-приложение может накапливать соединения из-за утечки, большого числа процессов или отсутствия пула. Увеличивать max_connections наугад нельзя: каждая сессия расходует память, а изменение обычно требует перезапуска сервера.

#Как различить причины

Возможная причинаКак узнатьЧто делать
Приложение не возвращает подключения в пулКод создаёт новое соединение для каждого запроса и не освобождает его.Число сессий по одному application_name растёт и почти не уменьшается.Исправить управление жизненным циклом подключения и использовать ограниченный пул.
Слишком много работников приложенияКаждый PHP-FPM/Node.js/другой процесс держит собственный пул.После увеличения числа работников резко растут соединения на стороне СУБД.Ограничить суммарный размер пулов и сравнить его с лимитом PostgreSQL.
Долгие и незавершённые транзакцииСессии долго остаются idle in transaction или заняты запросом.pg_stat_activity показывает возрастные транзакции и состояние idle in transaction.Найти запрос/код и обеспечить COMMIT или ROLLBACK на соответствующей ветке.

#Пошаговая диагностика и устранение

  1. Снимите симптом, не создавая новые подключенияЗапишите полную ошибку too many connections, SQLSTATE 53300 и примерное время возникновения из журнала приложения. Проверьте, происходит ли она только под нагрузкой или постоянно. Не запускайте стресс-тест: он может отнять последние доступные сеансы. Если администратор может подключиться через зарезервированный доступ, дальнейшие проверки выполняет он.
  2. Попробуйте обычный мониторинг только при доступном подключенииВ уже открытом psql или pgAdmin подключитесь к нужной базе и выполните SELECT current_database(), version(); SHOW max_connections;. Если новая сессия не создаётся, не пытайтесь многократно войти под разными пользователями — попросите администратора использовать штатный служебный доступ. Этот шаг не требует перезапуска.
  3. Определите, кто занимает подключенияПри наличии прав выполните запрос к pg_stat_activity, группирующий сессии по datname, usename, application_name и state. Сравните группы с настройками веб-приложения и числом его процессов. Если вы видите только свои сессии или часть полей скрыта, попросите администратора дать агрегированные показатели — не меняйте права пользователям ради диагностики.
  4. Найдите незавершённые транзакцииИспользуйте запрос на чтение с фильтром state = 'idle in transaction' из блока команд. Просмотрите возраст и application_name. Наличие старой транзакции не означает, что её разрешено прерывать: она может удерживать важные изменения. Найдите соответствующий обработчик приложения и причину отсутствующего COMMIT/ROLLBACK.
  5. Сверьте суммарное количество подключений в приложенииОткройте конфигурацию используемого драйвера или пула и число одновременно работающих процессов (например, настройки PHP-FPM, Node.js cluster, системы очередей). Рассчитайте верхнюю оценку: процессы × максимальный размер пула, плюс фоновые задания и служебные сессии. Если оценка существенно больше лимита, уменьшайте пул или число работников после проверки производительности.
  6. Исправьте повторное открытие соединенийВ коде найдите место, где соединение создаётся при каждом HTTP-запросе. Для драйвера с пулом используйте один управляемый пул на процесс и освобождение клиента в finally по официальной документации драйвера. Если есть утечка, проверьте каждую ветку исключения. Перезапустите только тестовый экземпляр приложения и сравните число соединений до и после серии запросов.
  7. Не завершайте неизвестные сессии без согласованияЕсли проблема уже влияет на рабочий сайт и требуется срочное действие, сначала покажите администратору диагностические группы и журналы. Не используйте безусловное pg_terminate_backend по всем pid: оно прерывает транзакции и пользовательские операции. Администратор может адресно завершить доказанно зависшую сессию после проверки владельца и последствий, либо штатно уменьшить нагрузку.
  8. Меняйте лимит только после оценки ресурсовЕсли исправленный пул всё равно исчерпывает доступные подключения, администратор планирует параметр max_connections вместе с памятью, резервами служебных подключений и окном перезапуска. До изменения сохраните конфигурацию и резервную копию, после — проверьте SHOW max_connections; и доступность приложения. Если вмешательство ухудшило состояние, верните прежний параметр и согласованно перезапустите сервер.
  9. Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
    Выберите подходящий вариант — это не команды для последовательного выполнения
    Вариант 1В существующей административной сессии SQL; только чтение.
    SQLКоманда
    В существующей административной сессии SQL; только чтение. Значение total_sessions включает текущую сессию и фоновые процессы, а не только веб-подключения.
    SHOW max_connections;
    SELECT count(*) AS total_sessions FROM pg_stat_activity;
    Вариант 2Только чтение; backend_type доступно в поддерживаемых современных версиях PostgreSQL.
    SQLКоманда
    Только чтение; backend_type доступно в поддерживаемых современных версиях PostgreSQL. Для старых выпусков сверяйте описание представления.
    SELECT datname, usename, application_name, state, count(*) AS sessions FROM pg_stat_activity WHERE backend_type = 'client backend' GROUP BY datname, usename, application_name, state ORDER BY sessions DESC;
    Вариант 3Только чтение.
    SQLКоманда
    Только чтение. Не используйте возвращённые PID для автоматического прерывания; сверяйте время и владельца.
    SELECT pid, datname, usename, application_name, now() - xact_start AS transaction_age FROM pg_stat_activity WHERE state = 'idle in transaction' AND xact_start IS NOT NULL ORDER BY transaction_age DESC LIMIT 20;

#Воспроизведение и проверка только в отдельной тестовой базе

SQL
Минимальный пример наблюдения, безопасен в любой доступной тестовой базе на поддерживаемой версии. Ожидаются число configured_max и client_sessions; искусственно открывать сотни соединений ради проверки запрещено.
SELECT current_setting('max_connections') AS configured_max, count(*) FILTER (WHERE backend_type='client backend') AS client_sessions FROM pg_stat_activity;

#Как убедиться в исправлении и что делать дальше

После исправления повторите привычную нагрузку на тестовой среде, отслеживая client_sessions в течение нескольких минут: число должно стабилизироваться ниже допустимого уровня, а 53300 исчезнуть из журнала. Если ошибки продолжаются, передайте администратору график подключений, размеры пулов, число процессов и настройки резервов; повторное повышение лимита без диагностики не считать решением.

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.