PostgreSQL LinuxWindowsmacOS

PostgreSQL: FATAL: sorry, too many clients already

  • Обновлено
  • Чтение ≈ 5 минут
  • Нужны права администратора

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

Ошибка PostgreSQL «too many connections for role» означает, что исчерпан лимит соединений роли. Найдите и закройте лишние сессии, увеличьте лимит роли, внедрите пул соединений (PgBouncer), уменьшите число подключений приложения.

В этой статье
  1. Что означает ошибка
  2. Причины
  3. Порядок
  4. Как не допустить повторения
FATAL: remaining connection slots are reserved for non-replication superuser connections
FATAL: too many connections for role "app"
По-русскиPostgreSQL: превышено число подключений.

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

Для роли PostgreSQL может быть задан лимит одновременных подключений (CONNECTION LIMIT). Когда приложение открывает больше соединений, чем разрешено, новые подключения получают FATAL: too many connections for role. Похожая ошибка про remaining connection slots относится к общему лимиту сервера max_connections (по умолчанию 100). Причины: утечки соединений в приложении, отсутствие пула, слишком много worker-процессов, зависшие транзакции, неправильные постоянные соединения в PHP-FPM.

#Причины

Возможная причинаКак узнатьЧто делать
Утечка соединенийНе закрываются.Рост числа сессий.Закрывайте, используйте пул.
Слишком много воркеровphp-fpm.Всплески нагрузки.Уменьшите max_children.
Нет пулаКаждый запрос создаёт соединение.Ошибка при пиках.PgBouncer.
Зависшие транзакцииidle in transaction.Растёт число.Тайм-аут сессии.
Мал лимит ролиCONNECTION LIMIT.Ошибка для одной роли.Увеличьте разумно.
Слишком высокий max_connectionsПамять.Тормоза сервера.Пул вместо увеличения.

#Порядок

  1. Выясните лимит роли и текущее число соединенийСообщение sorry, too many clients already обычно означает исчерпание доступных слотов PostgreSQL, а не обязательно персональный лимит роли. Администратор БД должен подключиться через существующую административную сессию или локальную консоль, если обычные подключения отклоняются. В psql выполните SHOW max_connections; и SELECT state,count(*) FROM pg_stat_activity GROUP BY state;; если нет прав, обратитесь к владельцу СУБД. Сначала соберите показатели, не увеличивайте лимиты вслепую.
  2. Посмотрите список сессий и найдите простаивающиеВ psql с нужными правами выполните SELECT pid,usename,application_name,client_addr,state,now()-state_change AS idle_for FROM pg_stat_activity ORDER BY state_change LIMIT 50;. Сравните idle (ожидание новой команды, нормальное для пулов) и idle in transaction (открытая незавершённая транзакция). Не считайте все idle лишними: приложение может повторно использовать их. Запишите время, пользователя и имя приложения.
  3. Завершите лишние сессии через pg_terminate_backendpg_terminate_backend(pid) немедленно разрывает соединение, может откатить текущую транзакцию и вызвать ошибки приложения. Выполняйте его лишь с согласованием после выявления ошибочно зависшей сессии: сначала посмотрите её pid, state и query_start, затем вызовите функцию для КОНКРЕТНОГО PID, избегая своей сессии (pid <> pg_backend_pid()). Не запускайте массовое завершение всех idle или процессов роли на рабочем сервере.
  4. Найдите источник: какое приложение и адрес создают много соединенийПо результатам pg_stat_activity сгруппируйте соединения по application_name и client_addr; сопоставьте всплеск с настройками пула приложения или веб-сервера и журналами ошибок за это время. Если приложение создаёт новое соединение на каждый запрос и не закрывает его, исправьте код/пул; увеличение max_connections лишь отложит новый отказ.
  5. Уменьшите число воркеровЕсли одновременно запущено слишком много процессов PHP-FPM/воркеров, найдите фактический пул и параметр pm.max_children на сервере приложения. Оцените, сколько соединений открывает один процесс, и изменяйте лимит только после измерения нагрузки и согласования: слишком маленький вызовет очередь запросов. Проверьте показатель подключения к PostgreSQL снова после изменения конфигурации приложения, не перезапускайте все службы без необходимости.
  6. Подключите пул соединений PgBouncerЕсли кратковременные запросы создают много одновременных подключений, рассмотрите PgBouncer по официальной документации. Администратор должен настроить отдельный адрес/порт (часто 6432), учётные записи, TLS и подходящий режим пула (transaction совместим не с любым использованием состояния сессии), затем протестировать приложение на испытательной базе. Это отдельный проект настройки, а не команда, которую нужно сразу выполнять после завершения сессий.
  7. Закрывайте соединения в приложении и настройтеВ коде приложения убедитесь, что подключение возвращается в пул после выполнения запроса, а транзакции закрываются COMMIT или ROLLBACK и не держатся во время сетевых операций. При систематических idle in transaction администратор может испытать idle_in_transaction_session_timeout на тестовом окружении и согласовать допустимое время, но таймаут принудительно завершит зависшие транзакции.
  8. Если нужно, увеличьте лимит роли или max_connectionsУвеличение max_connections — последнее средство после измерения RAM, размера рабочих процессов и запасных административных слотов. В psql проверьте SHOW max_connections;, план изменения согласуйте с администратором: для max_connections нужен перезапуск сервера, это затронет пользователей. Лимит роли ALTER ROLE ... CONNECTION LIMIT отличается от общего max_connections, поэтому сначала определите точный тип ошибки и не меняйте оба одновременно.
  9. Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
    Выберите подходящий вариант — это не команды для последовательного выполнения
    Вариант 1Лимит роли и число её соединений
    SQLКоманда
    Лимит роли и число её соединений
    SELECT rolname, rolconnlimit FROM pg_roles WHERE rolname = 'app';
    SELECT usename, count(*) FROM pg_stat_activity GROUP BY usename ORDER BY count DESC;
    SHOW max_connections;
    Вариант 2Состояния сессий и самые старые простаивающие
    SQLКоманда
    Состояния сессий и самые старые простаивающие
    SELECT pid, usename, application_name, client_addr, state, now() - state_change AS idle_for
    FROM pg_stat_activity
    WHERE usename = 'app'
    ORDER BY state_change LIMIT 20;
    Вариант 3Разрыв одного установленного соединения требует согласования; массовое завершение из оригинала удалено
    SQLРиск потери данныхПрава администратора
    Разрыв одного установленного соединения требует согласования; массовое завершение из оригинала удалено
    -- Пример только для уже проверенного PID 12345; замените на реальный
    SELECT pg_terminate_backend(12345) WHERE 12345 <> pg_backend_pid();

    Эта команда может привести к потере данных или существенным изменениям. Проверьте параметры, резервную копию и возможность отката.

    Вариант 4Опасные ALTER ROLE и глобальная установка 60-секундного таймаута исключены
    SQLКомандаПрава администратора
    Опасные ALTER ROLE и глобальная установка 60-секундного таймаута исключены
    -- Пример проверки параметров, не изменяющий конфигурацию
    SHOW max_connections;
    SELECT rolname,rolconnlimit FROM pg_roles WHERE rolname = current_user;
    Вариант 5Минимальная конфигурация PgBouncer (режим по транзакциям)
    INIКоманда
    Минимальная конфигурация PgBouncer (режим по транзакциям)
    [databases]
    appdb = host=127.0.0.1 port=5432 dbname=appdb
    [pgbouncer]
    listen_addr = 127.0.0.1
    listen_port = 6432
    auth_type = scram-sha-256
    auth_file = /etc/pgbouncer/userlist.txt
    pool_mode = transaction
    default_pool_size = 20
    max_client_conn = 500
    Вариант 6Удалены ALTER SYSTEM SET и немедленный перезапуск PostgreSQL
    Linux · Терминал (Bash)Команда
    Удалены ALTER SYSTEM SET и немедленный перезапуск PostgreSQL
    # Команды только для диагностики в psql, без изменения конфигурации
    SHOW max_connections;
    SELECT count(*) FROM pg_stat_activity;

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

Задайте на уровне приложения максимальный размер пула меньше лимита роли с запасом. Включите мониторинг (pg_stat_activity, Prometheus postgres_exporter). Каждое соединение PostgreSQL занимает около 5–10 МБ памяти, поэтому увеличение max_connections до тысяч без пула приведёт к нехватке RAM.

Так эту ошибку тоже называют

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

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