Erro MySQL: O Servidor Encerrou Sem Atualizar o Arquivo PID — Guia Completo de Diagnóstico e Correção
O erro "The server quit without updating PID file" significa que o MySQL foi encerrado antes de conseguir escrever o seu identificador de processo no ficheiro `.pid` configurado — uma paragem forçada que impede o daemon de aceitar ligações. Esta falha é quase sempre um sintoma de um problema mais profundo: uma configuração incorreta em `my.cnf`, uma incompatibilidade de permissões no diretório de dados, uma partição de disco cheia, corrupção ao nível das tabelas, ou um conflito de porta com uma segunda instância MySQL ou MariaDB.
Este guia percorre todas as causas raiz confirmadas, fornece comandos shell exatos para diagnosticar e reparar cada uma delas, e aborda casos especiais que os tutoriais genéricos habitualmente ignoram.
O Que o Ficheiro PID Realmente Faz e Por Que a Sua Ausência É Importante
O MySQL escreve o seu identificador de processo (PID) num pequeno ficheiro de texto simples — tipicamente `/var/run/mysqld/mysqld.pid` — imediatamente após a inicialização do daemon. Os sistemas init, gestores de serviços (systemd, SysVinit) e ferramentas de monitorização leem este ficheiro para enviar sinais ao processo correto. Se o MySQL falhar, sair de forma anormal ou encontrar um erro fatal durante o arranque, nunca chega ao ponto de escrever esse ficheiro. O gestor de serviços reporta então a mensagem "quit without updating PID file".
Compreender esta sequência é fundamental: o erro do ficheiro PID é uma *consequência*, não a causa raiz. Perseguir o próprio ficheiro PID sem ler primeiro o registo de erros é o erro mais comum que os administradores cometem.
Causas Raiz Comuns em Resumo
| Causa Raiz | Sintoma Típico no Registo de Erros | Sistemas Afetados |
|---|---|---|
| — | — | — |
| Caminho `pid-file` incorreto em `my.cnf` | `Can't start server: can't create PID file` | Todas as distribuições |
| Propriedade incorreta em `/var/run/mysqld` | `Permission denied` no diretório PID | Debian/Ubuntu após atualizações |
| Disco cheio ou esgotamento de inodes | `No space left on device` | Qualquer servidor com `/var` pequeno |
| `ibdata1` ou registos redo InnoDB corrompidos | `InnoDB: Corruption detected` | MySQL 5.7, 8.0, MariaDB |
| Ficheiro `.pid` obsoleto de uma falha anterior | `A mysqld process already exists` | Qualquer sistema após reinício forçado |
| Porta 3306 já em uso | `Can't start server: Bind on TCP/IP port` | Configurações com múltiplas instâncias |
| Negação de política AppArmor ou SELinux | `apparmor="DENIED"` no syslog | Ubuntu, RHEL/CentOS |
| `datadir` incompatível após atualização de pacote | `[ERROR] Fatal error: Can't open and lock privilege tables` | Atualizações de versão principal |
Passo 1 — Leia Primeiro o Registo de Erros do MySQL
Todos os outros passos dependem do que o registo de erros indica. Não ignore este passo.
“`bash
Debian/Ubuntu default path
sudo tail -100 /var/log/mysql/error.log
RHEL/CentOS/AlmaLinux default path
sudo tail -100 /var/log/mysqld.log
If you are unsure of the path, query the running config
mysqld –verbose –help 2>/dev/null | grep "log-error"
“`
Procure linhas contendo `[ERROR]`, `[FATAL]`, `Aborting` ou `InnoDB`. A primeira entrada `[ERROR]` na sequência de arranque é quase sempre a verdadeira causa.
Passo 2 — Verificar e Corrigir o Diretório do Ficheiro PID
O diretório PID é frequentemente recriado como propriedade de `root` após um reinício do sistema porque `/var/run` é uma montagem `tmpfs` nas distribuições Linux modernas. Esta é uma das causas mais frequentemente ignoradas no Ubuntu 20.04+ e Debian 11+.
“`bash
Check current ownership
ls -ld /var/run/mysqld
Recreate the directory with correct ownership
sudo mkdir -p /var/run/mysqld
sudo chown mysql:mysql /var/run/mysqld
sudo chmod 755 /var/run/mysqld
“`
Para tornar isto persistente entre reinícios em sistemas systemd, crie uma regra `tmpfiles.d`:
“`bash
echo "d /var/run/mysqld 0755 mysql mysql -" | sudo tee /etc/tmpfiles.d/mysqld.conf
“`
Confirme que o caminho PID configurado em `my.cnf` corresponde ao diretório que acabou de criar:
“`bash
sudo grep -i "pid" /etc/mysql/my.cnf /etc/mysql/mysql.conf.d/*.cnf 2>/dev/null
“`
Passo 3 — Auditar a Propriedade e Permissões do Diretório de Dados
O diretório de dados do MySQL deve ser totalmente propriedade do utilizador de sistema `mysql`. Atualizações de pacotes, cópias manuais de ficheiros ou restaurações a partir de cópias de segurança frequentemente quebram isto.
“`bash
Correct ownership recursively
sudo chown -R mysql:mysql /var/lib/mysql
Correct permissions — directories 750, files 640 is more secure than 755/644
sudo find /var/lib/mysql -type d -exec chmod 750 {} ;
sudo find /var/lib/mysql -type f -exec chmod 640 {} ;
“`
Caso especial importante: Se restaurou uma cópia de segurança usando `rsync` ou `cp` como `root`, o ficheiro de socket `/var/lib/mysql/mysql.sock` também pode ser propriedade de root. Remova-o — o MySQL irá recriá-lo no arranque:
“`bash
sudo rm -f /var/lib/mysql/mysql.sock
sudo rm -f /var/run/mysqld/mysqld.sock
“`
Passo 4 — Verificar Espaço em Disco e Disponibilidade de Inodes
Um disco cheio impede silenciosamente o MySQL de escrever qualquer ficheiro, incluindo o ficheiro PID e os registos binários.
“`bash
Check disk space
df -h
Check inode usage — often overlooked
df -i
Find the largest directories consuming space
sudo du -sh /var/lib/mysql/* | sort -rh | head -20
“`
Se a partição estiver cheia, os culpados habituais são os registos binários (`mysql-bin.000*`), registos de consultas gerais deixados ativados acidentalmente, ou ficheiros de core dump. Para purgar com segurança registos binários antigos a partir do MySQL:
“`bash
mysql -u root -p -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);"
“`
Passo 5 — Eliminar Ficheiros PID Obsoletos e Processos em Conflito
Após um kernel panic, perda de energia ou `kill -9`, um ficheiro PID obsoleto pode permanecer no disco. O MySQL recusa-se a iniciar se encontrar um.
“`bash
Check for a stale PID file
cat /var/run/mysqld/mysqld.pid
Verify whether that PID is actually running
ps aux | grep mysqld
If the process is not running but the file exists, remove it
sudo rm -f /var/run/mysqld/mysqld.pid
“`
Se outra instância MySQL ou MariaDB estiver genuinamente em execução e a ocupar a porta 3306:
“`bash
sudo ss -tlnp | grep 3306
sudo systemctl stop mariadb
sudo systemctl stop mysql
sudo killall -9 mysqld mysqld_safe
“`
Aguarde três segundos após terminar os processos antes de tentar um reinício, para permitir que os estados TIME_WAIT do socket do kernel sejam limpos.
Passo 6 — Verificar Políticas AppArmor e SELinux
Esta causa quase nunca é mencionada em tutoriais básicos, mas é responsável por uma percentagem significativa de erros de ficheiro PID em sistemas Ubuntu e da família RHEL.
Ubuntu / AppArmor:
“`bash
sudo dmesg | grep -i apparmor | grep -i mysql
sudo grep -i "DENIED" /var/log/syslog | grep mysql
“`
Se o AppArmor estiver a bloquear o MySQL, atualize o perfil ou defina-o temporariamente para modo de reclamação para diagnóstico:
“`bash
sudo aa-complain /usr/sbin/mysqld
“`
RHEL / CentOS / AlmaLinux — SELinux:
“`bash
sudo ausearch -c 'mysqld' –raw | audit2why
sudo sealert -a /var/log/audit/audit.log | grep mysqld
“`
Uma correção comum para problemas de contexto SELinux após mover o diretório de dados:
“`bash
sudo semanage fcontext -a -t mysqld_db_t "/new/datadir(/.*)?"
sudo restorecon -Rv /new/datadir
“`
Passo 7 — Diagnosticar e Reparar Corrupção InnoDB
Se o registo de erros contiver mensagens como `InnoDB: Corruption detected`, `[ERROR] InnoDB: Unable to lock ./ibdata1`, ou referências a inconsistências nos registos redo, o próprio tablespace InnoDB está danificado.
Para tabelas MyISAM, use `mysqlcheck`:
“`bash
sudo mysqlcheck –all-databases –repair –user=root –password
“`
Para corrupção InnoDB, `mysqlcheck` é insuficiente. A abordagem correta é ativar o modo de recuperação forçada InnoDB em `my.cnf`:
“`ini
[mysqld]
innodb_force_recovery = 1
“`
Inicie o MySQL com esta configuração, faça imediatamente um dump de todas as bases de dados e depois reconstrua:
“`bash
mysqldump –all-databases –single-transaction -u root -p > full_backup.sql
“`
Incremente `innodb_force_recovery` de 1 para 6 apenas se os valores mais baixos não conseguirem iniciar o servidor. No nível 4 e acima, é possível perda de dados — trate a instância como somente leitura e exporte imediatamente.
Após um dump bem-sucedido:
“`bash
sudo systemctl stop mysql
sudo rm -rf /var/lib/mysql/ib_logfile* # Remove corrupt redo logs
Remove innodb_force_recovery from my.cnf
sudo systemctl start mysql
mysql -u root -p < full_backup.sql
“`
Passo 8 — Isolar Erros de Configuração em my.cnf
Um único erro de digitação ou uma diretiva inválida em `my.cnf` irá abortar o arranque antes de o ficheiro PID ser escrito. O MySQL 8.0+ é mais rigoroso em relação a opções desconhecidas do que o 5.7.
“`bash
Validate configuration without starting the server
mysqld –validate-config
Or test with verbose output
mysqld –verbose –help > /dev/null
“`
Faça uma cópia de segurança e reduza a configuração para os valores predefinidos:
“`bash
sudo cp /etc/mysql/my.cnf /etc/mysql/my.cnf.bak.$(date +%F)
“`
As diretivas problemáticas mais comuns após atualizações de versão principal incluem opções obsoletas como `query_cache_size`, `query_cache_type`, `innodb_file_format` e `innodb_large_prefix` — todas removidas no MySQL 8.0.
Passo 9 — Reiniciar o MySQL e Validar
“`bash
sudo systemctl restart mysql
Check service status
sudo systemctl status mysql
Confirm the PID file was written
cat /var/run/mysqld/mysqld.pid
Confirm MySQL is accepting connections
mysqladmin -u root -p status
“`
Passo 10 — Reinstalar o MySQL (Último Recurso com Preservação de Dados)
A reinstalação só deve acontecer após esgotar todos os passos de diagnóstico acima. Antes de prosseguir, faça uma cópia de segurança de todos os dados:
“`bash
If MySQL can start in recovery mode, dump first
mysqldump –all-databases -u root -p > /backup/full_$(date +%F).sql
Copy raw data directory as a secondary backup
sudo rsync -av /var/lib/mysql/ /backup/mysql_datadir_$(date +%F)/
“`
Em seguida, remova e reinstale:
“`bash
sudo systemctl stop mysql
sudo apt-get remove –purge mysql-server mysql-client mysql-common
sudo apt-get autoremove && sudo apt-get autoclean
sudo rm -rf /var/lib/mysql /etc/mysql
sudo apt-get install mysql-server
sudo mysql_secure_installation
“`
Restaure a partir do dump:
“`bash
mysql -u root -p < /backup/full_$(date +%F).sql
“`
Escolher o Ambiente de Alojamento Certo para Prevenir Recorrências
Muitas destas falhas — esgotamento de disco, reposição de permissões após reinícios, contenção de recursos de serviços co-alojados — são problemas de infraestrutura tanto quanto problemas do MySQL. Executar uma base de dados de produção num servidor devidamente provisionado com recursos dedicados elimina categorias inteiras destes erros.
Se estiver a gerir uma aplicação suportada por MySQL, um ambiente de VPS Hosting dá-lhe acesso root completo, recursos isolados e a capacidade de configurar `tmpfiles.d`, perfis AppArmor e substituições de unidades systemd sem restrições. Para bases de dados de alto tráfego que requerem IOPS e RAM garantidos, os Servidores Dedicados eliminam completamente todas as preocupações de partilha de recursos.
Para equipas que preferem um painel de controlo gerido em vez de administração direta por CLI, o VPS com cPanel fornece interfaces de gestão MySQL juntamente com acesso ao nível do servidor. Se a sua stack também requer configuração de domínio e DNS, o Registo de Domínios e os Certificados SSL podem ser geridos pelo mesmo fornecedor, reduzindo a sobrecarga operacional.
Matriz de Decisão: Qual Correção Aplicar Primeiro
| Sintoma no Registo de Erros | Primeira Ação | Tempo Estimado de Resolução |
|---|---|---|
| — | — | — |
| `Permission denied` no diretório PID ou de dados | Corrigir propriedade com `chown mysql:mysql` | 2 minutos |
| `No space left on device` | Purgar registos binários, expandir disco | 5–30 minutos |
| `A mysqld process already exists` | Remover ficheiro PID obsoleto, terminar processo órfão | 2 minutos |
| `Bind on TCP/IP port: Address already in use` | Parar instância em conflito, verificar `ss -tlnp` | 5 minutos |
| `InnoDB: Corruption detected` | Ativar `innodb_force_recovery`, fazer dump, reconstruir | 30 minutos a várias horas |
| `apparmor="DENIED"` no syslog | Atualizar perfil AppArmor ou definir modo de reclamação | 10 minutos |
| `unknown variable` no registo | Executar `mysqld –validate-config`, corrigir `my.cnf` | 5 minutos |
| Sem erro específico, tudo o resto falhou | Reinstalar MySQL, restaurar a partir de cópia de segurança | 1–2 horas |
Lista de Verificação de Pontos-Chave Técnicos
- Leia sempre `/var/log/mysql/error.log` ou `/var/log/mysqld.log` antes de tocar em qualquer ficheiro — a primeira linha `[ERROR]` identifica a causa real.
- Em sistemas systemd com `tmpfs` em `/var/run`, crie uma regra `/etc/tmpfiles.d/mysqld.conf` persistente para evitar reposições de permissões em cada reinício.
- Após qualquer `rsync` ou restauração manual de cópia de segurança, execute `chown -R mysql:mysql /var/lib/mysql` antes de tentar iniciar o MySQL.
- Verifique `df -i` (utilização de inodes) juntamente com `df -h` (espaço em disco) — uma tabela de inodes cheia produz sintomas idênticos a um disco cheio.
- Para corrupção InnoDB, use `innodb_force_recovery` incrementalmente a partir de 1 para cima; nunca salte diretamente para o nível 6.
- Valide a sintaxe de `my.cnf` com `mysqld –validate-config` antes de reiniciar — isto deteta erros de digitação sem uma tentativa de arranque falhada.
- Remova as diretivas obsoletas do MySQL 5.7 (`query_cache_*`, `innodb_file_format`) antes de atualizar para o MySQL 8.0.
- No Ubuntu, verifique as negações AppArmor em `/var/log/syslog`; no RHEL/AlmaLinux, verifique o SELinux com `ausearch -c mysqld`.
Perguntas Frequentes
Qual é a forma mais rápida de descobrir por que o MySQL falhou ao iniciar?
Execute `sudo tail -50 /var/log/mysql/error.log` e procure a primeira linha contendo `[ERROR]` ou `[FATAL]`. Essa única linha identifica a causa raiz na grande maioria dos casos e determina qual correção aplicar.
Por que o diretório PID perde as suas permissões após um reinício?
Nas distribuições Linux que usam `tmpfs` para `/var/run` (o que inclui Ubuntu 18.04+ e Debian 10+), toda a árvore `/var/run` é reconstruída em memória no arranque. Qualquer diretório não definido em `/etc/tmpfiles.d/` é recriado como `root:root`. A correção é adicionar uma regra `tmpfiles.d`: `echo "d /var/run/mysqld 0755 mysql mysql -" | sudo tee /etc/tmpfiles.d/mysqld.conf`.
Posso recuperar dados se o MySQL não iniciar de todo devido a corrupção InnoDB?
Sim, na maioria dos casos. Defina `innodb_force_recovery = 1` em `my.cnf`, inicie o MySQL e execute imediatamente `mysqldump –all-databases`. Se o nível 1 não iniciar o servidor, incremente para 2, depois 3, e assim por diante. Nos níveis 4–6, alguns dados podem ser irrecuperáveis, mas a maioria das tabelas está tipicamente intacta.
Como posso evitar que "no space left on device" volte a derrubar o MySQL?
Ative a expiração de registos binários: defina `binlog_expire_logs_seconds = 604800` (7 dias) em `my.cnf`. Adicionalmente, desative o registo de consultas gerais em produção (`general_log = 0`) e configure um alerta de utilização de disco a 80% de capacidade através do seu sistema de monitorização.
Este erro ocorre também no MariaDB e a correção é a mesma?
Sim. O MariaDB usa o mesmo mecanismo de ficheiro PID e a mesma estrutura de diretório de dados que o MySQL. Todos os passos de diagnóstico neste guia aplicam-se diretamente ao MariaDB, com a única diferença de que o nome do serviço é `mariadb` em vez de `mysql` nos comandos `systemctl`, e o registo de erros pode estar localizado em `/var/log/mariadb/mariadb.log` dependendo da distribuição.
