Soltei acidentalmente um banco de dados MySQL no meu servidor. Existem maneiras de recuperar um banco de dados descartado?
Soltei acidentalmente um banco de dados MySQL no meu servidor. Existem maneiras de recuperar um banco de dados descartado?
Respostas:
Se você agir rápido, há uma grande chance de recuperar seu banco de dados. A chance é maior para o InnoDB, para o MyISAM é diferente de zero, mas próximo.
O problema é quando o MySQL executa DROP TABLE ou DROP DATABASE (que é essencialmente o mesmo) O InnoDB não apaga os dados. As páginas com os dados ainda estão no disco.
Dependendo da configuração innodb_file_per_table, o processo de recuperação é diferente. Se innodb_file_per_table estiver desativado (padrão até 5.5), a tabela descartada permanecerá em ibdata1. Se innodb_file_per_table estiver LIGADO (padrão a partir de 5.5), a tabela descartada estava no respectivo arquivo .ibd. O MySQL remove esse arquivo quando solta a tabela.
A primeira coisa a fazer é interromper qualquer possível gravação para que sua tabela não seja substituída. Se innodb_file_per_table estiver desativado, basta parar o MySQL (kill -9 é ainda melhor, mas certifique-se de matar o safe_mysqld primeiro). Se innodb_file_per_table estiver ativado, desmonte uma partição onde o MySQL armazena seus dados. Se o datadir estiver na partição raiz, recomendo desligar o servidor ou, pelo menos, tirar uma imagem do disco. Deixe-me repetir, o objetivo é evitar a substituição da tabela descartada pelo MySQL ou pelo sistema operacional.
Existe uma ferramenta que permite trabalhar com páginas do InnoDB em baixo nível, kit de ferramentas de recuperação de dados TwinDB . Vou usá-lo para ilustrar a recuperação de recuperação.
Você precisa levar a mídia com a tabela descartada (ibdata1 ou imagem de disco) e encontrar as páginas do InnoDB nela. A ferramenta stream_parser do kit de ferramentas faz isso.
./stream_parser -f /path/to/disk/image
Ele examinará o arquivo, encontrará as páginas do InnoDB e as classificará por tipo e index_id. index_id é um identificador que o InnoDB usa para se referir a um índice. Uma tabela é armazenada no índice PRIMARY. Para encontrar qual index_id é sua tabela eliminada, você precisa recuperar o dicionário InnoDB .
O dicionário InnoDB é armazenado no arquivo ibdat1. Você precisa digitalizar o arquivo ibdata1 da mesma maneira que acima:
./stream_parser -f /var/lib/mysql/ibdata1
Agora você precisa obter registros das tabelas de dicionário do InnoDB SYS_TABLES e SYS_INDEXES (digamos que sua tabela seja sakila.actor):
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql | grep sakila/actor
000000000B28 2A000001430D4D SYS_TABLES "sakila/actor" 158 4 1 0 0 "" 0
158 é table_id, lembre-se.
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql | grep 158
000000000B28 2A000001430BCA SYS_INDEXES 158 376 "PRIMARY" 1 3 0 4294967295
000000000B28 2A000001430C3C SYS_INDEXES 158 377 "idx\_actor\_last\_name" 1 0 0 4294967295
Portanto, index_id da sua tabela descartada (sakila.actor) é 376.
Agora você pode buscar registros da tabela eliminada no InnoDB index_id 376. Você precisa ter a estrutura da tabela eliminada, exatamente a instrução CREATE TABLE com a qual a tabela foi criada. Onde você pode conseguir isso? Do backup antigo ou de outro lugar. Também é possível recuperar a estrutura do dicionário InnoDB, mas não a abordarei nesta resposta. Vamos apenas assumir que você o possui.
./c_parser -6f pages-ibdata1/FIL_PAGE_INDEX/0000000000000376.page -t actor.sql > dump.tsv 2> load_cmd.sql
c_parser gera registros como despejo separado por tabulação para stdout. O dump pode ser carregado com o comando LOAD DATA. c_parser imprime no stderr.
Veja mais detalhes nas postagens:
Não há maneira fácil de quebrar isso para você. Não importa se você eliminou um banco de dados via phpmyadmin ou pela linha de comando. Já se foi.
O erro humano é um dos motivos para ter um bom regime de backup.
Eu não sou religioso, mas vou fazer uma oração esperando que não seja nada muito importante.
Depende da sua configuração. É possível restaurar se você configurar seu sistema corretamente. Se você tiver um backup, poderá restaurá-lo. e aplique os logs binários até o ponto imediatamente antes de você soltar a tabela.
http://dev.mysql.com/doc/refman/5.5/en/mysqlbinlog.html
Eu sugiro que você faça isso em outro servidor, depois de restaurar a tabela, você poderá usar o mysqldump para extraí-lo e importá-lo novamente para o servidor de produção. Isso não será uma restauração rápida, mas você pode recuperar os dados.
Se você não sabe o que está fazendo, sugiro abrir um contrato de suporte com uma das empresas de consultoria mysql (pythian, percona, palamino são provavelmente as melhores) e pedir que elas o ajudem com isso.
te desejo muita sorte