Wygląda na to, że w aplikacji występuje przeciek połączenia, ponieważ nie zamyka ona połączeń w puli . Nie masz problemów tylko z <idle> in transaction
sesjami, ale ogólnie ze zbyt dużą liczbą połączeń.
Zabijanie połączeń nie jest na to właściwą odpowiedzią, ale jest to w porządku tymczasowe obejście.
Zamiast ponownie uruchamiać PostgreSQL w celu uruchomienia wszystkich innych połączeń z bazy danych PostgreSQL, zobacz: Jak odłączyć wszystkich innych użytkowników od bazy danych postgres? i jak usunąć bazę danych PostgreSQL, jeśli są z nią aktywne połączenia? . Ta ostatnia pokazuje lepsze zapytanie.
Aby ustawić limity czasu, zgodnie z sugestią @Doon, zobacz Jak automatycznie zamykać bezczynne połączenia w PostgreSQL? , który zaleca użycie PgBouncer do proxy dla PostgreSQL i zarządzania bezczynnymi połączeniami. To bardzo dobry pomysł, jeśli masz błędną aplikację, która i tak przecieka połączenia; I bardzo silnie zaleca konfigurowania PgBouncer.
Keepalive TCP nie zrobi pracy tutaj, ponieważ aplikacja jest nadal podłączona i żywy, to po prostu nie powinno być.
W PostgreSQL 9.2 i nowszych możesz użyć nowej state_change
kolumny timestamp i state
pola of, pg_stat_activity
aby zaimplementować bezczynne połączenie. Niech zadanie crona uruchomi coś takiego:
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;
W starszych wersjach musisz zaimplementować skomplikowane schematy, które śledzą, kiedy połączenie było bezczynne. Nie przejmuj się; po prostu użyj pgbouncer.