Meu Postgres não conecta: troubleshooting de conexões

Introdução

Nesse artigo, vamos explorar problemas comuns ao tentar se conectar com seu servidor PostgreSQL. Há diversas possibilidades de problemas enfrentados, então veremos cenários mais comuns e como solucioná-los da maneira mais simples e rápida possível.

Roteiro:

  • O postgres está no ar?
  • Temos rota para conectar?
  • O pg_hba.conf e o postgresql.conf estão conectados devidamente?
  • Eu tenho permissão para me conectar?
  • Meu usuário existe?
  • O banco de dados existe?
  • A senha está correta?


Verifique sempre os logs da sua aplicação e, se possível, tente estabelecer uma conexão com o banco de dados utilizando o psql, que é o client oficial do PostgreSQL. Faça isso para eliminar qualquer possibilidade de erro em outra camada da sua aplicação e para poder ver claramente os erros que acontecem durante a conexão. Claro que para isso você vai precisar instalar o client do PostgreSQL no seu servidor de aplicação ou desktop, dependendo do caso. Sempre teste a conexão a partir do mesmo lugar da aplicação. Dependendo da origem da conexão, rotas, firewalls, VPNs, entre outras variáveis na sua rede podem mudar. Vamos mostrar aqui vários exemplos de erros que acontecem durante a conexão e simulá-los sempre utilizando o psql.

Recebi uma mensagem dizendo que o banco de dados não está no ar!

Na maioria das vezes, o erro que você vai receber quando tem um problema de conexão é este aqui:

psql shell: mensagem de erro por banco de dados fora do ar
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory
        Is the server running locally and accepting connections on that socket?


Apesar de a mensagem dar a entender que o seu banco de dados não está no ar, o motivo desse aviso pode variar um pouco:

  1. Você pode ter digitado o endereço do servidor ou a porta incorretamente;
  2. Você pode não ter uma rota na rede até o servidor;
  3. Pode haver um firewall bloqueando o caminho até o servidor;
  4. O banco de dados pode realmente não estar no ar; 
  5. O parâmetro listen_address pode estar desativado para esse IP.

A primeira coisa a fazer numa tentativa falha de conexão com o banco de dados, como a exibida anteriormente, é checar se o serviço do banco está disponível, ou seja, no ar. 

É possível verificar o status desse serviço com diversos comandos, que já abordamos por aqui, mas, para relembrar, veja alguns deles (se executados como usuário root, pode ser necessário utilizar o comando sudo antes, caso esteja logado com outro usuário):

  • ps -faux | grep postgres (este método é o mais confiável e funciona para qualquer ambiente Linux/Unix):
Debian shell: processos postgres
# ps -faux | grep postgres
root     1820618  0.0  0.1   3876  1832 pts/0    S+   14:41   0:00          \_ grep postgres
999      3358569  0.0  1.4 220064 14652 ?        Ss   Jul23   7:16  \_ postgres
999      3358637  0.0  3.1 220352 31392 ?        Ss   Jul23   0:05      \_ postgres: checkpointer
999      3358638  0.0  0.7 220216  7452 ?        Ss   Jul23   1:07      \_ postgres: background writer
999      3358640  0.0  0.7 220192  6904 ?        Ss   Jul23   1:13      \_ postgres: walwriter
999      3358641  0.0  0.4 221656  4024 ?        Ss   Jul23   1:45      \_ postgres: autovacuum launcher
999      3358642  0.0  0.4 221644  4020 ?        Ss   Jul23   0:03      \_ postgres: logical replication launcher
999        82547  0.0  1.0  11828 10184 ?        Sl   Aug20   4:02      \_ postgres:
999      1800988 99.5 27.7 308912 272700 ?       Sl   Oct16 1170:12          \_ postgres:


Caso o banco não esteja no ar, não aparecerão os diversos processos do serviço postgres, aparecendo, em geral, apenas o processo da própria busca do comando grep.

  • systemctl status postgresql (funciona para sistemas Linux modernos que usam o systemd configurados corretamente com o PostgreSQL. Porém, nos sistemas baseados em Red Hat, é necessário colocar -<número_versão> após postgresql, por exemplo: systemctl status postgresql-13): 
Debian shell: consulta do status do serviço postgres
# systemctl status postgresql
 postgresql.service - PostgreSQL RDBMS
     Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; preset: enabled)
     Active: active (exited) since Tue 2024-04-09 18:41:03 UTC; 5 months 0 days ago
    Process: 439735 ExecReload=/bin/true (code=exited, status=0/SUCCESS)
   Main PID: 171728 (code=exited, status=0/SUCCESS)
        CPU: 1ms

Sep 04 19:32:13 debian-teste systemd[1]: Reloading postgresql.service - PostgreSQL RDBMS...
...

Se o banco de dados estiver fora do ar, a seção ‘Active’ exibirá ‘inactive (dead)’, também indicando desde quando o serviço está nesse estado, conforme o exemplo. Há a possibilidade de o comando systemctl não estar disponível, se o servidor foi inicializado sem o systemd, e se for esse o caso, deverão ser utilizadas as outras alternativas demonstradas.

Uma última observação importante é que se o PostgreSQL estiver sendo manipulado sem o comando systemctl, pode ser que este método apresente informações incorretas, portanto, pode não ser uma boa ideia confiar nele.

  • pg_lsclusters (para sistemas baseados em Debian):
Debian shell: consulta do serviço postgres
# pg_lsclusters
Ver Cluster     Port Status Owner    Data directory                     Log file
16  main        5432 online postgres /var/lib/postgresql/16/main        /var/log/postgresql/postgresql-16-main.log
16  novocluster 5433 online postgres /var/lib/postgresql/16/novocluster /var/log/postgresql/postgresql-16-novocluster.log


Aqui, se o serviço estiver fora do ar, aparecerá ‘down’ no lugar de ‘online’, com as letras geralmente na cor vermelha, para indicar que não está funcionando. 

  • pg_ctlcluster <sua_versao> <nome_cluster> status (apenas para sistemas baseados em Debian):
Debian shell: consulta do serviço postgres
# pg_ctlcluster 16 main status
pg_ctl: server is running (PID: 433805)
/usr/lib/postgresql/16/bin/postgres "-D" "/var/lib/postgresql/16/main" "-c" "config_file=/etc/postgresql/16/main/postgresql.conf"


No caso de o banco estar fora do ar, o retorno será ‘pg_ctl: no server running’.

  • sc query postgresql-x64-<número_versão> (para Windows):
Windows shell: consulta do serviço postgres
C:\Windows\System32>sc query postgresql-x64-16

NOME_DO_SERVIÇO: postgresql-x64-16
    TIPO                       : 10  WIN32_OWN_PROCESS
    ESTADO                     : 4  RUNNING
                                (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
    CÓDIGO_DE_SAÍDA_DO_WIN32   : 0  (0x0)
    CÓDIGO_DE_SAÍDA_DO_SERVIÇO : 0  (0x0)
    PONTO_DE_VERIFICAÇÃO       : 0x0
    AGUARDAR_DICA              : 0x0

Aqui, a mudança para o banco fora do ar seria no ‘ESTADO’, diferente de ‘RUNNING’.

Como você pode ver, nos nossos exemplos, todos os comandos retornaram resposta positiva quanto ao estado do serviço do banco, que está no ar. Mas e se não estivesse, o que poderia ser feito? Como já citamos em artigos anteriores, no Linux é possível gerenciar o estado do seu banco de dados também com o utilitário systemctl:

  • Para subir, poderíamos utilizar o comando (que não tem saída):
    systemctl start postgresql

    E assim checar novamente o status do banco por um dos meios mencionados anteriormente.

    Em Windows, o comando para iniciar é: net start postgresql-x64-16 


Observação: se você iniciou o serviço, verifique se ele realmente subiu. Se não subir, verifique os logs do PostgreSQL para entender o motivo. Se o banco de dados estiver no ar, verifique novamente se a conexão funciona, primeiro localmente, depois remotamente.

Temos rota para conectar?

Depois de checar o status do serviço do PostgreSQL, caso ainda não tenha conseguido conectar, pode ser interessante checar a rota de conexão com o banco de dados. 
Algumas das mensagens de erros comuns para esse tipo de situação são:

psql shell: mensagem de erro por conexão recusada
psql: error: could not connect to server: Connection refused Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432?
psql shell: mensagem de erro por conexão falha
psql: error: connection to server at "192.168.0.1", port 5432 failed: Connection timed out        
Is the server running on that host and accepting TCP/IP connections?

Podemos conferir o status da rota consultando a conectividade de rede entre o cliente e o servidor PostgreSQL por meio de algumas ferramentas comuns:

  • Ping: verifica se o servidor está acessível a partir do cliente. O comando ping <ip-do-servidor> pode ser usado para verificar a resposta do servidor. Se o servidor não responder, isso pode indicar problemas de rede, como bloqueio por firewall ou roteamento incorreto. O comando ping está disponível tanto em Windows quanto em Linux e funciona de forma similar. É um bom comando para ver se um servidor está no ar, mesmo sem saber a porta que será utilizada. No entanto, alguns servidores têm o “ping” bloqueado intencionalmente por motivos de segurança, por isso ele nem sempre é a forma mais recomendada de verificar se o servidor remoto está acessível. 
Debian shell: teste de conexão via comando ping
$ ping 159.89.241.130
PING 159.89.241.130 (10.0.0.240) 56(84) bytes of data.
64 bytes from 159.89.241.130: icmp_seq=1 ttl=64 time=0.081 ms
64 bytes from 159.89.241.130: icmp_seq=2 ttl=64 time=0.127 ms
64 bytes from 159.89.241.130: icmp_seq=3 ttl=64 time=0.063 ms
64 bytes from 159.89.241.130: icmp_seq=4 ttl=64 time=0.058 ms
64 bytes from 159.89.241.130: icmp_seq=5 ttl=64 time=0.054 ms
64 bytes from 159.89.241.130: icmp_seq=6 ttl=64 time=0.062 ms
  • Porta: em todos os demais exemplos, você vai precisar saber em qual porta o PostgreSQL está rodando. A porta padrão é a 5432, mas ela pode ser substituída por outra conforme a necessidade. Uma maneira confiável de verificar a porta em uso é conectar-se ao banco de dados localmente via psql e executar o comando SHOW port:
psql shell: consulta de porta
postgres=# SHOW port;
 port
------
 5432
(1 row)

No caso de sistemas baseados em Debian, também é possível usar o comando pg_lsclusters:

Debian shell: consulta de porta
# pg_lsclusters
Ver Cluster Port Status Owner    Data directory              Log file
16  main    5432 online postgres /var/lib/postgresql/16/main /var/log/postgresql/postgresql-16-main.log
  • Nmap: o Nmap foi desenvolvido na década de 1990 como uma forma de descobrir serviços e portas utilizadas numa rede. Se você não tiver acesso local ao servidor, para verificar qual é a porta utilizada, ou se o seu administrador de redes estiver indisponível, você pode utilizar o Nmap, que faz isso para você. Alguns administradores podem não gostar muito de alguém varrendo a rede local e cutucando de porta em porta do servidor para saber se alguma está aberta. Existem ambientes com defesas contra esse tipo de ação, por ser utilizada por pessoas com más intenções querendo invadir um servidor. Esteja avisado!
Debian shell: retorno do comando nmap
$ nmap 159.89.241.130
Starting Nmap 7.93 ( https://nmap.org ) at 2024-12-11 15:10 -03
Nmap scan report for 159.89.241.130
Host is up (0.12s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT     STATE    SERVICE
3/tcp    filtered compressnet
22/tcp   open     ssh
5432/tcp open     postgresql

Nmap done: 1 IP address (1 host up) scanned in 14.55 seconds
  • Telnet: é um protocolo desenvolvido na década de 1960, que embora ninguém mais pense em usar com a sua finalidade original, é utilizado por algumas pessoas  para testar conexões entre computadores, por ser amplamente conhecido e fácil de usar, estando disponível em qualquer sistema operacional. O comando telnet <ip-do-servidor> 5432 pode ser aplicado para testar se a porta está acessível. Se a conexão for bem-sucedida, você verá uma mensagem confirmando a conexão (antes, pode ser necessário instalar o pacote do Telnet). Provavelmente, o Telnet não estará instalado por padrão. Você também pode utilizar as próximas opções da nossa lista. Recomendamos!
Debian shell: retorno do comando telnet
$ telnet 159.89.241.130 5432
Trying 159.89.241.130...
Connected to 159.89.241.130.
Escape character is '^]'.
  • Netcat: similar ao Telnet, o comando nc -vz <ip-do-servidor> 5432 pode ser usado para verificar se a porta está aberta e acessível (também pode ser necessário instalar o pacote antes):
Debian shell: retorno do comando netcat
$ nc -vz 159.89.241.130 5432
Connection to 159.89.241.130 5432 port [tcp/postgresql] succeeded!

Não tenho rota para o servidor, pode ser um firewall no caminho

Se você sabe que o PostgreSQL está no ar, sabe em qual porta ele roda, usou um dos aplicativos citados para tentar verificar e mesmo assim não conseguiu chegar ao banco de dados, você provavelmente está sendo bloqueado por alguma regra de segurança do firewall.

Para verificar se o firewall local está ativo, podemos utilizar os seguintes comandos:

  • Para sistemas baseados em Debian/Ubuntu (usando UFW): sudo ufw status
  • Para sistemas baseados em Red Hat/CentOS (usando firewalld): sudo firewall-cmd --list-all


Aqui, a resposta pode ser firewall ativo ou não (active/inactive), e caso não esteja ativo, é improvável que ele cause alguma dificuldade de conexão. Se estiver ativo, podemos ainda checar se a porta do lado do servidor está aberta com os comandos a seguir:

  • Para sistemas baseados em Debian/Ubuntu (usando UFW):
    • Verificar a porta: sudo ufw status | grep 5432
  • Abrir a porta (se necessário): sudo ufw allow 5432/tcp

  • Para sistemas baseados em Red Hat/CentOS (usando firewalld):
    • Verificar: sudo firewall-cmd --list-ports | grep 5432
  • Abrir:
    sudo firewall-cmd --zone=public --add-port=5432/tcp --permanent
    sudo firewall-cmd --reload


Geralmente, não é necessário abrir portas específicas no firewall do cliente para conexões de saída. No entanto, se houver restrições, você pode precisar permitir conexões de saída para a porta 5432:

  • Para sistemas baseados em Debian/Ubuntu (usando UFW):
    sudo ufw allow out to any port 5432
  • Para sistemas baseados em Red Hat/CentOS (usando firewalld):
    sudo firewall-cmd --zone=public --add-port=5432/tcp --permanent
    sudo firewall-cmd --reload

E se o firewall não for local?

Vejamos:

  • O banco de dados está no ar;
  • Você sabe a porta correta;
  • Não existe nenhum firewall local ativo;
  • Ainda assim você não tem rota até o banco de dados.


Nesse momento, pode haver algum problema de rota, firewall etc. no meio do caminho. Você vai precisar conversar com o administrador de redes para ajudar nisso. Foge um pouco do escopo deste artigo entrar nesses meandros, pois existem muitas variáveis que dependem da arquitetura da rede, da segurança, do uso de VPN etc. 

O pg_hba.conf e o postgresql.conf estão configurados devidamente?

Conforme abordado no último artigo, o pg_hba.conf é o arquivo que dita as regras de autenticação do banco de dados, o que significa que a sua configuração correta impacta totalmente em uma conexão bem-sucedida. Caso tenha algum problema ou impedimento nessas configurações, você deverá receber um retorno como este:

psql shell: mensagem de erro no pg_hba.conf
psql: error: connection to server at "192.168.0.1" (::1), port 5432 failed: FATAL:  no pg_hba.conf entry for host "::1", user "postgres", database "postgres", SSL off


Certificar-se de que o seu usuário e IP têm permissão de conexão no banco de dados correto no arquivo é um passo fundamental em caso de erro no acesso remoto, bem como seu usuário (ou grupo de usuários).

Além disso, no arquivo de configurações do PostgreSQL, o postgresql.conf, existe um parâmetro que é imprescindível para permitir conexões externas, o listen_addresses, que por padrão vem com o valor de localhost, significando que o servidor escuta do endereço local. É possível fazer restrições aqui, para maior segurança, podendo permitir IPs específicos, por exemplo:

postgresql.conf: definindo valores para parâmetro listen_adresses
listen_addresses = '192.168.1.100, localhost'

Então é necessário ter certeza de que está autorizado nas regras de ambos os arquivos.
Caso haja algum ajuste para permitir a conexão, o PostgreSQL deverá ser recarregado ou reiniciado, para que as novas configurações sejam aplicadas. Isso pode ser feito com os seguintes comandos:

  • Para recarregar (sem interromper conexões atuais, o suficiente para mudanças no pg_hba.conf): systemctl reload postgresql
  • Para reiniciar o banco (caso tenha alterado o parâmetro listen_addresses): systemctl restart postgresql


O banco de dados existe?

Outra possível causa de falha de conexão é o banco de dados que você está tentando acessar não existir. Nessa situação, temos a seguinte mensagem de erro:

psql shell: mensagem de erro sobre banco de dados inexistente
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL:  database "banco1" does not exist


Caso tenha esse retorno e queira verificar se digitou corretamente o nome do banco de dados ou se ele está presente no servidor apontado, você pode verificar isso localmente com um terminal psql (como usuário administrador) e listar todos os bancos de dados disponíveis com o comando \l. Esse e outros comandos básicos do psql podem ser relembrados no artigo Utilização do psql.

Esta é a nossa listagem de bancos:

psql shell: listando todos os bancos de dados
postgres=# \l
                                                    List of databases
    Name    |  Owner   | Encoding | Locale Provider | Collate |  Ctype  | ICU Locale | ICU Rules |   Access privileges
------------+----------+----------+-----------------+---------+---------+------------+-----------+-----------------------
 aplicacao1 | postgres | UTF8     | libc            | C.UTF-8 | C.UTF-8 |            |           |
 postgres   | postgres | UTF8     | libc            | C.UTF-8 | C.UTF-8 |            |           |
 template0  | postgres | UTF8     | libc            | C.UTF-8 | C.UTF-8 |            |           | =c/postgres          +
            |          |          |                 |         |         |            |           | postgres=CTc/postgres
 template1  | postgres | UTF8     | libc            | C.UTF-8 | C.UTF-8 |            |           | =c/postgres          +
            |          |          |                 |         |         |            |           | postgres=CTc/postgres
(4 rows)


Se o banco de dados que você está tentando acessar estiver listado, ele existe. Caso contrário, se necessário, você pode criá-lo com o comando CREATE DATABASE:

psql shell: comando para criar nova base de dados
CREATE DATABASE <nome_do_banco> OWNER <nome_do_usuario>;

Meu usuário existe?

Outra questão fundamental na hora de resolver problemas de conexão é garantir que o usuário que está tentando se conectar ao PostgreSQL realmente existe no banco de dados. Se o usuário não estiver devidamente criado ou não tiver as permissões corretas, a conexão falhará.

A mensagem de erro para essa ocasião é:

psql shell: mensagem de erro sobre usuário inexistente
psql: error: FATAL: role "my_username" does not exist

Para verificar se o usuário existe, você pode utilizar o comando SQL \du no terminal interativo psql, que lista todos os usuários (também chamados de “roles” no PostgreSQL):

psql shell: consultando todos os usuários
postgres=# \du
                                List of roles
    Role name    |                         Attributes
-----------------+------------------------------------------------------------
 admin_pagila    | Create role
 ana             |
 app1_admin      | Create role, Create DB
 app1_user1      |
 app1_user2      |
 app2_admin      | Create role, Create DB
 app2_user1      |
 app2_user2      |
 dba             | Superuser
 fabio           |
 ludmila         |
 meu_usuario     | Superuser
 postgres        | Superuser, Create role, Create DB, Replication, Bypass RLS


Se o seu usuário estiver nessa lista, ele existe. Caso não esteja, você precisará criá-lo com o comando CREATE ROLE, que pode ser visto com detalhes no artigo Utilização de SQL básico:

psql shell: comando para criar um novo usuário, com permissão de login e definição de senha
CREATE ROLE <nome_do_usuário_ou_grupo> LOGIN PASSWORD '<senha>';

Não se esqueça de garantir as permissões necessárias para que esse usuário possa se conectar.

Eu tenho permissão para me conectar?

Mesmo se a configuração no pg_hba.conf e postgresql.conf estiver correta, o seu usuário existir e o banco de dados também, você ainda poderá encontrar outros problemas. É possível que o usuário não tenha privilégios suficientes para realizar a conexão ou para acessar objetos específicos dentro do banco. Se for o caso de não haver permissão para login, você deverá ver uma mensagem parecida com esta:

psql shell: mensagem de erro relacionada a falta de permissão de login
psql: error: connection to server on at 192.168.0.10 failed: FATAL:  role "fabio" is not permitted to log in


Isso pode ser facilmente resolvido concedendo esse privilégio com o comando:

ALTER ROLE <usuário ou grupo> WITH LOGIN;

Agora, se houver falta de permissão para se conectar com o banco, essa deverá ser a mensagem de erro visualizada:

psql shell: mensagem de erro relacionada a falta de permissão de conexão com o banco
psql: error: connection to server at 192.168.0.10, port 5432 failed: FATAL: permission denied for database "postgres"
DETAIL: User does not have CONNECT privilege.


Podemos resolver isso com o comando GRANT, que vimos detalhadamente no artigo O mínimo sobre segurança que você precisa saber. Em um resumo rápido, existe o privilégio CONNECT, que especificamente trata de permissão de conexão com o banco, que pode ser fornecido com o seguinte comando:

GRANT CONNECT ON DATABASE <nome do banco> TO <usuario>;

Isso e muito mais pode ser visto de forma detalhada no artigo citado.

A senha está correta?

Mesmo que o banco de dados e o usuário estejam configurados corretamente, uma senha incorreta pode ser um obstáculo. Se você suspeita que a senha do seu usuário está errada ou precisa ser redefinida, há algumas formas de corrigir isso. Este é o erro para esse caso:

psql shell: mensagem de erro para senha incorreta
psql: error: connection to server at "localhost" (::1), port 5432 failed: FATAL:  password authentication failed for user "user3"


No PostgreSQL, não há um comando direto para visualizar senhas, já que elas são armazenadas de forma segura. No entanto, se o arquivo pg_hba.conf estiver configurado para um método de autenticação que exija senha (como md5 ou scram-sha-256), a senha deve estar correta para que a conexão seja estabelecida.

Caso precise alterar a senha de um usuário, você pode fazê-lo através do psql, com um usuário com permissões de superusuário, executando o comando ALTER USER para realizar a alteração:

psql shell: comando para alterar a senha de um usuário
ALTER USER <nome_do_usuario> WITH PASSWORD '<nova_senha>';

Agora, a nova senha será usada nas próximas tentativas de conexão. Se o problema estava sendo causado por uma senha incorreta, ele será resolvido.

Conclusão

Quando você instala o PostgreSQL pela primeira vez em um servidor, é fundamental configurar o postgresql.conf e o pg_hba.conf corretamente, uma vez que a instalação padrão não vem configurada para permitir conexões remotas. Depois disso, você talvez precise criar novos usuários, bancos de dados, senhas etc. Por fim, a rede onde você roda o PostgreSQL deve permitir o acesso remoto ao servidor naquela porta. 

Além disso, muitas coisas podem dar errado nesse caminho. Não caia na tentação de burlar os mecanismos de segurança! Se você entender o significado de cada mensagem de erro que apresentamos aqui, rapidamente você conseguirá chegar lá. Mas lembre-se: sempre verifique o que a mensagem de erro diz, pois isso será fundamental para entender onde e como agir para resolver o problema. 

Compartilhe

Você pode gostar

pg_hba.conf

Introdução O arquivo pg_hba.conf (PostgreSQL Host-Based Authentication) é uma peça fundamental na configuração de segurança de qualquer instância PostgreSQL. Ele define as regras de autenticação

Tuning de SO (no Linux)

Introdução Tuning refere-se ao processo de ajustar e otimizar o desempenho de um sistema, software ou aplicação. A otimização do sistema operacional é uma etapa

Tipos de cargas dos bancos de dados

Introdução Cargas de dados referem-se aos diferentes tipos de operações e transações que um banco de dados deve processar. Essas cargas variam conforme o tipo

plugins premium WordPress