Траблшутинг превышения max_connections в PostgreSQL и лимитов systemd
- Приложения получают критическую ошибку
FATAL: sorry, too many clients already. - Администраторы не могут подключиться к серверу по SSH/psql для проведения диагностики.
- Служба PostgreSQL падает с ошибкой
could not open file: Too many open files.
1. Поиск источников утечки соединений в pg_stat_activity
SELECT client_addr, usename, state, count(*)
FROM pg_stat_activity
GROUP BY client_addr, usename, state
ORDER BY count(*) DESC;2. Завершение зависших бездействующих сессий (idle)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
AND state_change < now() - INTERVAL '15 minutes'
AND pid != pg_backend_pid();3. Настройка резервирования соединений в postgresql.conf
# Лимит общих подключений (не завышайте свыше 300-500 без PgBouncer)
max_connections = 200
# Зарезервированные слоты для аварийного подключения администратора
superuser_reserved_connections = 5
# Автоматическое закрытие брошенных сессий
idle_session_timeout = 600000 # 10 минут
idle_in_transaction_session_timeout = 60000 # 1 минута4. Снятие файловых лимитов в Systemd Unit
Выполните systemctl edit postgresql и добавьте:
[Service]
LimitNOFILE=65535
LimitNPROC=65535systemctl daemon-reload
systemctl restart postgresql Частые вопросы (FAQ)
Почему нельзя просто выставить max_connections = 5000 в PostgreSQL?
Каждое соединение в PostgreSQL — это отдельный процесс ОС с собственными структурами памяти и накладными расходами на переключение контекста CPU. Большое число процессов вызывает резкую деградацию производительности из-за конкуренции за Spinlocks и L3-кэш.
Для чего нужен параметр superuser_reserved_connections?
Он оставляет указанное количество свободных слотов исключительно для пользователей с правами суперпользователя, позволяя администратору подключиться и локализовать проблему даже при 100% заполнении пула клиентами.