↓Pular para o conteúdo principal
  1. blog/
ARTIGO TÉCNICO

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:

1
2
3
InnoDB: Unable to lock ./ibdata1 error: 11
InnoDB: Check that you do not already have another mysqld process
using the same InnoDB data or log files.

Uma tentativa anterior terminava ainda mais explícita:

1
2
3
4
InnoDB: Cannot open datafile './ibdata1'
InnoDB: Could not open or create the system tablespace
Plugin 'InnoDB' registration as a STORAGE ENGINE failed
Unknown/unsupported storage engine: InnoDB

O erro parecia apontar para arquivo, permissão ou corrupção.

Mas o dado decisivo veio de um comando muito mais simples:

1
ps aux | egrep 'mariadbd|mysqld'

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:

1
2
Operating system error number 11 in a file operation
Error number 11 means 'Resource temporarily unavailable'

Isso é diferente de concluir automaticamente:

1
ibdata1 corrompido

ou:

1
permissão errada

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:

1
2
3
root   ... mysqld_safe --datadir=/var/lib/mysql ...
mysql  A   /usr/sbin/mysqld --datadir=/var/lib/mysql ... --port=3306
mysql  B   /usr/sbin/mysqld --basedir=/usr

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:

1
ss -lntp | grep 3306

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:

1
2
3
4
5
6
7
8
mysqld antigo
  ├── mantém os arquivos InnoDB
  └── escuta 3306

systemctl start mariadb
  └── cria segundo mysqld
       └── tenta abrir o mesmo ibdata1
            └── error 11 / lock negado

systemctl status sozinho podia induzir ao erro #

O serviço mostrava algo como:

1
2
Active: activating (start)
Main PID: <novo mysqld>

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:

1
2
3
4
systemctl status mariadb -l --no-pager
journalctl -u mariadb -n 100 --no-pager
ps auxww | egrep '[m]ariadbd|[m]ysqld'
ss -lntp | grep 3306

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:

1
2
3
ls -l /var/lib/mysql/*.pid \
      /run/mariadb/*.pid \
      /var/run/mariadb/*.pid 2>/dev/null

Depois comparar:

1
2
3
4
PID no arquivo
PID que escuta 3306
PID conhecido pelo systemd
PIDs presentes no ps

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:

1
2
3
4
5
6
chown recursivo em /var/lib/mysql
chmod amplo
remover ibdata1
recriar tablespace
restaurar backup
reboot

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:

1
lsof /var/lib/mysql/ibdata1

ou:

1
fuser -v /var/lib/mysql/ibdata1

Esses comandos ajudam a ligar diretamente:

1
2
3
arquivo
→ PID
→ processo

Para a porta:

1
ss -lntp | grep ':3306'

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:

1
qual das duas instâncias é a legítima?

Antes de parar qualquer processo:

  1. identificar qual PID atende 3306;
  2. verificar seu comando completo e data directory;
  3. conferir PID file;
  4. conferir conexões/aplicações dependentes;
  5. entender por que ele não está representado corretamente no estado do serviço;
  6. decidir qual processo precisa permanecer;
  7. parar a instância indevida de forma controlada;
  8. 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:

1
2
3
systemctl is-active mariadb
ps auxww | egrep '[m]ariadbd|[m]ysqld'
ss -lntp | grep ':3306'

E no banco:

1
mysqladmin ping

Quando houver acesso seguro:

1
2
3
SELECT 1;
SHOW GLOBAL STATUS LIKE 'Uptime';
SHOW GLOBAL STATUS LIKE 'Threads_connected';

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_safe iniciado 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:

1
2
3
4
5
6
systemctl cat mariadb
systemctl list-unit-files | grep -Ei 'mysql|maria'
ps -fp <PID>
cat /proc/<PID>/cmdline | tr '\0' ' '
crontab -l
sudo crontab -l

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 #

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
[ ] systemctl status completo
[ ] journal da unit
[ ] listar todos mysqld/mariadbd
[ ] identificar quem escuta 3306
[ ] conferir data directory de cada processo
[ ] conferir PID files
[ ] usar lsof/fuser no ibdata1 se necessário
[ ] não apagar ibdata1/PID file por reflexo
[ ] definir qual processo é legítimo
[ ] parar a instância indevida de forma controlada
[ ] normalizar systemd
[ ] mysqladmin ping / SELECT 1
[ ] validar aplicação
[ ] investigar a origem do processo duplicado

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?

TEM UM CENÁRIO PARECIDO?

Me chama.

Manda o contexto, os sintomas e o que já foi testado. Bora organizar as evidências antes de sair mexendo.

Falar com Castro →
Sem enrolação. Com evidência.