MySQL InnoDB perdeu tabelas mas existem arquivos


33

Eu tenho um MySQL InnoDB que possui todos os arquivos de tabela do banco de dados, mas o MySQL não os vê e não os carrega.

O problema aconteceu porque eu apaguei esses três arquivos: ibdata1, ib_logfile0eib_logfile1

porque eu estava tendo problemas com o mysql inicializando, e o que li foi para removê-los porque o MySQL apenas os regenerará (eu sei que eu deveria ter feito o backup deles, mas não o fiz).

O que posso fazer para que o MySQL veja as tabelas novamente?

about_member.frm                              site_stories.frm
about_member.ibd                              site_stories.ibd
db.opt                                        stories.frm
FTS_00000000000000bb_BEING_DELETED_CACHE.ibd  stories.ibd
FTS_00000000000000bb_BEING_DELETED.ibd        story_comments.frm
FTS_00000000000000bb_CONFIG.ibd               story_comments.ibd
FTS_00000000000000bb_DELETED_CACHE.ibd        story_likes.frm
FTS_00000000000000bb_DELETED.ibd              story_likes.ibd
FTS_00000000000000f5_BEING_DELETED_CACHE.ibd  story_tags.frm
FTS_00000000000000f5_BEING_DELETED.ibd        story_tags.ibd
FTS_00000000000000f5_CONFIG.ibd               story_views.frm
FTS_00000000000000f5_DELETED_CACHE.ibd        story_views.ibd
FTS_00000000000000f5_DELETED.ibd              story_view_totals.frm
member_favorites.frm                          story_view_totals.ibd
member_favorites.ibd                          tags.frm
members.frm                                   tags.ibd
members.ibd

Você tentou restaurar esses arquivos? Os arquivos de log podem permanecer excluídos. Você realmente não deveria ter excluído ibdata1
— Ramhound 13/11

Copiei o arquivo de uma versão antiga do mysql onde o arquivo estava localizado, mas as tabelas não aparecem.
— Get Off My Lawn

Respostas:


36

Aqui está o porquê o MySQL não pode ver esses arquivos: O espaço de tabela do sistema (ibdata1) possui um dicionário de dados específico do Storage-Engine que permite ao InnoDB mapear o uso potencial da tabela:

Arquitetura InnoDB

Mover tabelas do InnoDB de um lugar para outro requer comandos como

ALTER TABLE tblname DISCARD TABLESPACE;
ALTER TABLE tblname IMPORT TABLESPACE;

Aqui está uma parte da documentação do MySQL 5.5, explicando o que precisa ser considerado

Considerações sobre portabilidade para arquivos .ibd

Você não pode mover livremente os arquivos .ibd entre os diretórios do banco de dados, como é possível com os arquivos de tabela MyISAM. A definição de tabela armazenada no espaço de tabela compartilhado do InnoDB inclui o nome do banco de dados. Os IDs da transação e os números de sequência do log armazenados nos arquivos do espaço de tabela também diferem entre os bancos de dados.

Para mover um arquivo .ibd e a tabela associada de um banco de dados para outro, use uma instrução RENAME TABLE:

TABELA DE RENOMEAÇÃO db1.tbl_name TO db2.tbl_name; Se você tiver um backup "limpo" de um arquivo .ibd, poderá restaurá-lo para a instalação do MySQL da qual se originou da seguinte maneira:

A tabela não deve ter sido descartada ou truncada desde que você copiou o arquivo .ibd, pois isso altera o ID da tabela armazenada dentro do espaço de tabela.

Emita esta instrução ALTER TABLE para excluir o arquivo .ibd atual:

ALTER TABLE nome_tabela DISCARD TABLESPACE; Copie o arquivo .ibd de backup no diretório de banco de dados apropriado.

Emita esta instrução ALTER TABLE para informar ao InnoDB para usar o novo arquivo .ibd da tabela:

ALTER TABLE nome_tabela IMPORT TABLESPACE; Nesse contexto, um backup de arquivo .ibd “limpo” é aquele para o qual os seguintes requisitos são atendidos:

Não há modificações não confirmadas por transações no arquivo .ibd.

Não há entradas de buffer de inserção não imersas no arquivo .ibd.

A remoção removeu todos os registros de índice marcados com exclusão do arquivo .ibd.

O mysqld liberou todas as páginas modificadas do arquivo .ibd do buffer pool para o arquivo.

Dadas essas advertências e protocolos, aqui está um curso de ação sugerido

Neste exemplo, vamos tentar restaurar a tagstabela no mydbbanco de dados

PASSO 1

Verifique se você tem backups daqueles .frme .ibdarquivos/tmp/innodb_data

PASSO 2

Obtenha a CREATE TABLE tagsinstrução e execute-a como CREATE TABLE mydb.tags .... Verifique se é exatamente a mesma estrutura que o originaltags.frm

ETAPA 3

Exclua o vazio tags.ibdusando o MySQL

ALTER TABLE mydb.tags DISCARD TABLESPACE;

PASSO 4

Traga a cópia de backup de tags.ibd

cd /var/lib/mysql/mydb
cp /tmp/innodb_data.tags.ibd .
chown mysql:mysql tags.ibd

PASSO # 5

Adicionar tagstabela ao dicionário de dados do InnoDB

ALTER TABLE mydb.tags IMPORT TABLESPACE;

PASSO 6

Teste a acessibilidade da tabela

SHOW CREATE TABLE mydb.tags\G
SELECT * FROM mydb.tags LIMIT 10;

Se você obtiver resultados normais, parabéns por importar uma tabela do InnoDB.

PASSO 7

No futuro, não exclua ibdata1 e seus logs

De uma chance !!!

Eu já discuti coisas assim antes

EMBARGO

E se você não conhece a estrutura da tabela do tags?

Existem ferramentas para obter a instrução CREATE TABLE apenas usando o .frmarquivo Também escrevi um post sobre isso: como extrair o esquema da tabela apenas do arquivo .frm? . Nesse post, copiei um arquivo .frm para uma máquina Windows a partir de uma caixa Linux, executei a ferramenta Windows e obtive a CREATE TABLEdeclaração.


Obrigado pela incrível resposta! Ainda estou importando uma tabela, porque continuo criando problemas, mas chegarei lá eventualmente e informarei como funciona! Obrigado!
— Get Off My Lawn

1
Quando executo a criação, recebo: ERRO 1813 (HY000): espaço de tabela para tabela ' weblyize. tags' existe. DESCARTE o espaço de tabela antes de IMPORTAR. Então, tento executar o alter tablespace primeiro e recebo este erro: ERRO 1146 (42S02): A tabela 'weblyize.tags' não existe . O que eu posso fazer?
— Get Off My Lawn

Obrigado! Para corrigir meu erro, criei um novo banco de dados, executei CREATE TABLE ...e siga suas etapas! Você me salvou de ter que reescrevê-los 100% do zero! Não importou chaves estrangeiras, mas tudo bem, eu mesmo posso fazer isso! Mais uma vez obrigado!
— Get Off My Lawn

E se eu tiver 100 tabelas que devem ser corrigidas dessa maneira. Não farei operações para cada mesa manualmente. Como poderia ser automatizado?
— Oleg Abrazhaev 29/11

10

Eu tenho a mesma situação, não é possível soltar ou criar tblname específico. Meu procedimento de correção é:

  1. Pare o MySQL.

    service mysql stop
    
  2. Remova ib_logfile0 e ib_logfile1.

    cd /var/lib/mysql;
    rm ib_logfile0 ib_logfile1
    
  3. Remova os arquivos tblname. AVISO: ESTE DECLARARÁ SEMPRE SEUS DADOS

    cd /var/lib/mysql/dbname;
    rm tblname*
    
  4. Inicie o MySQL.

    service mysql start
    

1
Obrigado, isso resolveu meu problema, não fiz a etapa 3, simplesmente removi os arquivos de log e iniciei o backup do mysql.
— Jeff Wilbert

Você é absolutamente fantástico! Resolvido meu problema.
— Alex GP #

2

Eu tive esse problema também. Apaguei ibdata1acidentalmente e todos os meus dados foram perdidos.

Após uma pesquisa de um dia no google e no SO, finalmente encontrei uma solução que salvou minha vida (eu tinha tantos bancos de dados e tabelas com registros enormes).

  1. faça um backup de /var/lib/mysql

  2. recuperar esquema da tabela do .frmarquivo com dbsake (havia outra opção! mysqlfrm . mas não funcionou para mim)

dbsake frmdump --type-codes /var/lib/mysql/database-name/tbl.frm
  1. crie nova tabela (com novo nome) com esquema exportado.

  2. descarte novos dados da tabela com este comando:

ALTER TABLE `tbl-new` DISCARD TABLESPACE;
  1. copie os dados da tabela antiga e cole-os em vez de novos e defina a permissão correta.
cp tbl.ibd tbl@002dnew.ibd && chown mysql:mysql tbl@002dnew.ibd
  1. importar dados para nova tabela.
ALTER TABLE `tbl-new` IMPORT TABLESPACE;
  1. bem! temos dados na nova tabela e podemos abandonar a antiga.
DROP TABLE `tbl`;
  1. verifique /var/lib/mysql/database-namee, se houver dados ( .ibdarquivo) para a tabela antiga, exclua-a.
rm tbl.ibd
  1. e finalmente renomeie a nova tabela para o nome original
ALTER TABLE `tbl-new` RENAME `tbl`;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.