PostgreSQL-FEHLER: Keine weiteren Verbindungen erlaubt


19

Wie können Sie PostgreSQL-Verbindungen freigeben, die von Client-Anwendungen nicht ordnungsgemäß geschlossen werden?

Ich habe eine Data-Mining-App, die mehrere Prozesse beschleunigt und alle Verbindungen zu einer lokalen PostgreSQL 9.1-Datenbank herstellt, um Daten abzurufen. Es läuft ein paar Stunden lang einwandfrei, stirbt dann aber mit dem Fehler:

FATAL:  remaining connection slots are reserved for non-replication superuser connections

Nachforschungen haben ergeben, dass dies höchstwahrscheinlich darauf zurückzuführen ist, dass die App ihre Verbindungen nicht ordnungsgemäß schließt. Diese Verbindungen werden jedoch auch mit der getöteten App nie freigegeben. Gibt es keine Zeitüberschreitung, bei der PostgreSQL automatisch eine Verbindung schließt?

Ich habe auch versucht, die max_connections von Postgres von 100 auf 200 zu erhöhen, aber beim Neustart ist mir der Fehler unterlaufen:

2014-02-23 10:51:15 EST FATAL:  could not create shared memory segment: Invalid argument
2014-02-23 10:51:15 EST DETAIL:  Failed system call was shmget(key=5432001, size=36954112, 03600).
2014-02-23 10:51:15 EST HINT:  This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter.  You can either reduce the request size or reconfigure the kernel with larger SHMMAX.  To reduce the request size (currently 36954112 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
    If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter, in which case raising the request size or reconfiguring SHMMIN is called for.
    The PostgreSQL documentation contains more information about shared memory configuration.

Mein System ist Ubuntu 12.04 und verfügt über 8 GB Arbeitsspeicher. Alle anderen PG-Einstellungen sind Standardeinstellungen. Daher bin ich mir nicht sicher, warum das System möglicherweise nicht über genügend Arbeitsspeicher verfügt.

Ich habe dann versucht, pgbouncer zu verwenden, um Verbindungen zu bündeln und wiederzuverwenden. Dies schien ein bisschen besser zu funktionieren, aber schließlich gingen mir die Verbindungen aus und ich bekam den Fehler:

ERROR:  no more connections allowed

Wie kann ich dieses Problem weiter diagnostizieren und beheben?


Zeigen Sie die Ausgabe von pg_stat_activity
ETL

Antworten:


8

Sie können die maximale Anzahl von Verbindungen erhöhen, indem Sie die Einstellungen für den gemeinsamen Speicher ändern. Wenn das Problem jedoch darin besteht, dass Ihre Verbindungen nicht geschlossen werden, sollten Sie dies wirklich beheben. Wenn die Software außer Kontrolle gerät und fehlerhaft ist, weil die Verbindungen nicht geschlossen wurden, können Sie einen Cron-Job wie den folgenden verwenden:

select pg_terminate_backend(procpid)
from pg_stat_activity
where usename = 'yourusername'
 and current_query = '<IDLE>'
 and query_start < current_timestamp - interval '5 minutes'
;

Das ist, was ich tue, um undichte Verbindungen von einer ähnlichen Buggy-Software zu beseitigen.

Alternativ können Sie Ihre fehlerhafte Software möglicherweise über einen Verbindungspool ausführen, der über eine ähnliche Funktionalität verfügt, um inaktive Verbindungen wie pgpool zu beenden.

Hinweis : Neuere Versionen von Postgres haben leicht unterschiedliche Spaltennamen:

select pg_terminate_backend(pid)
from pg_stat_activity
where usename = 'YOURDATABASEUSERNAME*'
 and state = 'idle'
 and query_start < current_timestamp - interval '5 minutes'
;

Sollte das mit 9.6 funktionieren? Wenn ich es versuche, bekomme ichpostgres=> select pg_terminate_backend(procpid) from pg_stat_activity where current_query = '<IDLE>' and query_start < current_timestamp - interval '5 minutes'; ERROR: column "procpid" does not exist LINE 1: select pg_terminate_backend(procpid) from pg_stat_activity ...
Magick

Es ist pidstatt procpidin neueren Versionen.
ETL

4

Für neuere Versionen von PostgreSQL:

select pg_terminate_backend(pid)
from pg_stat_activity
where usename = 'YOUR_DATABASE_USERNAME*'
 and state = 'idle'
 and query_start < current_timestamp - interval '5 minutes'
;

Mit den oben genannten Schritten können Sie Ihre inaktiven Verbindungen beenden. Ich hatte das gleiche Problem, aber es stellte sich heraus, dass es ein Problem mit meiner Flask- und SQLAlchemy-Methode war, eine Verbindung zur Datenbank herzustellen.

* Benutzername ist kein Tippfehler


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.