PostgreSQL não inicia: could not create lock file "/var/run/postgresql/.s.PGSQL.5432.lock"#
Análise técnica profunda, RCA e correção definitiva para ambiente de produção.
Pré-requisitos#
Antes de executar as correções, valide se seu ambiente possui as seguintes ferramentas e permissões:
- Systemd: Versão 211+ (necessário para suporte à diretiva
RuntimeDirectory) - Verificar versão:
systemd --version | head -3 - Verificar suporte a override:
systemctl edit --help | head -5 - PostgreSQL: Qualquer versão ativa no Linux (ex: 12, 13, 14, 15, 16)
- Systemd Tmpfiles: Caso utilize a alternativa baseada em
tmpfiles.d - Verificar disponibilidade:
which systemd-tmpfiles - Acesso root/sudo: Privilégios elevados para interagir com o systemd, ler logs do kernel e gerenciar diretórios de sistema.
Esse é o tipo de incidente que parece simples, mas abre um buraco operacional se você corrigir só no improviso. A mensagem fala de "lock file", mas o problema real está no ciclo de vida de diretório volátil no Linux moderno e na forma como o serviço foi orquestrado.
1) Cenário do incidente#
Você tenta subir o serviço:
sudo systemctl start postgresql
# Job for postgresql.service failed because the control process exited with error code.
No systemctl status, muitas vezes a causa aparece superficial. O erro raiz normalmente surge no log da instância:
FATAL: could not create lock file "/var/run/postgresql/.s.PGSQL.5432.lock": No such file or directory
Quando isso acontece, o PostgreSQL não está "quebrado". Ele não consegue criar socket/lock porque o diretório pai esperado simplesmente não existe naquele boot.
2) RCA (root cause analysis): onde o ambiente falhou#
2.1 /var/run é volátil (tmpfs)#
Em várias distros, /var/run (ou symlink para /run) vive em memória. Reiniciou o host, o conteúdo evapora.
2.2 expectativa do binário#
O processo do Postgres espera que o diretório de runtime já exista para fazer bind do socket Unix e criar lock.
2.3 falha de orquestração#
Se a unit do systemd não declara corretamente o runtime dir (ou instalação manual deixou lacuna), ninguém recria /var/run/postgresql antes do serviço subir.
Resultado: falha consistente no start, especialmente após reboot.
3) Workflow profissional de troubleshooting#
Em incidente real, eu não fico preso na abstração do systemctl. Vou direto no binário para isolar o erro.
Passo 1 - bypass do systemd#
sudo -u postgres /usr/bin/postgres -D /var/lib/pgsql/data
Isso expõe erro de path/permissão sem ruído de orquestração.
Passo 2 - confirmar se 5432 está livre (ou processo concorrente/zumbi)#
# 1. Verificar se a porta TCP 5432 já está sendo ouvida
ss -ltnp | grep 5432
# 2. Listar todos os processos ativos do postgres para verificar concorrência
ps aux | grep postgres | grep -v grep
# 3. Identificar se existem múltiplas instâncias rodando no sistema
pg_lsclusters
# 4. Localizar eventuais processos zumbis do postgres no sistema
ps aux | awk '{if ($8=="Z") print}'
Se já tiver processo escutando, pode existir colisão de instância/serviço paralelo. Se não tiver nada, reforça o diagnóstico de diretório/sock.
Passo 3 - validar runtime dir, espaço em disco e ownership#
# 1. Verificar se o diretório do runtime existe e quais suas permissões
ls -ld /var/run/postgresql /run/postgresql 2>/dev/null
# 2. Verificar se o usuário postgres possui UID/GID válidos
id postgres
# 3. Verificar se há espaço livre na montagem volátil /run (tmpfs)
df -h /run
# 4. Auditar inodes disponíveis no sistema de arquivos temporário
df -i /run
# 5. Confirmar se o ponto de montagem /run está corretamente montado como tmpfs
mount | grep -w "/run"
Aqui você confirma se o caminho existe, se há recursos suficientes no tmpfs e se o dono/permissão estão compatíveis.
4) Correção: do hotfix à solução definitiva#
4.0 backup preventivo de configurações do systemd#
Antes de aplicar qualquer alteração nas configurações das units do orquestrador do sistema, faça um backup preventivo:
# 1. Criar um diretório seguro para o backup
sudo mkdir -p /root/systemd-backup-$(date +%Y%m%d)
# 2. Fazer backup da unit do serviço do PostgreSQL atual
sudo cp /lib/systemd/system/postgresql.service /root/systemd-backup-$(date +%Y%m%d)/
# Nota: Em alguns sistemas baseados em RHEL/CentOS, o caminho pode ser /usr/lib/systemd/system/postgresql.service
# 3. Verificar se já existem arquivos de override cadastrados
ls -la /etc/systemd/system/postgresql.service.d/ 2>/dev/null
4.1 hotfix imediato (volta serviço agora)#
sudo mkdir -p /var/run/postgresql
sudo chown postgres:postgres /var/run/postgresql
sudo chmod 775 /var/run/postgresql
sudo systemctl start postgresql
Isso resolve na hora, mas não é definitivo se você não tratar recriação automática no boot.
4.2 solução definitiva via systemd (reboot-safe)#
A correção madura é declarar runtime directory no serviço:
sudo systemctl edit postgresql
Conteúdo do override:
[Service]
RuntimeDirectory=postgresql
RuntimeDirectoryMode=0775
Aplicação:
sudo systemctl daemon-reload
sudo systemctl restart postgresql
Com isso, o systemd cria o diretório no ciclo correto, define modo e remove quando necessário, mantendo idempotência operacional.
5) Alternativa complementar: tmpfiles.d#
Em alguns cenários (customizações de distro/packaging), também pode ser útil declarar no tmpfiles:
# /etc/tmpfiles.d/postgresql.conf
d /var/run/postgresql 0775 postgres postgres -
Aplicar sem reboot:
sudo systemd-tmpfiles --create /etc/tmpfiles.d/postgresql.conf
Essa abordagem garante criação precoce no boot via systemd-tmpfiles.
6) Segurança prática: por que 775 e nunca 777#
Permissão errada em socket path é vetor local de abuso.
0775(drwxrwxr-x) mantém escrita no dono/grupo e leitura controlada.0777abre superfície para usuários locais não confiáveis, inclusive tentativa de interferência em IPC/socket.
Para validar de forma consistente as permissões de acesso ao arquivo de socket ativo:
# 1. Listar permissões detalhadas do arquivo de socket e do diretório pai
ls -la /var/run/postgresql/
# 2. Testar se o usuário postgres tem permissão de leitura e escrita no diretório
sudo -u postgres test -r /var/run/postgresql/ && echo "Postgres pode ler"
sudo -u postgres test -w /var/run/postgresql/ && echo "Postgres pode escrever"
# 3. Verificar se há processos que mantêm arquivos de lock ou sockets abertos no diretório
sudo lsof +D /var/run/postgresql/
# Ou apontando diretamente ao socket
sudo lsof /var/run/postgresql/.s.PGSQL.5432 2>/dev/null
Para ambientes com requisitos mais rígidos, valide se 0770 é possível conforme os consumidores legítimos do socket.
7) Pós-incidente e logs de verificação#
Checklist que uso para fechar o RCA com evidência:
- Capturar log de falha com timestamp.
- Registrar estado de
/runantes/depois da correção. - Registrar override de unit aplicado.
- Inspecionar logs de depuração pós-fix:
# Acompanhar os logs dinâmicos do PostgreSQL
sudo tail -n 50 /var/log/postgresql/postgresql-*.log
# Consultar logs da unit no systemd desde os últimos 10 minutos
sudo journalctl -u postgresql --since "10 min ago"
# Filtrar logs de erro ou permissão negada no systemd
sudo journalctl -u postgresql | grep -iE "permission|denied|error|fatal" | tail -n 20
- Confirmar healthcheck e persistência pós-reboot (reboot controlado):
# Verificar se o serviço está ativo (deve retornar 'active')
sudo systemctl is-active postgresql
# Verificar se o diretório de runtime foi recriado pelo systemd
ls -ld /var/run/postgresql
# Confirmar que o arquivo de socket Unix foi criado com sucesso
ls -la /var/run/postgresql/.s.PGSQL.5432*
# Testar a conexão local de loopback via socket
sudo -u postgres psql -c "SELECT version();"
# Confirmar se está ouvindo na porta TCP correta
ss -ltnp | grep 5432
Sem validação pós-reboot, o incidente não está encerrado.
8) Lições aprendidas de infraestrutura#
- Log interno do serviço > mensagem genérica do orquestrador.
- Idempotência é critério de qualidade operacional. Se só funciona após comando manual, ainda está quebrado.
- Infra resiliente se reconstrói sozinha. Runtime dir temporário precisa estar no desenho do serviço.
- Varredura de outros serviços voláteis: Audite se outros daemons rodando na máquina compartilham da mesma fragilidade de dependência de
/var/runsem declaração explícita no systemd:
# Listar serviços que utilizam a diretiva RuntimeDirectory
grep -r "RuntimeDirectory" /usr/lib/systemd/system/*.service 2>/dev/null | head -15
# Verificar unidades de serviço em estado de falha (failed) no sistema
systemctl list-units --state=failed
Checklist de recuperação: erro de lock file do PostgreSQL#
Use esta lista operacional para mitigar o problema e garantir a integridade da pilha:
- [ ] Diagnóstico: Executou bypass do systemd e coletou logs de erros em
/var/log/postgresql/. - [ ] Porta/Processos: Validou se a porta 5432 está livre e filtrou processos zumbis/concorrentes.
- [ ] Recursos: Checou espaço livre e inodes no ponto de montagem
/run(tmpfs). - [ ] Backups: Efetuou backup preventivo das units originais em
/root/systemd-backup-$(date +%Y%m%d). - [ ] Correção Provisória: Criou manualmente a pasta, alterou dono (
postgres:postgres) e permissões (775). - [ ] Correção Definitiva: Criou override systemd (
RuntimeDirectory) e recarregou daemons. - [ ] Logs pós-fix: Auditou erros ou logs de permissões negadas via
journalctl. - [ ] Segurança de Socket: Validou permissões seguras do socket (
0775) e acessibilidade do usuário postgres. - [ ] Varredura de Sistema: Pesquisou outros serviços vulneráveis a reboots e diretórios voláteis
/var/run. - [ ] Homologação Pós-Reboot: Reiniciou o host físico/VM para certificar a recriação do diretório e healthcheck estável.
Considerações práticas#
Resolver esse erro não é "criar uma pasta". É alinhar o PostgreSQL ao modelo de runtime volátil do Linux com orquestração correta no systemd.
Quando você fecha a causa-raiz com RuntimeDirectory (ou tmpfiles onde fizer sentido), para de apagar incêndio e passa a operar banco de forma previsível em produção.
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários