Wygląda na to, że masz przeciek połączenia w Twojej aplikacji, ponieważ nie zamyka połączeń w puli . Nie masz problemów tylko z <idle> in transaction
sesji, ale ze zbyt dużą liczbą połączeń.
Zabijanie połączeń nie jest właściwą odpowiedzią na to, ale jest to OK, 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 PostgreSQL? oraz Jak usunąć bazę danych PostgreSQL, jeśli są z nią aktywne połączenia? . Ten ostatni pokazuje lepsze zapytanie.
Aby ustawić limity czasu, jak zasugerował @Doon, zobacz Jak automatycznie zamykać bezczynne połączenia w PostgreSQL?, gdzie zaleca się używanie PgBouncera do proxy dla PostgreSQL i zarządzanie bezczynnymi połączeniami. To bardzo dobry pomysł, jeśli masz wadliwą aplikację, która i tak przecieka połączenia; bardzo mocno zalecamy skonfigurowanie PgBouncera.
Utrzymanie aktywności TCP nie zadziała tutaj, ponieważ aplikacja jest nadal połączona i działa, po prostu nie powinna.
W PostgreSQL 9.2 i nowszych możesz użyć nowego state_change
kolumna sygnatury czasowej i state
pole pg_stat_activity
aby zaimplementować żniwiarkę bezczynnego połączenia. Niech zadanie cron 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 stało się bezczynne. Nie przejmuj się; po prostu użyj pgbouncera.