Como recuperar uma tabela do InnoDB cujos arquivos foram movidos

13

Então, eu tenho um servidor de banco de dados de teste que foi configurado em um fluxo de replicação. Por cima do nome, veio uma otimização que rapidamente preencheu o espaço no datadir dos escravos. O Mysql obedientemente estava apenas esperando por mais espaço.

Este datadir é um sistema de arquivos usado SOMENTE como o datadir do mysql, portanto não havia mais nada para liberar.

Eu tinha uma tabela de teste de innodb de 4 GB que não fazia parte do fluxo de replicação, então imaginei que tentaria algo para ver se funcionaria e, sendo um ambiente de teste, não estava muito preocupado se as coisas saíssem horrivelmente erradas.

Aqui estão os passos que tomei

  1. Lavou a mesa que eu estava prestes a me mudar
  2. Colocou um bloqueio de leitura nele (mesmo que nada estivesse gravando nele e não estivesse no fluxo de replicação)
  3. Copiou o .frm e o .ibd para um sistema de arquivos com algum espaço livre
  4. Destrancou a mesa
  5. Truncou a tabela - isso liberou espaço suficiente para a otimização terminar, e a replicação começou a funcionar novamente.
  6. Parar slaving / shutdown mysql
  7. Copie o arquivo de tmp de volta para o diretório de dados
  8. Reinicie o mysql

Nada aparece no log .err, as coisas parecem boas. Eu conecto e uso mydb; e veja a tabela com a qual eu estava mexendo nas tabelas do show. Mas se eu tentar

select * from testtable limit 10;

Eu recebo o erro

ERROR 1146 (42S02): Table 'mydb.testtable' doesn't exist

Pelo que sei até agora, posso ler todas as outras tabelas e a replicação foi iniciada sem queixas.

Existe algo que eu possa fazer para me recuperar desse ponto? Posso reconstruí-lo do zero, se necessário, mas fiquei curioso com o que os outros pensavam sobre esse empreendimento em geral. Houve algo sobre a série de etapas que eu tomei que acabaria com mais resultados impecáveis?

E se este não fosse um servidor de teste, eu não poderia simplesmente 'fazer isso ao vivo' e ver o que acontece? Qual seria a melhor maneira de liberar espaço temporariamente em um escravo de produção se eu tivesse que gostar disso?

atxdba
fonte

Respostas:

15

A maior coisa que a maioria das pessoas esquece sobre TRUNCATE TABLE é que TRUNCATE TABLE é DDL e não DML . No InnoDB, os metadados no ibdata1 contêm uma lista numerada de tabelas do InnoDB. O uso de TRUNCATE TABLE faz com que o ID de metadados interno da tabela InnoDB se desloque. Isso acontece porque TRUNCATE TABLE efetivamente faz o seguinte:

Exemplo: Para truncar uma tabela do InnoDB chamada mydb.mytb

USE mydb
CREATE TABLE newtb LIKE mytb;
ALTER TABLE mytb RENAME oldtb;
ALTER TABLE newtb RENAME mytb;
DROP TABLE oldtb;

O novo mytb teria, assim, um ID de metadados interno diferente.

Quando você copiou o arquivo .ibd para outro local, o .ibd contém nele o ID de metadados interno original. Simplesmente colocar o arquivo .ibd de volta não causa uma reconciliação do ID de metadados interno com o do ibdata1.

O que você deveria ter feito é o seguinte:

Copie o arquivo .ibd da tabela InnoDB. Então, execute isso

ALTER TABLE tablename DISCARD TABLESPACE;

Para trazê-lo de volta mais tarde, copie o arquivo .ibd de volta para o datadir e execute

ALTER TABLE tablename IMPORT TABLESPACE;

Isso teria preservado o ID de metadados interno.

Verifique se .frm está sempre presente.

Certa vez, ajudei um cliente a restaurar 30 tabelas do InnoDB que ele utilizou da mesma maneira. Eu tive que usar outro servidor de banco de dados e jogar alguns jogos adicionando e descartando tabelas do InnoDB para procurar o ID correto de metadados internos.

O cliente encontrou este artigo: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Nós o usamos e isso ajudou bastante. Espero que ajude você.

RolandoMySQLDBA
fonte
1
Eu tenho 2 bancos de dados onde todas as tabelas dizem Table 'X' doesn't exist in engine. Preciso fazer o método acima para todas as tabelas ou existem maneiras melhores de corrigir isso?
papanito 20/01
-2

Eu experimentei com o meu Mac, antes de vender para um amigo, basta copiar a pasta XAMPP apenas para o meu disco rígido. (NÃO É SUCESSO) Infelizmente, isso estava causando problemas para mim, porque tentei as seguintes etapas: - Instalei o XAMPP novo e copio todo o \{docs e var \ mysql no meu novo Mac, aqueles db apenas com .frm e .ibd, NÃO FUNCIONA, ainda não consigo acessar as tabelas dentro do PHPMyAdmin ... - Tentei instalar a mesma versão do xampp e repita as etapas acima, ainda NÃO FUNCIONANDO. - Decidiu ir para a cama.

(SUCESSO) - Hoje de manhã, trouxe meu disco de backup e tente com o Windows 7. - Instale o XAMPP para Windows mais recente, c: \ xampp - Eu tenho um site (pasta) do meu backup \{docs e a pasta do banco de dados correspondente dentro \ var \ mysql está PRONTO no windows 7, eu só quero tentar com um site e depois tentar o resto, porque tenho muitos projetos dentro de activationdocs \ e \ var \ mysql - copio a menção activationdocs \ para o Windows c: \ xampp \ httdocs e copie o \ var \ mysql para c: \ xampp \ mysql \ data

Ainda não copiei o ib_logfile0, ib_logfile1, ibdata1 do meu arquivo de backup para o Windows xampp c: \ xampp \ mysql \ data

Eu atualizo o http: // localhost / mywebsite

WOW WOW FEITO ... está funcionando ...

Armindo
fonte