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.
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 zumbi)
ss -ltnp | grep 5432
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 e ownership
ls -ld /var/run/postgresql /run/postgresql 2>/dev/null
id postgres
Aqui você confirma se o caminho existe e se dono/permissão estão compatíveis.
---
4) Correção: do hotfix à solução definitiva
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 ambiente com requisitos mais rígidos, valide se 0770 é possível conforme os consumidores legítimos do socket.
---
7) Pós-incidente (post-mortem operacional)
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.
- Validar restart e reboot controlado.
- Confirmar healthcheck:
sudo systemctl is-active postgresql
sudo -u postgres psql -c "select version();"
ss -lxnp | grep PGSQL
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.
---
Conclusão
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 post está licenciado sob CC BY-NC.
Comentários
Participe da discussão abaixo.
Comentários ainda não configurados. Adicione as opções do Cusdis em /assets/json/config/blog-comments-config.json.