org.postgresql.util.PSQLException: FATAL: Entschuldigung, bereits zu viele Clients


91

Ich versuche, eine Verbindung zu einer Postgresql-Datenbank herzustellen. Es wird der folgende Fehler angezeigt:

Fehler: org.postgresql.util.PSQLException: FATAL: Entschuldigung, bereits zu viele Clients

Was bedeutet der Fehler und wie behebe ich ihn?

Meine server.propertiesDatei lautet wie folgt:

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

Antworten:


37

Wir wissen nicht, welche server.properties- Datei das ist, wir wissen auch nicht, was SimocoPoolSize bedeutet (oder?)

Angenommen, Sie verwenden einen benutzerdefinierten Pool von Datenbankverbindungen. Dann besteht das Problem vermutlich darin, dass Ihr Pool so konfiguriert ist, dass 100 oder 120 Verbindungen geöffnet werden, Ihr Postgresql-Server jedoch so konfiguriert ist, dass er akzeptiert MaxConnections=90. Diese Einstellungen scheinen widersprüchlich zu sein. Versuchen Sie zu erhöhen MaxConnections=120.

Aber Sie sollten zuerst Ihre Datenbank-Infrastruktur verstehen und wissen, welchen Pool Sie verwenden, wenn Sie wirklich so viele offene Verbindungen im Pool benötigen. Und insbesondere, wenn Sie die geöffneten Verbindungen ordnungsgemäß an den Pool zurückgeben


163

Eine Erklärung des folgenden Fehlers:

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

Zusammenfassung:

Sie haben mehr als die zulässige Anzahl von Verbindungen zur Datenbank geöffnet. Sie haben so etwas ausgeführt: Connection conn = myconn.Open();innerhalb einer Schleife und vergessen zu laufen conn.close();. Nur weil Ihre Klasse zerstört und Müll gesammelt wird, wird die Verbindung zur Datenbank nicht freigegeben. Die schnellste Lösung besteht darin, sicherzustellen, dass Sie den folgenden Code für jede Klasse haben, die eine Verbindung herstellt:

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

Platzieren Sie diesen Code in einer beliebigen Klasse, in der Sie eine Verbindung erstellen. Wenn Ihre Klasse dann Müll gesammelt hat, wird Ihre Verbindung freigegeben.

Führen Sie diese SQL aus, um die maximal zulässigen Postgresql-Verbindungen anzuzeigen:

show max_connections;

Der Standardwert ist 100. PostgreSQL auf guter Hardware kann mehrere hundert Verbindungen gleichzeitig unterstützen. Wenn Sie Tausende haben möchten, sollten Sie die Verwendung von Verbindungspooling-Software in Betracht ziehen, um den Verbindungsaufwand zu verringern.

Schauen Sie sich genau an, wer / was / wann / wo Ihre Verbindungen offen hält:

SELECT * FROM pg_stat_activity;

Die Anzahl der derzeit verwendeten Verbindungen ist:

SELECT COUNT(*) from pg_stat_activity;

Debugging-Strategie

  1. Sie können den Programmen, die möglicherweise die Verbindungen nicht freigeben, unterschiedliche Benutzernamen / Kennwörter geben, um herauszufinden, um welche es sich handelt, und dann in pg_stat_activity nachsehen, welche nicht nach sich selbst bereinigt.

  2. Führen Sie eine vollständige Ablaufverfolgung des Ausnahmestapels durch, wenn die Verbindungen nicht erstellt werden konnten, und folgen Sie dem Code bis zu dem Ort, an dem Sie eine neue erstellen Connection. Stellen Sie sicher, dass jede Codezeile, in der Sie eine Verbindung erstellen, mit einem endetconnection.close();

So stellen Sie die max_connections höher ein:

max_connections in der postgresql.conf legt die maximale Anzahl gleichzeitiger Verbindungen zum Datenbankserver fest.

  1. Suchen Sie zuerst Ihre postgresql.conf-Datei
  2. Wenn Sie nicht wissen, wo es sich befindet, fragen Sie die Datenbank mit dem SQL ab: SHOW config_file;
  3. Meins ist in: /var/lib/pgsql/data/postgresql.conf
  4. Melden Sie sich als root an und bearbeiten Sie diese Datei.
  5. Suchen Sie nach der Zeichenfolge: "max_connections".
  6. Sie sehen eine Zeile mit der Aufschrift max_connections=100.
  7. Stellen Sie diese Zahl größer ein und überprüfen Sie das Limit für Ihre Postgresql-Version.
  8. Starten Sie die postgresql-Datenbank neu, damit die Änderungen wirksam werden.

Was ist die maximale max_connections?

Verwenden Sie diese Abfrage:

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

Ich verstehe den Wert 8388607, theoretisch ist das der höchste Wert , den Sie haben dürfen, aber dann kann ein außer Kontrolle geratener Prozess Tausende von Verbindungen verschlingen, und überraschenderweise reagiert Ihre Datenbank bis zum Neustart nicht. Wenn Sie eine vernünftige max_connections wie 100 hätten. Dem fehlerhaften Programm würde eine neue Verbindung verweigert.


4
Warum vergessen manche Leute das ';' nach SQL-Anweisungen?! Macht das Kopieren und Einfügen ein Ziehen :)
Codervince

@codervince Du musst aufpassen. Ich würde fast so weit gehen zu sagen, dass Sie die Befehle transkribieren sollten, anstatt sie zu kopieren und einzufügen.
AVProgrammer

5

Die MaxConnections und InitialConnections müssen nicht erhöht werden. Schließen Sie einfach Ihre Verbindungen nach der Arbeit. Zum Beispiel, wenn Sie eine Verbindung herstellen:

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

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

Nach Ihrer Arbeit schließen Sie die Verbindung:

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

7
Verbindungen immer im Endblock schließen! Andernfalls bleibt die Verbindung offen, wenn ein Fehler auftritt.
Tine2k

1

Die beleidigenden Zeilen sind die folgenden:

MaxConnections=90
InitialConnections=80

Sie können die Werte erhöhen, um mehr Verbindungen zu ermöglichen.


4
Und wenn mehr Verbindungen zulässig sind, passen Sie auch die Speicherparameter an, um sie an erhöhte Verbindungen anzupassen.
Kuberchaun

0

Sie müssen alle Ihre Verbindungen schließen, zum Beispiel: Wenn Sie eine INSERT INTO-Anweisung erstellen, müssen Sie die Anweisung und Ihre Verbindung auf folgende Weise schließen:

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

Und wenn Sie eine SELECT-Anweisung abgeben, müssen Sie die Anweisung, den Zusammenhang und die Ergebnismenge folgendermaßen schließen:

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

Ich habe das gemacht und es hat funktioniert

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.