2013-11-13 14:52:59 +0000 2013-11-13 14:52:59 +0000
33
33

MySQL InnoDB perdeu tabelas mas existem ficheiros

Tenho um MySQL InnoDB que tem todos os ficheiros da tabela da base de dados, mas o MySQL não os vê, e não os está a carregar.

O problema aconteceu porque eu apaguei estes três ficheiros: ibdata1, ib_logfile0 e ib_logfile1 0x6&

porque estava a ter problemas com o arranque do mysql, e o que li foi para os remover porque o MySQL irá apenas regenerá-los (sei que deveria tê-los apoiado mas não o fiz).

O que posso fazer para que o MySQL volte a ver as tabelas?

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

Respostas (3)

36
36
36
2013-11-14 15:34:22 +0000

Eis porque é que o MySQL não consegue ver esses ficheiros: O espaço de tabelas do sistema (ibdata1) tem um dicionário de dados específico do Storage-Engine que permite ao InnoDB mapear a utilização potencial da tabela:

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

Mover tabelas InnoDB de um local para outro requer comandos como

ALTER TABLE mydb.tags DISCARD TABLESPACE;

Aqui está uma parte da Documentação MySQL 5.5 explicando o que precisa de ser considerado

Considerações de portabilidade para ficheiros .ibd

Não pode mover livremente ficheiros .ibd entre directórios de bases de dados como pode com os ficheiros de tabelas MyISAM. A definição da tabela armazenada no espaço de tabelas partilhadas InnoDB inclui o nome da base de dados. Os IDs de transacção e números de sequência de registo armazenados nos ficheiros do tablespace também diferem entre as bases de dados.

& > Para mover um ficheiro .ibd e a tabela associada de uma base de dados para outra, utilize uma declaração RENAME TABLE:

& > TABELA RENAME db1.tbl_name TO db2.tbl_name; Se tiver uma cópia de segurança “limpa” de um ficheiro .ibd, pode restaurá-lo à instalação MySQL a partir da qual se originou, como se segue:

& > A tabela não deve ter sido largada ou truncada desde que copiou o ficheiro .ibd, porque ao fazê-lo altera o ID da tabela armazenada dentro do espaço de tabelas.

& > Emitir esta declaração de TABELA ALTERA para apagar o ficheiro .ibd actual:

& > ALTER TABLE tbl\_name DISCARD TABLESPACE; Copiar o ficheiro .ibd de salvaguarda para o directório apropriado da base de dados.

& > Emitir esta declaração de TABELA ALTERA para dizer à InnoDB que utilize o novo ficheiro .ibd para a tabela:

& > ALTER TABLE tbl_name IMPORT TABLESPACE; Neste contexto, uma cópia de segurança “limpa” do ficheiro .ibd é uma cópia de segurança para a qual os seguintes requisitos são satisfeitos:

& > Não há modificações não comprometidas por transacções no ficheiro .ibd.

& > Não há entradas tampão de inserção não autorizadas no ficheiro .ibd.

& > A purga removeu todos os registos de índice com a marca de eliminação do ficheiro .ibd.

& > mysqld apagou todas as páginas modificadas do ficheiro .ibd do buffer pool para o ficheiro.

Dadas estas advertências e protocolos, aqui está uma linha de acção sugerida

Para este exemplo, vamos tentar restaurar a tabela tags à base de dados mydb

PASSO #1

Certifique-se de que tem cópias de segurança desses ficheiros .frm e .ibd em /tmp/innodb_data

PASSO #2

PASSO #2 CREATE TABLE tags e execute a declaração CREATE TABLE mydb.tags ... como tags.frm. Certifique-se de que é exactamente a mesma estrutura que a original tags.ibd

PASSO #3

Apagar o vazio tags.ibd usando MySQL

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

PASSO #4

Trazer a cópia de segurança de tags

ALTER TABLE mydb.tags IMPORT TABLESPACE;

PASSO #5

Adicionar Apr 23, 2012 tabela ao Dicionário de Dados InnoDB

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

PASSO 6

Testar a acessibilidade da tabela

Se obtiver resultados normais, parabéns pela sua importação de uma tabela InnoDB.

PASSO 7

No futuro, por favor não elimine ibdata1 e os seus logs

Experimente!!

Discuti coisas como esta antes de

CAVEAT

E se não souber a estrutura da tabela CREATE TABLE ?

Existem ferramentas para obter a declaração da tabela CREATE TABLE utilizando apenas o ficheiro 0x6&. Escrevi também um post sobre isto : Como pode extrair o esquema da tabela apenas do ficheiro .frm? . Nesse post, copiei um ficheiro .frm para uma máquina Windows a partir de uma caixa Linux, executei a ferramenta Windows e obtive a declaração 0x6&.

10
10
10
2014-01-28 02:08:22 +0000

Tenho a mesma situação, Não posso deixar cair ou criar um nome específico para a culpa. O meu procedimento de reparação é:

  1. parar o MySQL.

  2. Remover ib_logfile0 e ib_logfile1.

  3. Remover os ficheiros tblname. AVISO: ESTE DELETERÁ PERMANENTE OS SEUS DADOS

  4. Inicie o MySQL.

2
2
2
2019-03-27 11:19:13 +0000

Eu também tinha este problema. Apaguei ibdata1 acidentalmente e todos os meus dados foram perdidos.

Após 1-2 dias de pesquisa no google e SO, finalmente encontrei uma solução que salvou a minha vida (tinha tantas bases de dados e tabelas com registos enormes).

  1. fazer uma cópia de segurança de /var/lib/mysql

  2. recuperar esquema de tabela de .frm arquivo 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. criar nova tabela (com novo nome) com esquema exportado.

  2. descartar novos dados da tabela com este comando:

ALTER TABLE `tbl-new` DISCARD TABLESPACE;
  1. copiar os dados da tabela antiga e colá-los em vez de novos e definir a permissão correcta para os mesmos.
cp tbl.ibd tbl@002dnew.ibd && chown mysql:mysql tbl@002dnew.ibd
  1. importar dados para a nova tabela.
ALTER TABLE `tbl-new` IMPORT TABLESPACE;
  1. tudo bem! temos dados na nova tabela e podemos deixar cair a antiga.
DROP TABLE `tbl`;
  1. verificar /var/lib/mysql/database-name e se houver dados (.ibd ficheiro) para a tabela antiga, apagá-los.
rm tbl.ibd
  1. e finalmente renomear a nova tabela para nome original
ALTER TABLE `tbl-new` RENAME `tbl`;