So sieht die Meldung aus
FATAL: sorry, too many clients already
connection to server at "db" (10.0.0.5), port 5432 failedHäufige Ursachen
- Die Anwendung öffnet Verbindungen und schließt sie nicht, etwa nach einem Deploy oder in einem Worker ohne
finally. - Die Summe aller Poolgrößen liegt über
max_connections, besonders mit mehreren Instanzen oder Containern. - Ein PgBouncer im Modus
sessionreicht jede Client-Verbindung durch und hebt das Pooling auf. - Transaktionen bleiben
idle in transactionoffen und halten Slots, ohne zu arbeiten. - Backup, Monitoring und Migrationsjobs kommen zusätzlich zu den Anwendungspools.
Prüfen
- Belegte und erlaubte Verbindungen
psql -c "SELECT count(*) AS used, current_setting('max_connections')::int AS max FROM pg_stat_activity;" - Wer hält die Verbindungen?
psql -c "SELECT usename, state, count(*) FROM pg_stat_activity GROUP BY 1,2 ORDER BY 3 DESC;" - Lange idle-Transaktionen
psql -c "SELECT pid, now()-state_change AS idle_for, query FROM pg_stat_activity WHERE state LIKE 'idle in transaction%' ORDER BY 2 DESC LIMIT 10;" - Reservierte Slots
psql -c "SHOW superuser_reserved_connections;"
Lösung
- Erst messen, dann erhöhen:
max_connectionszu vergrößern verdeckt nur ein Leak und kostet pro Verbindung Speicher. - Leak schließen: Context-Manager bzw.
finallynutzen, Pool pro Instanz kleiner setzen alsmax_connections / Instanzen. - Für viele kurze Verbindungen PgBouncer im Modus
transactiondavorsetzen. idle_in_transaction_session_timeoutsetzen, damit hängende Transaktionen beendet werden.- Erhöhen nur mit Speicherreserve für Autovacuum und Backups, und daran denken:
max_connectionsbraucht einen Neustart.
Häufige Fragen
Reicht es, max_connections zu erhöhen?
Kurzfristig ja, bei einem Leak ist der Fehler in wenigen Stunden zurück. Erst messen, wer die Slots hält.
Warum sind weniger Verbindungen frei, als max_connections anzeigt?
Reservierte Slots für Superuser und Hintergrundprozesse zählen mit, deshalb sieht der normale Client das Limit früher.