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
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.
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.
- Trouvez d'abord votre fichier postgresql.conf
- Si vous ne savez pas où il se trouve, interrogez la base de données avec le sql:
SHOW config_file;
- Le mien est en:
/var/lib/pgsql/data/postgresql.conf
- Connectez-vous en tant que root et modifiez ce fichier.
- Recherchez la chaîne: "max_connections".
- Vous verrez une ligne qui dit
max_connections=100
.
- Définissez ce nombre plus grand, vérifiez la limite de votre version postgresql.
- 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.
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(); }
la source
Les lignes incriminées sont les suivantes:
MaxConnections=90 InitialConnections=80
Vous pouvez augmenter les valeurs pour autoriser davantage de connexions.
la source
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é
la source