org.postgresql.util.PSQLException: FATAL: désolé, trop de clients déjà


93

J'essaie de me connecter à une base de données Postgresql, j'obtiens l'erreur suivante:

Erreur: org.postgresql.util.PSQLException: FATAL: désolé, trop de clients déjà

Que signifie l'erreur et comment la corriger?

Mon server.propertiesdossier suit:

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

Réponses:


38

Nous ne savons pas de quel fichier server.properties s'agit-il, nous ne savons pas non plus ce que signifie SimocoPoolSize ( n'est -ce pas?)

Supposons que vous utilisez un pool personnalisé de connexions de base de données. Ensuite, je suppose que le problème est que votre piscine est configurée pour ouvrir 100 ou 120 connexions, mais votre serveur Postgresql est configuré pour accepter MaxConnections=90. Ces paramètres semblent conflictuels. Essayez d'augmenter MaxConnections=120.

Mais vous devez d'abord comprendre votre infrastructure de couche db, savoir quel pool vous utilisez, si vous avez vraiment besoin d'autant de connexions ouvertes dans le pool. Et, spécialement, si vous renvoyez gracieusement les connexions ouvertes au pool


168

Une explication de l'erreur suivante:

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

Sommaire:

Vous avez ouvert plus que la limite autorisée de connexions à la base de données. Vous avez exécuté quelque chose comme ceci: à l' Connection conn = myconn.Open();intérieur d'une boucle et avez oublié de courir conn.close();. Ce n'est pas parce que votre classe est détruite et que les déchets sont récupérés que la connexion à la base de données est libérée. La solution la plus rapide à ce problème consiste à vous assurer que vous disposez du code suivant avec la classe qui crée une connexion:

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

Placez ce code dans n'importe quelle classe où vous créez une connexion. Ensuite, lorsque votre classe est garbage collection, votre connexion sera libérée.

Exécutez ce SQL pour voir les connexions postgresql max autorisées:

show max_connections;

La valeur par défaut est 100. PostgreSQL sur du bon matériel peut prendre en charge quelques centaines de connexions à la fois. Si vous voulez en avoir des milliers, vous devriez envisager d'utiliser un logiciel de regroupement de connexions pour réduire la surcharge de connexion.

Regardez exactement qui / quoi / quand / où tient ouvert vos connexions:

SELECT * FROM pg_stat_activity;

Le nombre de connexions actuellement utilisées est:

SELECT COUNT(*) from pg_stat_activity;

Stratégie de débogage

  1. Vous pouvez donner des noms d'utilisateur / mots de passe différents aux programmes qui pourraient ne pas libérer les connexions pour savoir lequel il s'agit, puis regarder dans pg_stat_activity pour savoir lequel ne nettoie pas après lui-même.

  2. Faites une trace complète de la pile d'exceptions lorsque les connexions n'ont pas pu être créées et suivez le code jusqu'à l'endroit où vous créez une nouvelle Connection, assurez-vous que chaque ligne de code où vous créez une connexion se termine par unconnection.close();

Comment définir les max_connections plus haut:

max_connections dans le postgresql.conf définit le nombre maximal de connexions simultanées au serveur de base de données.

  1. Trouvez d'abord votre fichier postgresql.conf
  2. Si vous ne savez pas où il se trouve, interrogez la base de données avec le sql: SHOW config_file;
  3. Le mien est en: /var/lib/pgsql/data/postgresql.conf
  4. Connectez-vous en tant que root et modifiez ce fichier.
  5. Recherchez la chaîne: "max_connections".
  6. Vous verrez une ligne qui dit max_connections=100.
  7. Définissez ce nombre plus grand, vérifiez la limite de votre version postgresql.
  8. Redémarrez la base de données postgresql pour que les modifications prennent effet.

Quel est le maximum max_connections?

Utilisez cette requête:

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

Je comprends la valeur 8388607, en théorie, c'est le maximum que vous êtes autorisé à avoir, mais alors un processus galopant peut consommer des milliers de connexions, et surprise, votre base de données ne répond pas jusqu'au redémarrage. Si vous aviez un max_connections raisonnable comme 100. Le programme incriminé se verrait refuser une nouvelle connexion.


4
pourquoi certaines personnes oublient le «;» après les instructions SQL?! Fait un copier-coller d'un glisser :)
codervepuis

@codervince Vous devez faire attention. J'irais presque jusqu'à dire que vous devriez transcrire les commandes plutôt que copier + coller.
AVProgrammer

4

Pas besoin d'augmenter les MaxConnections & InitialConnections. Fermez simplement vos connexions après avoir fait votre travail. Par exemple, si vous créez une connexion:

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

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

Après avoir fait votre travail, fermez la connexion:

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

11
Fermez toujours les connexions dans le bloc finally! Sinon, la connexion reste ouverte si une erreur se produit.
tine2k

1

Les lignes incriminées sont les suivantes:

MaxConnections=90
InitialConnections=80

Vous pouvez augmenter les valeurs pour autoriser davantage de connexions.


4
Et si vous avez plus de connexions autorisées, ajustez également les paramètres de mémoire pour vous aligner sur des connexions accrues.
Kuberchaun

0

Vous devez fermer toutes vos connexions par exemple: Si vous faites une instruction INSERT INTO, vous devez fermer l'instruction et votre connexion de cette manière:

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

Et si vous faites une instruction SELECT, vous devez fermer l'instruction, la connexion et l'ensemble de résultats de cette manière:

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

Je l'ai fait et ça a marché

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.