web-dev-qa-db-fra.com

Comment récupérer une table InnoDB dont les fichiers ont été déplacés

J'ai donc un serveur de base de données de test qui a été configuré sur un flux de réplication. Sur le nom, une optimisation est apparue qui a rapidement rempli l'espace sur le datadir des esclaves. Mysql attendait consciencieusement un peu plus d'espace.

Ce datadir est un système de fichiers utilisé UNIQUEMENT comme datadir de mysql donc il n'y avait rien d'autre à libérer.

J'avais une table de test innodb de 4 gig qui ne faisait pas partie du flux de réplication alors j'ai pensé que j'essaierais quelque chose pour voir si cela fonctionnerait, et étant un environnement de test, je n'étais pas trop inquiet si les choses allaient terriblement mal.

Voici les étapes que j'ai prises

  1. Rincé la table que j'allais bouger
  2. Placé un verrou de lecture dessus (même si rien n'y était écrit et qu'il n'était pas dans le flux de réplication)
  3. Copié le .frm et le .ibd sur un système de fichiers avec une pièce de rechange
  4. Déverrouillé la table
  5. La table a été tronquée - cela a libéré suffisamment d'espace pour que l'optimisation se termine et que la réplication recommence à avancer.
  6. Arrêter l'asservissement/l'arrêt de mysql
  7. Copiez le fichier hors de tmp dans le répertoire de données
  8. Redémarrez mysql

Rien n'apparaît dans le journal .err, les choses semblent bonnes. Je me connecte et utilise mydb; et voir la table avec laquelle je jouais dans les tables d'exposition. Mais si j'essaye

select * from testtable limit 10;

Je reçois l'erreur

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

D'après ce que je peux dire jusqu'à présent, je peux lire à partir de toutes les autres tables très bien et la réplication a commencé sans aucune plainte.

Puis-je faire quelque chose pour récupérer à partir de ce point? Je peux le reconstruire à partir de zéro si nécessaire, mais j'étais curieux de savoir ce que les autres pensaient de cette entreprise en général. Y avait-il quelque chose dans la série d'étapes que j'ai prises qui aurait abouti à des résultats plus parfaits?

Et si ce n'était pas un serveur de test, je ne pouvais pas simplement "le faire en direct" et voir ce qui se passait? Quelle serait la meilleure façon de libérer temporairement de l'espace sur un esclave de production si je devais aimer ça?

14
atxdba

La plus grande chose que la plupart des gens oublient à propos de TRUNCATE TABLE est que TRUNCATE TABLE est DDL et non DML . Dans InnoDB, les métadonnées dans ibdata1 contiennent une liste numérotée de tables InnoDB. L'utilisation de TRUNCATE TABLE entraîne le décalage de l'ID de métadonnées interne de la table InnoDB. Cela se produit car TRUNCATE TABLE effectue effectivement les opérations suivantes:

Exemple: pour tronquer une table InnoDB appelée mydb.mytb

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

La nouvelle mytb aurait donc un identifiant de métadonnées interne différent.

Lorsque vous avez copié le fichier .ibd à un autre endroit, le .ibd contient en lui l'ID de métadonnées interne d'origine. Le simple fait de remettre le fichier .ibd ne provoque pas de rapprochement de l'ID de métadonnées interne avec celui de ibdata1.

Ce que vous auriez dû faire est le suivant:

Copiez le fichier .ibd de la table InnoDB. Ensuite, exécutez cette

ALTER TABLE tablename DISCARD TABLESPACE;

Pour le récupérer ultérieurement, copiez le fichier .ibd dans datadir puis exécutez

ALTER TABLE tablename IMPORT TABLESPACE;

Cela aurait préservé l'ID de métadonnées interne.

Assurez-vous que .frm est toujours présent.

Une fois, j'ai aidé un client à restaurer 30 tables InnoDB qu'il avait arrosées de la même manière. J'ai dû utiliser un autre serveur de base de données et jouer à des jeux avec l'ajout et la suppression de tables InnoDB pour rechercher le bon identifiant de métadonnées interne.

Le client a trouvé cet article: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Nous l'avons utilisé et cela a beaucoup aidé. J'espère que ça t'aide.

15
RolandoMySQLDBA