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 on “Como recuperar uma base de dados InnoDB e MyISAM (MySQL) corrompida

  1. isaias

    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

  2. admin Post author

    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”.

  3. Daniel

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

  4. admin Post author

    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.

  5. Alex

    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?

  6. admin Post author

    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.

  7. Everton

    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 !!

  8. admin Post author

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

  9. Assis

    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?

  10. admin Post author

    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.

  11. Assis

    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.

  12. wando

    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?

  13. wando

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

  14. Kico (Henrique Lobo Weissmann) Post author

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

  15. Kico (Henrique Lobo Weissmann) Post author

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

  16. Jeison

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

  17. Kico (Henrique Lobo Weissmann) Post author

    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.

  18. Pingback: Meus links diários 06/20/2013 | Guto Costa

  19. Daniel

    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

  20. Kico (Henrique Lobo Weissmann) Post author

    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. :)

  21. bruno

    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

  22. Kico (Henrique Lobo Weissmann) Post author

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

  23. TELIO

    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?

  24. Kico (Henrique Lobo Weissmann) Post author

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

  25. Giovani

    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!

  26. Hercules

    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.

  27. Luis Ferreira

    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

  28. Kico (Henrique Lobo Weissmann) Post author

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

  29. Luis Ferreira

    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

  30. Ricardo

    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.

  31. Paulo

    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?

  32. Kico (Henrique Lobo Weissmann) Post author

    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.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

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