org.postgresql.util.PSQLException: FATAL: przepraszam, już za dużo klientów


93

Próbuję połączyć się z bazą danych Postgresql, pojawia się następujący błąd:

Błąd: org.postgresql.util.PSQLException: KRYTYCZNY: przepraszam, już za dużo klientów

Co oznacza błąd i jak go naprawić?

Mój server.propertiesplik jest następujący:

serverPortData=9042
serverPortCommand=9078
trackConnectionURL=jdbc:postgresql://127.0.0.1:5432/vTrack?user=postgres password=postgres
dst=1
DatabaseName=vTrack
ServerName=127.0.0.1
User=postgres
Password=admin
MaxConnections=90
InitialConnections=80
PoolSize=100
MaxPoolSize=100
KeepAliveTime=100
TrackPoolSize=120
TrackMaxPoolSize=120
TrackKeepAliveTime=100
PortNumber=5432
Logging=1

Odpowiedzi:


38

Nie wiemy, co to za plik server.properties , nie wiemy też, co oznacza SimocoPoolSize (prawda?)

Załóżmy, że używasz niestandardowej puli połączeń z bazą danych. Wydaje mi się, że problem polega na tym, że twoja pula jest skonfigurowana do otwierania 100 lub 120 połączeń, ale serwer Postgresql jest skonfigurowany do akceptowania MaxConnections=90. Te ustawienia wydają się sprzeczne. Spróbuj zwiększyć MaxConnections=120.

Ale najpierw powinieneś zrozumieć swoją infrastrukturę warstwy db, wiedzieć, jakiej puli używasz, jeśli naprawdę potrzebujesz tak wielu otwartych połączeń w puli. Szczególnie, jeśli wdzięcznie zwracasz otwarte połączenia do puli


168

Wyjaśnienie następującego błędu:

org.postgresql.util.PSQLException: FATAL: sorry, too many clients already.

Podsumowanie:

Otworzyłeś więcej niż dozwolony limit połączeń z bazą danych. Uruchomiłeś coś takiego: Connection conn = myconn.Open();wewnątrz pętli i zapomniałeś uruchomić conn.close();. Tylko dlatego, że twoja klasa została zniszczona i zebrane elementy bezużyteczne, nie zwalniają połączenia z bazą danych. Najszybszym rozwiązaniem jest upewnienie się, że masz następujący kod z dowolną klasą, która tworzy połączenie:

protected void finalize() throws Throwable  
{  
    try { your_connection.close(); } 
    catch (SQLException e) { 
        e.printStackTrace();
    }
    super.finalize();  
}  

Umieść ten kod w dowolnej klasie, w której tworzysz połączenie. Następnie, gdy twoja klasa jest zbierana jako śmieci, twoje połączenie zostanie zwolnione.

Uruchom ten kod SQL, aby zobaczyć dozwolone maksymalne połączenia postgresql:

show max_connections;

Wartością domyślną jest 100. PostgreSQL na dobrym sprzęcie może obsługiwać kilkaset połączeń naraz. Jeśli chcesz mieć tysiące, powinieneś rozważyć użycie oprogramowania do buforowania połączeń, aby zmniejszyć obciążenie połączenia.

Przyjrzyj się dokładnie, kto / co / kiedy / gdzie utrzymuje otwarte połączenia:

SELECT * FROM pg_stat_activity;

Liczba aktualnie używanych połączeń to:

SELECT COUNT(*) from pg_stat_activity;

Strategia debugowania

  1. Możesz podać różne nazwy użytkownika / hasła programom, które mogą nie zwalniać połączeń, aby dowiedzieć się, który to jest, a następnie zajrzeć do pg_stat_activity, aby dowiedzieć się, który z nich nie jest czyszczony po sobie.

  2. Wykonaj pełny ślad stosu wyjątków, gdy nie można było utworzyć połączeń, i postępuj zgodnie z kodem z powrotem do miejsca, w którym tworzysz nowy Connection, upewnij się, że każda linia kodu, w której tworzysz połączenie, kończy się znakiemconnection.close();

Jak ustawić wyższą wartość max_connections:

max_connections w postgresql.conf ustawia maksymalną liczbę jednoczesnych połączeń z serwerem bazy danych.

  1. Najpierw znajdź swój plik postgresql.conf
  2. Jeśli nie wiesz, gdzie to jest, wyślij zapytanie do bazy danych za pomocą polecenia sql: SHOW config_file;
  3. Mój jest w: /var/lib/pgsql/data/postgresql.conf
  4. Zaloguj się jako root i edytuj ten plik.
  5. Wyszukaj ciąg: „max_connections”.
  6. Zobaczysz wiersz, który mówi max_connections=100.
  7. Ustaw większą liczbę, sprawdź limit wersji postgresql.
  8. Uruchom ponownie bazę danych postgresql, aby zmiany odniosły skutek.

Jaka jest maksymalna maksymalna liczba połączeń?

Użyj tego zapytania:

select min_val, max_val from pg_settings where name='max_connections';

Rozumiem wartość 8388607, teoretycznie to najwięcej, co możesz mieć, ale wtedy niekontrolowany proces może pochłonąć tysiące połączeń i, niespodzianka, twoja baza danych nie odpowiada do ponownego uruchomienia. Gdybyś miał rozsądne max_connections, takie jak 100. Obrażający program nie uzyskałby nowego połączenia.


4
dlaczego niektórzy ludzie zapominają o znaku ';' po instrukcjach SQL ?! Powoduje skopiowanie i wklejenie przeciągnięcia :)
codervince

@codervince Musisz uważać. Prawie posunąłbym się do stwierdzenia, że ​​powinieneś raczej transkrybować polecenia niż kopiować i wklejać.
AVProgrammer

4

Nie ma potrzeby zwiększania MaxConnections i InitialConnections. Po zakończeniu pracy zamknij połączenia. Na przykład, jeśli tworzysz połączenie:

try {
     connection = DriverManager.getConnection(
                    "jdbc:postgresql://127.0.0.1/"+dbname,user,pass);

   } catch (SQLException e) {
    e.printStackTrace();
    return;
}

Po wykonaniu pracy zamknij połączenie:

try {
    connection.commit();
    connection.close();
} catch (SQLException e) {
    e.printStackTrace();
}

11
Zawsze zamykaj połączenia w ostatnim bloku! W przeciwnym razie połączenie pozostanie otwarte, jeśli wystąpi błąd.
tine2k

1

Obraźliwe linie są następujące:

MaxConnections=90
InitialConnections=80

Możesz zwiększyć wartości, aby umożliwić więcej połączeń.


4
A jeśli będziesz mieć więcej dozwolonych połączeń, dostosuj również parametry pamięci, aby dopasować je do zwiększonej liczby połączeń.
Kuberchaun

0

Musisz zamknąć wszystkie swoje połączenia, na przykład: Jeśli wykonujesz instrukcję INSERT INTO, musisz zamknąć instrukcję i połączenie w ten sposób:

statement.close();
Connexion.close():

A jeśli wykonasz instrukcję SELECT, musisz zamknąć instrukcję, połączenie i zestaw wyników w ten sposób:

resultset.close();
statement.close();
Connexion.close();

Zrobiłem to i zadziałało

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.