2012-11-05 4 views
50
1 S postgres 5038 876 0 80 0 - 11962 sk_wai 09:57 ?  00:00:00 postgres: postgres my_app ::1(45035) idle                     
1 S postgres 9796 876 0 80 0 - 11964 sk_wai 11:01 ?  00:00:00 postgres: postgres my_app ::1(43084) idle    

Ich sehe viele von ihnen. Wir versuchen, unser Verbindungsleck zu beheben. In der Zwischenzeit möchten wir eine Zeitüberschreitung für diese Leerlaufverbindungen festlegen, vielleicht maximal 5 Minuten.Gibt es eine Zeitüberschreitung für inaktive PostgreSQL-Verbindungen?

+0

wie einstellen sind Du verbindest dich mit der DB? socketTimeout könnte das sein, was Sie suchen. – Doon

+0

Wir haben diese Legacy Pylons Web App, und wir haben SQLAlchemy verwendet, aber anscheinend haben wir es nicht richtig benutzt. Ich erinnere mich nicht. Wir versuchen, das Leck zu beheben. 'socketTimeout' von dem Dokument, das so aussieht, schließt die Verbindung zur DB vollständig. Ich versuche, jeden Leerlauf zu schließen, und der Zähler startet, sobald die Verbindung hergestellt ist. – user1012451

+4

siehe http://stackoverflow.com/questions/12391174/is-it-possible-to-configure-postgresql-to-automatisch-close-idle-connections – Doon

Antwort

69

Es klingt wie Sie haben eine Verbindung in Ihrer Anwendung auslaufen, weil es nicht gepoolten Verbindungen zu schließen. Sie haben keine Probleme nur mit <idle> in transaction Sitzungen, aber mit zu vielen Verbindungen insgesamt.

Töten von Verbindungen ist nicht die richtige Antwort dafür, aber es ist eine OK-ish temporäre Problemumgehung.

Anstatt PostgreSQL neu zu starten, um alle anderen Verbindungen von einer PostgreSQL-Datenbank zu starten, siehe: How do I detach all other users from a postgres database? und How to drop a PostgreSQL database if there are active connections to it?. Letzteres zeigt eine bessere Abfrage.

Zum Festlegen von Zeitüberschreitungen, wie von @Doon empfohlen, siehe How to close idle connections in PostgreSQL automatically?, in der Sie aufgefordert werden, PgBouncer für die Verwendung von PostgreSQL zu verwenden und Verbindungen im Leerlauf zu verwalten. Dies ist eine sehr gute Idee, wenn Sie eine fehlerhafte Anwendung haben, die Verbindungen trotzdem verliert. I sehr stark empfehlen, PgBouncer zu konfigurieren.

Ein TCP keepalive wird hier nicht funktionieren, weil die App immer noch verbunden und am Leben ist, sollte es einfach nicht sein.

In PostgreSQL 9.2 und höher, können Sie die neue state_change Timestamp-Spalte und das status Feld pg_stat_activity verwenden, um eine Verbindung im Leerlauf Reaper zu implementieren. Haben Sie einen cron-Job etwas wie folgt aus:

SELECT pg_terminate_backend(pid) 
    FROM pg_stat_activity 
    WHERE datname = 'regress' 
     AND pid <> pg_backend_pid() 
     AND state = 'idle' 
     AND state_change < current_timestamp - INTERVAL '5' MINUTE; 

In älteren Versionen müssen Sie komplizierte Systeme implementieren, die verfolgen, wenn die Verbindung ging im Leerlauf. Mach dir keine Sorgen. benutze einfach pgbouncer.

+0

Gut, aber es wird andere PgAdmin Backends töten. Benutze zusätzliche Bedingung application_name = '' –

+0

Kann ich pg_terminate_backend ausführen, wenn ich pgbouncer verwende? –

+0

@HenleyChiu Ich sehe nicht warum nicht, obwohl ich nicht speziell überprüft habe. –

15

In PostgreSQL 9.1, die Verbindungen im Leerlauf mit der folgenden Abfrage. Es half mir, die Situation abzuwehren, die beim Neustart der Datenbank bestand. Dies geschieht hauptsächlich bei geöffneten und nicht ordnungsgemäß geschlossenen JDBC-Verbindungen.

SELECT 
    pg_terminate_backend(procpid) 
FROM 
    pg_stat_activity 
WHERE 
    current_query = '<IDLE>' 
AND 
    now() - query_start > '00:10:00'; 
+0

pg_terminate_backend ist in seit 8.4 –

+0

rettete mein Leben !! –

20

In PostgreSQL 9.6 gibt es eine neue Option idle_in_transaction_session_timeout die erreichen sollten, was Sie beschreiben. Sie können es den SET Befehl, zB:

SET SESSION idle_in_transaction_session_timeout = '5min'; 
+0

Es nervt, etwas so Einfaches zu fragen, aber ich bin ganz neu in Datenbanken im Allgemeinen - Könnten Sie bitte ein sehr einfaches Beispiel für die Verwendung dieser Funktion geben? –

+2

Kein Problem, aktualisierte die Antwort. – shosti

+0

Alles in früheren Versionen von PostgreSQL? – sdsc81

0

wenn Sie postgresql 9.6+ verwenden, dann in Ihrem postgresql.conf Sie

idle_in_transaction_session_timeout = 30000(ms)

Verwandte Themen