MySQL InnoDB a perdu des tables mais des fichiers existent

33

J'ai un MySQL InnoDB qui contient tous les fichiers de table de base de données, mais MySQL ne les voit pas et ne les charge pas.

Le problème est arrivé parce que je supprimé ces trois fichiers: ibdata1, ib_logfile0etib_logfile1

parce que j'avais des problèmes avec le démarrage de mysql, et ce que j'ai lu était de les supprimer car MySQL va juste les régénérer (je sais que j'aurais dû les sauvegarder mais pas).

Que puis-je faire pour que MySQL revoie les tables?

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
Descendre ma pelouse
la source
Avez-vous essayé de restaurer ces fichiers? Les fichiers journaux peuvent rester supprimés. Vous ne devriez vraiment pas avoir supprimé ibdata1
Ramhound
J'ai copié le fichier à partir d'une ancienne version de mysql où se trouvait le fichier mais les tableaux n'apparaissent pas.
Descendez de ma pelouse

Réponses:

36

Voici pourquoi MySQL ne peut pas voir ces fichiers: L'espace disque logique système (ibdata1) possède un dictionnaire de données spécifique au moteur de stockage qui permet à InnoDB de cartographier l'utilisation potentielle de la table:

Architecture InnoDB

Le déplacement des tables InnoDB d'un endroit à un autre nécessite des commandes telles que

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

Voici une partie de la documentation MySQL 5.5 expliquant ce qui doit être pris en compte

Considérations de portabilité pour les fichiers .ibd

Vous ne pouvez pas déplacer librement les fichiers .ibd entre les répertoires de base de données comme vous pouvez le faire avec les fichiers de table MyISAM. La définition de table stockée dans l'espace de table partagé InnoDB inclut le nom de la base de données. Les ID de transaction et les numéros de séquence de journal stockés dans les fichiers d'espace disque logique diffèrent également entre les bases de données.

Pour déplacer un fichier .ibd et la table associée d'une base de données vers une autre, utilisez une instruction RENAME TABLE:

RENAME TABLE db1.tbl_name TO db2.tbl_name; Si vous avez une sauvegarde «propre» d'un fichier .ibd, vous pouvez le restaurer dans l'installation MySQL d'où il provient comme suit:

La table ne doit pas avoir été supprimée ou tronquée depuis que vous avez copié le fichier .ibd, car cela modifie l'ID de table stocké dans l'espace disque logique.

Émettez cette instruction ALTER TABLE pour supprimer le fichier .ibd actuel:

ALTER TABLE tbl_name DISCARD TABLESPACE; Copiez le fichier .ibd de sauvegarde dans le répertoire de base de données approprié.

Émettez cette instruction ALTER TABLE pour indiquer à InnoDB d'utiliser le nouveau fichier .ibd pour la table:

ALTER TABLE tbl_name IMPORT TABLESPACE; Dans ce contexte, une sauvegarde de fichier .ibd «propre» est une sauvegarde pour laquelle les conditions suivantes sont remplies:

Il n'y a aucune modification non validée par des transactions dans le fichier .ibd.

Il n'y a aucune entrée de tampon d'insertion non fusionnée dans le fichier .ibd.

La purge a supprimé tous les enregistrements d'index marqués comme supprimés du fichier .ibd.

mysqld a vidé toutes les pages modifiées du fichier .ibd du pool de tampons dans le fichier.

Compte tenu de ces mises en garde et protocoles, voici un plan d'action suggéré

Pour cet exemple, essayons de restaurer la tagstable dans la mydbbase de données

ÉTAPE 1

Assurez-vous d'avoir des sauvegardes de ceux-ci .frmet des .ibdfichiers dans/tmp/innodb_data

ÉTAPE 2

Obtenez l' CREATE TABLE tagsinstruction et exécutez-la en tant que CREATE TABLE mydb.tags .... Assurez-vous que c'est exactement la même structure que l'originaltags.frm

ÉTAPE 3

Supprimer le vide en tags.ibdutilisant MySQL

ALTER TABLE mydb.tags DISCARD TABLESPACE;

ÉTAPE 4

Apportez la copie de sauvegarde de tags.ibd

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

ÉTAPE # 5

Ajouter une tagstable au dictionnaire de données InnoDB

ALTER TABLE mydb.tags IMPORT TABLESPACE;

ÉTAPE 6

Testez l'accessibilité de la table

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

Si vous obtenez des résultats normaux, félicitations pour l'importation d'une table InnoDB.

ÉTAPE 7

À l'avenir, veuillez ne pas supprimer ibdata1 et ses journaux

Essaie !!!

J'ai discuté de choses comme ça avant

CAVEAT

Et si vous ne connaissez pas la structure de la table du tags?

Il existe des outils pour obtenir l'instruction CREATE TABLE en utilisant simplement le .frmfichier. J'ai également écrit un article à ce sujet: Comment extraire le schéma de table à partir du fichier .frm? . Dans ce post, j'ai copié un fichier .frm sur une machine Windows à partir d'une boîte Linux, j'ai exécuté l'outil Windows et obtenu la CREATE TABLEdéclaration.

RolandoMySQLDBA
la source
Merci pour la réponse géniale! Je suis toujours en train d'importer une table importée, car je continue de créer des problèmes, mais j'y arriverai finalement, et je vous ferai savoir comment ça marche! Merci!
Descendez de ma pelouse
1
Lorsque j'exécuteweblyizetags la création, j'obtiens: ERREUR 1813 (HY000): Espace disque logique pour la table ' . 'existe. Veuillez JETER l'espace disque logique avant d'importer. Alors j'essaie d'abord d'exécuter le tablespace alter et d'obtenir cette erreur: ERREUR 1146 (42S02): la table 'weblyize.tags' n'existe pas . Que puis-je faire?
Descendez de ma pelouse
Merci! Pour corriger mon erreur, j'ai créé une nouvelle base de données, j'ai couru CREATE TABLE ...puis suivi vos étapes! Vous m'avez évité d'avoir à les réécrire à 100% à partir de zéro! Il n'a pas importé de clés étrangères mais ça va, je peux le faire moi-même! Merci encore!
Descendez de ma pelouse
Et si j'ai 100 tables qui devraient être corrigées de cette façon. Je ne ferai pas d'opérations pour chaque table à la main. Comment pourrait-il être automatisé?
Oleg Abrazhaev
10

J'ai la même situation, impossible de supprimer ou de créer un nom de tbl spécifique. Ma procédure de correction est la suivante:

  1. Arrêtez MySQL.

    service mysql stop
    
  2. Supprimez ib_logfile0 et ib_logfile1.

    cd /var/lib/mysql;
    rm ib_logfile0 ib_logfile1
    
  3. Supprimez les fichiers tblname. AVERTISSEMENT: CECI SUPPRIMERA DE MANIÈRE PERMANENTE VOS DONNÉES

    cd /var/lib/mysql/dbname;
    rm tblname*
    
  4. Démarrez MySQL.

    service mysql start
    
user293871
la source
1
Merci d'avoir résolu mon problème, je n'ai pas fait l'étape 3, j'ai simplement supprimé les fichiers journaux et redémarré mysql.
Jeff Wilbert
Tu es absolument fantastique! Résolu mon problème.
Alex GP
2

J'ai eu ce problème également. J'ai supprimé ibdata1accidentellement et toutes mes données ont été perdues.

Après 1 à 2 jours de recherche dans Google et SO, j'ai finalement trouvé une solution qui m'a sauvé la vie (j'avais tellement de bases de données et de tableaux avec d'énormes enregistrements).

  1. prendre une sauvegarde de /var/lib/mysql

  2. récupérer le schéma de table à partir d'un .frmfichier avec dbsake (il y avait une autre option! mysqlfrm . mais cela n'a pas fonctionné pour moi)

dbsake frmdump --type-codes /var/lib/mysql/database-name/tbl.frm
  1. créer une nouvelle table (avec un nouveau nom) avec le schéma exporté.

  2. supprimer les nouvelles données de table avec cette commande:

ALTER TABLE `tbl-new` DISCARD TABLESPACE;
  1. Copiez les données de l'ancienne table et collez-les au lieu de nouvelles et définissez les autorisations appropriées.
cp tbl.ibd [email protected] && chown mysql:mysql [email protected]
  1. importer des données dans une nouvelle table.
ALTER TABLE `tbl-new` IMPORT TABLESPACE;
  1. bien! nous avons des données dans un nouveau tableau et nous pouvons supprimer l'ancien.
DROP TABLE `tbl`;
  1. vérifiez /var/lib/mysql/database-nameet s'il existe des données ( .ibdfichier) pour l'ancienne table, supprimez-les.
rm tbl.ibd
  1. et enfin renommer la nouvelle table en nom d'origine
ALTER TABLE `tbl-new` RENAME `tbl`;
mostafaznv
la source