- Castro/
- blog/
- MariaDB não reinicia e InnoDB acusa Unable to lock ibdata1: quando dois mysqld disputam o mesmo data directory/
MariaDB não reinicia e InnoDB acusa Unable to lock ibdata1: quando dois mysqld disputam o mesmo data directory
Como diagnosticar um MariaDB que não inicia porque outra instância mysqld já mantém o tablespace InnoDB e a porta do banco em uso.
O serviço MariaDB estava tentando iniciar, mas ficava preso em activating e repetia no log:
| |
Uma tentativa anterior terminava ainda mais explícita:
| |
O erro parecia apontar para arquivo, permissão ou corrupção.
Mas o dado decisivo veio de um comando muito mais simples:
| |
Havia dois processos mysqld ao mesmo tempo.
Um deles já estava atendendo na porta 3306; o processo iniciado pelo systemd era o segundo e não conseguia obter o lock do tablespace InnoDB.
O que o erro 11 estava dizendo #
No mesmo log aparecia:
| |
Isso é diferente de concluir automaticamente:
| |
ou:
| |
A mensagem do próprio InnoDB já sugeria verificar outro mysqld usando os mesmos arquivos.
A hipótese virou evidência quando a lista de processos mostrou duas instâncias reais.
O processo antigo ainda estava vivo #
A coleta sanitizada era conceitualmente assim:
| |
O processo A já existia.
O processo B tinha sido iniciado pelo serviço MariaDB e tentava abrir o mesmo ibdata1.
Para confirmar quem estava realmente atendendo a porta:
| |
A resposta apontava a porta 3306 para o processo antigo, não para a nova tentativa do systemd.
Isso fecha uma parte importante do diagnóstico:
| |
systemctl status sozinho podia induzir ao erro #
O serviço mostrava algo como:
| |
Se eu olhasse apenas essa tela, poderia interpretar que o banco inteiro estava simplesmente “travado na inicialização”.
Mas systemctl descrevia a instância que ele estava tentando gerenciar naquele momento.
Ele não eliminava a possibilidade de haver um processo antigo fora do estado esperado do serviço.
Por isso, em banco que não inicia, eu junto pelo menos:
| |
O PID file também entra na investigação #
Quando processo e systemd perderam sincronização, vale conferir PID files e diretórios de runtime:
| |
Depois comparar:
| |
O objetivo é entender o estado antes de apagar qualquer arquivo.
Remover PID file por reflexo não é diagnóstico.
Se o processo correspondente ainda existe, apagar o arquivo pode apenas esconder parte da inconsistência.
O que eu não faria primeiro #
Com Unable to lock ./ibdata1, eu evitaria começar por:
| |
Nada disso responde à primeira pergunta:
Existe outro processo usando esse arquivo?
E algumas dessas ações têm blast radius enorme.
O próprio log chega a alertar para não remover arquivos antigos que contenham dados.
Como provar quem mantém o arquivo aberto #
Além de ps, quando necessário:
| |
ou:
| |
Esses comandos ajudam a ligar diretamente:
| |
Para a porta:
| |
A combinação arquivo + processo + socket é muito mais forte do que inferir pelo erro isolado.
Uma observação importante sobre memória #
Na tentativa iniciada pelo serviço, o log também mostrava inicialização de um Buffer Pool grande.
Isso é um dado relevante para capacidade, mas não foi necessário para explicar o lock de ibdata1 nesta ocorrência.
O motivo comprovado do erro de abertura era a coexistência dos processos sobre o mesmo data directory.
Não vale transformar todo sinal preocupante do mesmo servidor na causa daquele sintoma específico.
Como eu conduziria a correção #
A correção precisa partir da pergunta:
| |
Antes de parar qualquer processo:
- identificar qual PID atende
3306; - verificar seu comando completo e data directory;
- conferir PID file;
- conferir conexões/aplicações dependentes;
- entender por que ele não está representado corretamente no estado do serviço;
- decidir qual processo precisa permanecer;
- parar a instância indevida de forma controlada;
- só então normalizar o gerenciamento via
systemd.
Em produção, kill -9 deveria ser último recurso, não etapa padrão.
Um mysqld ativo pode ter dirty pages, transações e escrita em andamento.
Validação depois da normalização #
Eu não consideraria resolvido apenas porque systemctl ficou verde.
Validaria pelo menos:
| |
E no banco:
| |
Quando houver acesso seguro:
| |
Depois, validar a aplicação que realmente depende do banco.
A pergunta posterior: como surgiram dois mysqld? #
Resolver a disputa não encerra a investigação.
Ainda é preciso descobrir como o processo antigo ficou vivo fora do estado esperado.
Possíveis linhas de investigação — não causas assumidas:
mysqld_safeiniciado manualmente;- script legado de inicialização;
- cron;
- serviço antigo convivendo com unit nova;
- processo órfão após uma tentativa operacional;
- automação externa iniciando banco diretamente.
Para isso eu procuraria:
| |
E scripts de init legados quando aplicável.
Por que retirei “Too many connections” do título #
A pauta original do catálogo citava:
Too many connections e MySQL que não reinicia…
Na fonte recuperada desta ocorrência, o que está comprovado é:
- duas instâncias
mysqld; - uma delas já atendendo a porta
3306; - a segunda tentando iniciar;
Unable to lock ./ibdata1 error: 11;- falha da inicialização InnoDB por não conseguir abrir o system tablespace.
A coleta recuperada não comprova Too many connections como parte desse mesmo incidente.
Então o título público foi reduzido ao que a evidência realmente sustenta.
Checklist #
| |
O principal aprendizado #
Unable to lock ./ibdata1 parece um erro de arquivo.
Neste caso, ele era principalmente um erro de estado operacional: dois mysqld disputavam o mesmo tablespace e só um deles podia possuí-lo.
Antes de mexer no banco em disco, vale responder uma pergunta simples:
quantos bancos estão realmente rodando neste host agora?
Me chama.
Manda o contexto, os sintomas e o que já foi testado. Bora organizar as evidências antes de sair mexendo.