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

13

J'ai donc un serveur de base de données de test qui a été installé 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 tournaient horriblement 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êtez l'asservissement / l'arrêt de mysql
  7. Copiez le fichier 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 vivre" 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?

atxdba
la source

Réponses:

15

La plus grande chose que la plupart des gens oublient 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 plus tard, 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.

J'ai aidé une fois 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.

RolandoMySQLDBA
la source
1
J'ai 2 bases de données où toutes les tables disent Table 'X' doesn't exist in engine. Dois-je faire la méthode ci-dessus pour chacune des tables ou existe-t-il de meilleures façons de résoudre ce problème?
papanito
-2

J'ai expérimenté avec mon Mac, avant de vendre à un ami, copiez simplement le dossier XAMPP uniquement sur mon disque dur. (PAS DE SUCCÈS) Malheureusement, cela me posait des problèmes, car j'ai essayé les étapes suivantes: - J'installe de nouveaux XAMPP et copie l'intégralité des \ httdocs et var \ mysql sur mon nouveau Mac, ces db uniquement avec .frm et .ibd, NE FONCTIONNE PAS, je ne peux toujours pas accéder aux tables dans PHPMyAdmin ... - J'ai essayé d'installer la même version de xampp et de répéter les étapes ci-dessus, toujours PAS FONCTIONNANT. - J'ai décidé d'aller me coucher.

(SUCCÈS) - Ce matin, j'ai apporté mon disque de sauvegarde et essayez avec Windows 7. - Installez le dernier XAMPP pour Windows, c: \ xampp - J'ai un site Web (dossier) de ma sauvegarde \ httdocs et un dossier de base de données correspondant à l'intérieur \ var \ mysql sont PRETS dans mes fenêtres 7, je veux juste essayer avec un site web puis essayer le reste car j'ai beaucoup de projets dans httdocs \ et \ var \ mysql - je copie la mention httdocs \ dans Windows c: \ xampp \ httdocs et copiez le \ var \ mysql dans c: \ xampp \ mysql \ data

PAS DERNIER ENCORE Je copie ib_logfile0, ib_logfile1, ibdata1 de mon fichier de sauvegarde vers windows xampp c: \ xampp \ mysql \ data

Je rafraîchis le http: // localhost / mywebsite

WOW WOW DONE ... ça marche ...

Armindo
la source