org.postgresql.util.PSQLException: FATAL: lo siento, ya hay demasiados clientes

93

Estoy tratando de conectarme a una base de datos de Postgresql, obtengo el siguiente error:

Error: org.postgresql.util.PSQLException: FATAL: lo siento, ya hay demasiados clientes

¿Qué significa el error y cómo lo soluciono?

Mi server.propertiesarchivo es el siguiente:

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
lakshmi
fuente

Respuestas:

38

No sabemos qué archivo server.properties es ese, tampoco sabemos qué significa SimocoPoolSize (¿verdad?)

Supongamos que está utilizando un grupo personalizado de conexiones de base de datos. Entonces, supongo que el problema es que su grupo está configurado para abrir 100 o 120 conexiones, pero su servidor Postgresql está configurado para aceptar MaxConnections=90. Estos parecen escenarios conflictivos. Intente aumentar MaxConnections=120.

Pero primero debe comprender su infraestructura de capa de base de datos, saber qué grupo está utilizando, si realmente necesita tantas conexiones abiertas en el grupo. Y, especialmente, si está devolviendo con gracia las conexiones abiertas al grupo

Leonbloy
fuente
168

Una explicación del siguiente error:

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

Resumen:

Abriste más del límite permitido de conexiones a la base de datos. Ejecutó algo como esto: Connection conn = myconn.Open();dentro de un bucle y se olvidó de ejecutar conn.close();. El hecho de que su clase sea destruida y la basura recolectada no libera la conexión a la base de datos. La solución más rápida para esto es asegurarse de tener el siguiente código con cualquier clase que cree una conexión:

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

Coloque ese código en cualquier clase donde cree una conexión. Luego, cuando su clase sea recolectada como basura, su conexión será liberada.

Ejecute este SQL para ver las conexiones máximas de postgresql permitidas:

show max_connections;

El valor predeterminado es 100. PostgreSQL en un buen hardware puede admitir algunos cientos de conexiones a la vez. Si desea tener miles, debería considerar el uso de software de agrupación de conexiones para reducir la sobrecarga de conexión.

Eche un vistazo a exactamente quién / qué / cuándo / dónde mantiene abiertas sus conexiones:

SELECT * FROM pg_stat_activity;

El número de conexiones que se utilizan actualmente es:

SELECT COUNT(*) from pg_stat_activity;

Estrategia de depuración

  1. Puede dar diferentes nombres de usuario / contraseñas a los programas que podrían no liberar las conexiones para averiguar cuál es, y luego buscar en pg_stat_activity para averiguar cuál no se está limpiando después de sí mismo.

  2. Realice un seguimiento completo de la pila de excepciones cuando no se pudieron crear las conexiones y siga el código hasta donde cree una nueva Connection, asegúrese de que cada línea de código donde cree una conexión termine con unaconnection.close();

Cómo configurar max_connections más alto:

max_connections en postgresql.conf establece el número máximo de conexiones simultáneas al servidor de la base de datos.

  1. Primero encuentre su archivo postgresql.conf
  2. Si no sabe dónde está, consulte la base de datos con el sql: SHOW config_file;
  3. El mío está en: /var/lib/pgsql/data/postgresql.conf
  4. Inicie sesión como root y edite ese archivo.
  5. Busque la cadena: "max_connections".
  6. Verás una línea que dice max_connections=100.
  7. Establezca ese número más grande, verifique el límite para su versión de postgresql.
  8. Reinicie la base de datos postgresql para que los cambios surtan efecto.

¿Cuál es el máximo de max_connections?

Utilice esta consulta:

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

Entiendo el valor 8388607, en teoría eso es lo máximo que se le permite tener, pero luego un proceso fuera de control puede consumir miles de conexiones y, sorpresa, su base de datos no responde hasta que se reinicia. Si tuviera un max_connections sensato como 100. Al programa infractor se le negaría una nueva conexión.

Eric Leschinski
fuente
4
por qué algunas personas olvidan el ';' después de las sentencias SQL? Hace copiar y pegar un arrastre :)
codervince
@codervince Tienes que prestar atención. Casi iría tan lejos como para decir que debería transcribir los comandos en lugar de copiar y pegar.
AVProgrammer
4

No es necesario aumentar MaxConnections e InitialConnections. Simplemente cierre sus conexiones después de hacer su trabajo. Por ejemplo, si está creando una conexión:

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

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

Después de hacer su trabajo, estrecha conexión:

try {
    connection.commit();
    connection.close();
} catch (SQLException e) {
    e.printStackTrace();
}
JK Tomar
fuente
11
¡Siempre cierre las conexiones en el bloque final! De lo contrario, la conexión permanece abierta si ocurre un error.
tine2k
1

Las líneas ofensivas son las siguientes:

MaxConnections=90
InitialConnections=80

Puede aumentar los valores para permitir más conexiones.

Delan Azabani
fuente
4
Y si va a tener más conexiones permitidas, ajuste los parámetros de memoria también para alinearlos con el aumento de conexiones.
Kuberchaun
0

Debe cerrar todas sus conexiones, por ejemplo: si realiza una instrucción INSERT INTO, debe cerrar la declaración y su conexión de esta manera:

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

Y si realiza una declaración SELECT, debe cerrar la declaración, la conexión y el conjunto de resultados de esta manera:

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

Hice esto y funcionó

Brayan Escobedo
fuente