DBAtlas · Атлас эксплуатации баз данных

Шторм подключений (слишком много соединений)

Симптом

'too many connections', 'ORA-00018', 'remaining connection slots reserved' — новые подключения отклоняются.

1. Оцените текущее состояние

Сколько подключений, каков лимит и сколько из них активны, а сколько простаивают?

Oracle

SELECT COUNT(*) total, SUM(CASE WHEN status='ACTIVE' THEN 1 ELSE 0 END) active FROM v$session WHERE type='USER';

PostgreSQL

SELECT count(*), state FROM pg_stat_activity WHERE backend_type = 'client backend' GROUP BY state;

MySQL

SHOW STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';

SQL Server

SELECT COUNT(*), status FROM sys.dm_exec_sessions WHERE is_user_process=1 GROUP BY status;

Redis

INFO clients

2. Определите источник: кто/откуда

Какое приложение/хост/пользователь открывает подключения? Обычно переполнен пул одного сервера приложений или есть утечка подключений (масса сессий idle in transaction).

PostgreSQL

SELECT client_addr, usename, state, count(*) FROM pg_stat_activity WHERE backend_type = 'client backend' GROUP BY 1,2,3 ORDER BY 4 DESC;

MySQL

SELECT host, user, count(*) FROM information_schema.processlist GROUP BY host, user ORDER BY 3 DESC;

SQL Server

SELECT host_name, program_name, login_name, COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process=1 GROUP BY host_name, program_name, login_name ORDER BY 4 DESC;

3. Немедленно получите передышку

Очистите долго простаивающие подключения и подключения idle-in-transaction. При необходимости массово сбросьте подключения проблемного приложения. Используйте слот, зарезервированный для входа администратора (PG superuser_reserved_connections).

4. Правильное решение: пул подключений

Неограниченное увеличение max_connections расходует память и лишь откладывает проблему. Правильное решение — пул подключений на стороне приложения (HikariCP, PgBouncer, ProxySQL) с разумным размером пула. Размер пула обычно около (ядра*2 + число дисков) — см. калькулятор Tools > Connection Pool.

5. Предотвратите утечки и повторение

Убедитесь, что приложение закрывает подключения (finally/using). Задайте idle_in_transaction_session_timeout и wait_timeout. Настройте оповещение по числу подключений.

Открыть в DBAtlas →