org.postgresql.util.PSQLException: FATAL: desculpe, já há muitos clientes


99

Estou tentando me conectar a um banco de dados Postgresql, estou recebendo o seguinte erro:

Erro: org.postgresql.util.PSQLException: FATAL: desculpe, já há muitos clientes

O que significa o erro e como faço para corrigi-lo?

Meu server.propertiesarquivo está seguindo:

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

Respostas:


44

Não sabemos que arquivo server.properties é esse, nem sabemos o que SimocoPoolSize significa (e você?)

Vamos supor que você esteja usando algum pool personalizado de conexões de banco de dados. Então, acho que o problema é que seu pool está configurado para abrir 100 ou 120 conexões, mas seu servidor Postgresql está configurado para aceitar MaxConnections=90. Essas configurações parecem conflitantes. Experimente aumentar MaxConnections=120.

Mas primeiro você deve entender sua infraestrutura de camada de banco de dados, saber qual pool está usando, se realmente precisar de tantas conexões abertas no pool. E, especialmente, se você estiver retornando normalmente as conexões abertas para o pool


174

Uma explicação do seguinte erro:

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

Resumo:

Você abriu mais do que o limite permitido de conexões com o banco de dados. Você executou algo assim: Connection conn = myconn.Open();dentro de um loop e se esqueceu de executar conn.close();. Só porque sua classe foi destruída e o lixo coletado não libera a conexão com o banco de dados. A solução mais rápida para isso é garantir que você tenha o seguinte código com qualquer classe que cria uma conexão:

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

Coloque esse código em qualquer classe onde você cria uma conexão. Então, quando sua classe for coletada como lixo, sua conexão será liberada.

Execute este SQL para ver as conexões máximas do postgresql permitidas:

show max_connections;

O padrão é 100. PostgreSQL em um bom hardware pode suportar algumas centenas de conexões por vez. Se você deseja ter milhares, deve considerar o uso de software de pool de conexão para reduzir a sobrecarga de conexão.

Dê uma olhada em exatamente quem / o quê / quando / onde está mantendo suas conexões abertas:

SELECT * FROM pg_stat_activity;

O número de conexões usadas atualmente é:

SELECT COUNT(*) from pg_stat_activity;

Estratégia de depuração

  1. Você pode dar nomes de usuário / senhas diferentes aos programas que podem não estar liberando as conexões para descobrir qual é, e então olhar em pg_stat_activity para descobrir qual deles não está limpando depois de si mesmo.

  2. Faça um rastreamento de pilha de exceção completo quando as conexões não puderam ser criadas e siga o código de volta até onde você criou um novo Connection, certifique-se de que cada linha de código onde você cria uma conexão termina com umconnection.close();

Como definir max_connections mais alto:

max_connections no postgresql.conf define o número máximo de conexões simultâneas com o servidor de banco de dados.

  1. Primeiro encontre seu arquivo postgresql.conf
  2. Se você não sabe onde está, consulte o banco de dados com o sql: SHOW config_file;
  3. O meu está em: /var/lib/pgsql/data/postgresql.conf
  4. Faça login como root e edite esse arquivo.
  5. Procure a string: "max_connections".
  6. Você verá uma linha que diz max_connections=100.
  7. Aumente esse número, verifique o limite para sua versão do postgresql.
  8. Reinicie o banco de dados postgresql para que as alterações tenham efeito.

Qual é o máximo max_connections?

Use esta consulta:

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

Eu entendi o valor 8388607, em teoria é o máximo que você pode ter, mas um processo descontrolado pode consumir milhares de conexões e, surpresa, seu banco de dados não responde até a reinicialização. Se você tivesse um max_connections sensível como 100. O programa ofensivo teria uma nova conexão negada.


5
por que algumas pessoas esquecem o ';' depois das instruções SQL ?! Arrastar e copiar :)
codervince

@codervince Você tem que prestar atenção. Eu quase diria que você deve transcrever os comandos em vez de copiar + colar.
AVProgrammer

3

Não há necessidade de aumentar MaxConnections e InitialConnections. Apenas feche suas conexões após fazer seu trabalho. Por exemplo, se você estiver criando uma conexão:

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

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

Depois de fazer seu trabalho, feche a conexão:

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

13
Sempre feche as conexões no bloco finally! Caso contrário, a conexão permanecerá aberta se ocorrer um erro.
tine2k

1

As linhas ofensivas são as seguintes:

MaxConnections=90
InitialConnections=80

Você pode aumentar os valores para permitir mais conexões.


4
E se você tiver mais conexões permitidas, ajuste os parâmetros de memória também para alinhar com o aumento das conexões.
Kuberchaun

0

Você precisa fechar todas as suas conexões, por exemplo: Se você fizer uma instrução INSERT INTO, você precisa fechar a instrução e sua conexão desta forma:

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

E se você fizer uma instrução SELECT, você precisa fechar a instrução, a conexão e o conjunto de resultados desta forma:

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

eu fiz isso e funcionou

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.