Como recuperar uma base de dados InnoDB e MyISAM (MySQL) corrompida

Eu sei: não é nosso trabalho cuidar da manutenção de servidores de bancos de dados. Mas quando você não possui uma equipe competente para tal, esta “responsabilidade” acaba caindo sobre você.

Pois bem: vejam o que aconteceu comigo na semana passada. Esperando o final do dia, no qual o número de conexões ao MySQL é normalmente quase zero, resolvi criar um índice para uma tabela gigantesca de logs (14 Gb). Enquanto o índice era criado, alguns usuários reclamaram ao administrador de rede que o acesso às aplicações estava lento. Solução encontrada pelo administrador? Desligar o servidor do MySQL físicamente! (detalhe: quando ele desligou o servidor, a criação do índice ainda estava em execução!)

Obviamente, a tabela em questão foi perdida e, pior ainda: o servidor do MySQL simplesmente não pode mais ser iniciado. Por que? Por que as tabelas presentes no banco de dados, assim como os logs de transação e diversas outras informações fundamentais para a execução do banco de dados foram corrompidos. Acabei adotando o problema (sei que é loucura, mas era a solução) e, após algumas horas de pesquisa (e a empresa de 600 funcionários parada), encontrei uma solução tosca, mas que pode salvar uma base de dados MySQL corrompida.

No caso, a tabela na qual eu estava criando o índice era do tipo MyISAM, porém, como houve um desligamento incorreto do servidor, diversos outros arquivos foram corrompidos para o processo, incluindo as tabelas no formato InnoDB.

A solução adotada neste procedimento resolve o problema para arquivos no formato MyISAM e InnoDB apenas. Convém mencionar também que a versão usada do MySQL foi a 5.0. O procedimento de recuperação é composto por três passos:

1. Execute o programa myisamchk dentro do diretório que contém a estrutura de bancos de dados do MySQL. Se não souber aonde este diretório se encontra, abra o seu arquivo my.ini (Windows) oy my.cnf (Linux e Unix em geral) e localize a instrução datadir.

Dentro deste diretório, execute o comando

myisamchk --force --verbose */*.MYI

O atributo –force obriga o aplicativo a reparar qualquer tipo de erros encontrados na estrutura da tabela, enquanto o –verbose simplesmente irá expor na tela o status da execução do aplicativo.

Só para lembrar, este aplicativo serve para reparar as suas tabelas do tipo MyISAM.

2. Inicie o servidor do mysql com o atributo –innodb_force_recovery=[algum valor]

Você deverá iniciar o seu servidor MySQL com o atributo –innodb_force_recovery com um valor de 1 a 6, sendo que quanto maior o valor, maior o nível de corrupção da sua base de dados. Se o valor estiver entre 1 e 4, o MySQL irá reparar todos os erros das suas tabelas e em seguida você poderá trabalhar na base de dados normalmente. Caso contrário, todas as bases de dados estarão disponíveis apenas para leitura. Execute o servidor passando este parâmetro até que este volte a ser inicializado.

(aviso aos orelhas: se o seu servidor voltou a executar com o valor 2 ou 3, não é preciso executar o servidor com valores maiores)

Exemplo de execução:

mysqld --innodb_force_recovery=4

Se quiser, pode também incluir este atributo no arquivo de configuração do MySQL (my.ini no Windows, my.cnf no Linux/Unix/etc). Para tal, basta incluir a instrução innodb_force_recovery=valor logo após a seção mysqld deste arquivo, tal como no exemplo abaixo:


[mysqld]
innodb_force_recovery=4

3. Faça backup da sua base de dados e, em seguida, faça o restore da mesma em uma nova instalação do MySQL.

Este terceiro passo pode parecer exagerado se você executou o comando innodb_force_recovery com valores menores ou iguais a 4, porém, como seguro morreu de velho, esta alternativa garante que na nova base de dados não haja informações corrompidas.

37 Comments

Add Yours →

Muito bom… parabens pelo texto.

Parabens pela atitude de resolver o problema. A empresa precisa estar preparada e sempre atenta para este tipo de situação.

Só uma ressalva sobre o caso:

Não deves punir SEVERAMENTE o “administrador da rede” pelo ocorrido, poderá estar punindo um profissional com futuro promissor. Ninguem nasce sabendo e não jogue a responsabilidade que é sua para outra pessoa, tome a atitude mais ética e responsável possível.

Quem sabe isso não serviu de lição para que tua estrutura esteja melhor preparada e prevenida contra falhas humanas (que podem acontecer até por erros do melhor profissional do mercado, que quem sabe é você mesmo).

Trate de deixá-lo ciente da responsabilidade do seu ato, mas NUNCA trate-o de forma mal educada. A responsabilidade é sua (ou de quem seja o responsável pelo sistema, quem recebe por isso) e pelo que vi tu soube lidar bem com a situação cujo post estou guardando para uma possível necessidade (apesar de eu não utilizar MySQL).

Grande abraço e obrigado por compartilhar o caso e a solução prática. Assim quem lê tanbém aprende com a tragédia.

Isaías

Responda

admin Reply:

Olá Isaías,

claro que ninguém foi punido severamente! Estas coisas acontecem e, sabe de uma coisa? No final das contas, é ótimo, porque assim ficam expostas as falhas dentro da equipe.

Eu realmente acredito no que Nietzsche dizia: “o que não nos mata nos fortalece”.

Responda

Muito bom artigo, tanto da parte técnica quando da parte ética com os profissionais envolvidos!

Responda

Posso executar todos esses comandos via FTP?

Responda

admin Reply:

Via FTP eu acho meio difícil, porque por FTP você só vai poder enviar ou apagar arquivos no servidor.

No entanto, via terminal remoto da pra fazer isto como se fosse local.

Qualquer coisa estou a sua disposição.

Responda

Meu provlema é o seguinte: Eu tinha o WAMP instalado no pc ( partição C:), como estou fazendo faculdade de sistemas de informação tinha um trabalho no qual deveria ser instalado o phptriad e o apache separadamente, para não mexer nas tabelas que tinha no wamp eu usei o dual boot que já existia no pc e instalei o phptrid em outra versão do xp (partição D:) mas por padrão o phptriad extrai os arquivos diretamente no C:. Aí começa o problema, entrei novamente no xp instalado no C: mas não consegui mais acessar as tabelas mysql, tento abrir mas me retorna um erro 10061. Tem como recuperar isso?

Responda

admin Reply:

Uai Alex, neste caso tudo o que você precisa fazer consiste em alterar a sua configuração do MySQL para que acesse os dados presentes no outro diretório.

Responda

Mysql e Oracle são duas bostas. Na moral.

Responda

Ricardo Reply:

Não sei quanto ao Oracle. Mas também acho o MySQL uma BOSTA graúda. Tenho bancos de dados Firebird com mais de 1 milhão e meio de registros ativos por mais de 10 anos (fora os imensos arquivos-mortos) e nunca tive uma só tabela corrompida. Sem contar que você pode simplesmente copiar o Banco Firebird e colar aonde quiser e colocar ativo sem qualquer aporrinhação. MySQL fica devendo e muito na rapidez de se fazer uma manutenção é péssimo. Pode defender quem quiser, quem defende só conhece essa merda mesmo. Quero tentar o PostGresql para ver a diferença, mas muitas serviços de Web e Internet ficam devendo pela manutenção do Banco, precário mesmo.

Responda

Valeu, funcionou comigo aqui.
Eu tentei:
myisamchk –force –verbose */*.MYI
apareceu o erro:
‘myisamchk: error: File ‘*/*.MYI’ doesn’t exist’

Então como eu já sabia a tabela que tava com problema, coloquei.
myisamchk –force –verbose tabela_do_banco.MYI
Funcionou!!

Valeu mesmo !!

Responda

admin Reply:

Ótimo! Fico feliz que tenha te ajudado.
Precisando de qualquer coisa, to ai!

Responda

O HD do meu servidor estragou e corrompeu a maioria das tabelas.
Nesse caso essas opções não foram suficientes para resgatar os dados.

Como utilizo um arquivo InnoDB por tabela, tenho algumas tabelas intactas. Gostaria de resgatar os dados e a estrutura dessas tabelas.
As tabelas MyIsam eu instalei um novo MySQL e copiei os arquivos para a pasta de dados e consegui recuperar os dados e a estrutura, porem nas tabelas InnoDB não sei como resgatar essas informações.
Alguem sabe como resgatar essas informações?

Responda

admin Reply:

Há algo que você pode fazer, mas é bastante arriscado.

Crie um novo banco de dados

Copie os arquivos .myi destas tabelas, assim como os de indice (.idx se não me engano) para o diretório que o MySQL vai criar para este banco de dados (com o serviço do MySQL parado)

Reinicie o servidor e tente acessá-las, depois me conte o resultado ok?

O problema é você saber quais tabelas estão ou não corrompidas.

Responda

Assis Reply:

Brigadão pela dica.
Listou as tabelas, porem não consegui acessar os dados das tabelas InnoDB.
As tabelas MyIsam que fiz isso funcionaram.
Quando o HD estragou o unico arquivo que perdi foi o ibdata1 que é onde ficam todos os dados de todas as tabelas innoDB, porem como utilizo arquivos separados por tabela, acredito que tenha como resgatar esses dados, só não sei como.

Responda

E quando seu site está hospedade em um servidor pago, que não é o servidor da empresa. Como posso recuperar a tabela se não tenho status de adm do servidor. E pior preciso que estes seja recuperados com urgencia?

Responda

Kico (Henrique Lobo Weissmann) Reply:

Neste caso você fica na mão do serviço de hospedagem

Responda

E qdo o servidor é pago e não tenho status de administrador, como posso recuperar as tabelas?

Responda

Kico (Henrique Lobo Weissmann) Reply:

Neste caso você vai ter de contar com a boa intenção dos administradores do serviço que está assinando.

Responda

o meu não está encontrando o comando myisamchk o que posso fazer?

Responda

Kico (Henrique Lobo Weissmann) Reply:

Provávelmente não está instalado em seu sistema. Sugiro que você baixe uma vesão do MySQL que já venha compilada para poder executar este comando.

Responda

Bom dia Kico,

Estou precisando de uma força,

Eu tinha um wampserver instalado bonitinho no C: ai fiz um crtl+c da pasta todo para o D: , ai mandei o formate na maquina so que agora nao funciona mais a meu servidor.

Já instalei dez bilhoes de vezes e nada de funcionar.

Se poder me ajudar fico muito grato

Responda

Kico (Henrique Lobo Weissmann) Reply:

Oi Daniel,

não sei se o que vou te dizer vai ajudar, mas vai lá.
Existe uma opção no MySQL de fazer backup do tipo bruto, ou seja, ao invés de gerar um arquivo de backup que é um script SQL, você simplesmente copia mesmo a base de dados de um diretório do servidor antigo para o novo.

Não sei se vai te ajudar no seu caso, mas pelo menos te serve como guia pra alguma coisa. :)

Responda

E agora, mudei o ibdata1 de lugar pois tinha 73 GIGA e o mysql nao abria, apos ele criar um novo ibdata1 nao encontrei mais as emsmas tabelas

Responda

Kico (Henrique Lobo Weissmann) Reply:

Teria de ter mais detalhes sobre o seu caso Bruno. Assim de antemão não sei te responder.

Responda

Estou com esse problema, o computador do cliente desligou inesperadamente, e todos os arquivos de formato ibd eu perdi, agora não estou conseguindo saber como recupera-lo. Tentei o comando como vc pediu porem ocorreu um erro 22 when open myisan-table ‘*.*.ibd’ e se tento recuperar a propria tabela esta dando que ela nao existe porque de fato nao existe ela em formato ibd. Alguem tem uma ideia?

Responda

Kico (Henrique Lobo Weissmann) Reply:

Arquivos IBD não são MyISAM, mas InnoDB, por isto não funciona.

Responda

Muito bom o artigo, parabéns! Estamos pela primeira vez mesclando os dois tipos de tabela em minha empresa e já deixei salvo aqui essa dica, caso precise algum dia!

Responda

Olá!

Eu já havia instalado o wamp com os dbs, porém me enganei e instalei novamente.
resumindo:
Tenho os “frm” e “ibd” porém os ibdata1, ib_logfile0 e ib_logfile1 são o da nova instalação.
Tem como recuperar meus dados?

Obrigado.

Responda

Kico (Henrique Lobo Weissmann) Reply:

Neste caso, não sei.

Responda

Boas,
Fiz um BD Mysql em um servidor Raspberry com PHP ( LAMP) e por algum motivo nao consegui mais acessar.
A instalacao estava em um cartao SD , ai fiz um backup do cartao todo para nao mexer no original.
Consegui resgatar as paginas mas agora nao sei como proceder para resgatar o Banco.
Tenho Linux instalado no laprtop e gostaria de mandar o Banco primeiro para o laptop para depois mandar para o novo servidor que instalei .

Voce poderia me ajudar neste caso.
Grato,
Luis Ferreira

Responda

Kico (Henrique Lobo Weissmann) Reply:

Oi Luiz, não sei como te ajudar neste caso.
Apenas relatei uma experiẽncia que tive anos atrás neste post.

Responda

Criei um arquivo para fazer backup do Banco de Dados Mysql e pelo que me parece ele nao executou do jeito que pensei.
Gostaria que ele fizesse as 01:15 da manha de sabado e nao funcionou.
Vc poderia me ajudar ?
Grato.

crontab
‪#‎faz‬ backup automatico do banco de dados mysql apto
15 01 * * 6 /bin/sh /home/backup/bkp_apto.sh

cat bkp_apto.sh
#!/bin/sh
# bkp_apto.sh

# DATA vai imprimir a data no estio dia-mes-ano
DATA=`/bin/date +%d-%m-%Y`

# NOME armazena o nome do arquivo de backup e
# o diretorio onde o arquivo será salvo no meu caso
# /www/virtual/backup é uma pasta publica do apache,
# coloque o diretório onde quer guardar o backup.

NOME=”/home/backup/apto-$DATA.sql”

# variaveis do MySQL
HOST=”localhost”
USER=”mane”
PASSWORD=”mane1234″
DATABASE=”apto”

mysqldump -h $HOST -u $USER -p$PASSWORD $DATABASE > $NOME

Responda

Boa tarde, tenho um servidor na Amazon e parece que corrompeu a parte de bancos de dados do mysql.
Na parte de data do mysql, tenho apenas o ibdata1, acho que é nele que contém os dados do banco.

Como você acha que a gente consegue recuperar os dados?

Responda

Kico (Henrique Lobo Weissmann) Reply:

Oi Paulo, não sei. Este caso que relatei muitos anos atrás é muito específico, e não conheço a fundo os formatos dos arquivos do MySQL para poder te ajudar nesta.

Responda

Deixe um comentário

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.