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
Widzę ich dużo. Próbujemy naprawić wyciek połączenia. Ale w międzyczasie chcemy ustawić limit czasu dla tych bezczynnych połączeń, może maksymalnie 5 minut.
postgresql
database-connection
user1012451
źródło
źródło
socketTimeout
z dokumentu wygląda na to, że całkowicie zamknę połączenie z bazą danych. Próbuję zamknąć każdy bezczynność, a licznik uruchamia się, gdy tylko zostanie nawiązane połączenie.<IDLE> in transaction
sesji, pozostawiając sesję działającą, ale w<IDLE>
stanie? Innymi słowy, zakończyć transakcję, ale nie zakończyć sesję? (Z głosem negatywnym: niejasne pytanie)idle
nieskończoność, pytamy, czy moglibyśmy ustawić limit czasu dla każdego połączenia / sesji (szczerze mówiąc nie znam poprawnej terminologii, przepraszam). Jeśli transakcja trwa 5 minut w przypadku normalnej aplikacji internetowej, coś musi być nie tak ...Odpowiedzi:
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 istate
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.
źródło
idle
. dlaczego powinienem to zamknąć.W PostgreSQL 9.6 jest nowa opcja,
idle_in_transaction_session_timeout
która powinna wykonać to, co opisujesz. Możesz to ustawić za pomocąSET
polecenia np:SET SESSION idle_in_transaction_session_timeout = '5min';
źródło
SET SESSION
dotyczy tylko bieżącej sesji (wróci do ustawień domyślnych po otwarciu nowego połączenia). Możesz także ustawić parametry konfiguracyjne na poziomie bazy danych używając np.ALTER DATABASE SET idle_in_transaction_session_timeout = '5min'
Lub używając plików konfiguracyjnych (patrz postgresql.org/docs/current/static/config-setting.html ).W PostgreSQL 9.1 bezczynne połączenia z następującym zapytaniem. Pomogło mi to zażegnać sytuację, która uzasadniała ponowne uruchomienie bazy danych. Dzieje się tak głównie w przypadku połączeń JDBC otwartych i nieprawidłowo zamkniętych.
SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE current_query = '<IDLE>' AND now() - query_start > '00:10:00';
źródło
jeśli używasz postgresql 9.6+, możesz ustawić w swoim postgresql.conf
idle_in_transaction_session_timeout = 30000
(msec)źródło
Możliwym obejściem, które pozwala włączyć limit czasu sesji bazy danych bez zewnętrznego zaplanowanego zadania, jest użycie rozszerzenia pg_timeout , które opracowałem.
źródło