Aller au contenu principal

Actus / Le lab

Récupérer une base InnoDB à partir des fichiers .ftm

Cet article se base sur ce post dont il est largement inspiré :
https://medium.com/magebit/recover-innodb-database-from-frm-and-ibd-files-99fdb0deccad

Contexte :

Je viens de griller la carte SSD de mon backbook Pro que je venais de changer pour une plus grande capacité. Heureusement j'ai une sauvegarde relativement récente et donc, peu de perte de données.
Je cherche à retrouver mes bases de données locales que je n'avais pas préalablement exportées, via les fichiers Mysql (version 5.6) dans le dossier de MAMP que j'utilise en local (/Library/Application Support/appsolute/MAMP PRO/db/mysql56).
Je copie-colle les dossiers des bases sauvegardées dans ce dossier, espérant que tout fonctionne tout seul et, bien sûr, cela ne fonctionne pas. Les bases semblent corrompues, InnoDB est incapable avec l'ensemble des dossiers sauvegardés de retrouver ses petits (j'ai pourtant la totalité des fichiers du dossier mysql56, dont ib_logfile 1 & 2, ibdata1, etc.).

ERROR 1146 (42S02): Table ‘database.table’ doesn’t exist

Comment faire pour retrouver ses bases locales qui n'existent pas ailleurs, sur d'autres serveurs (notre base de comptabilité, par exemple) ?

Voici la solution :

Étape 1 : retrouver la structure de notre base de données

Note : Ceci fonctionne seulement si vous avez ces paramètres dans votre fichier de configuration Mysql, pour que les données soient stockées dans les fichiers .frm/.ibd et non le fichier ibdata.

[mysqld]
innodb_file_per_table = 1
innodb_force_recovery = 1

Pour cela, éditer le fichier my.cnf (dans MAMP, menu File/Edit Template/MySQL (my.cnf)) et ajouter cette ligne. Redémarrer Mysql pour que ce paramètre soit pris en compte.

Pour retrouver la structure de votre base de données, créer une archive du dossier de votre base de données sauvegardée (i.e. ma_base_svg.zip) et l'uploader sur ce site : https://recovery.twindb.com/
(outil gratuit : Recover structure / from .frm file).

L'outil vous donne les requêtes SQL pour recréer toutes les tables de votre base.

Étape 2 : créer une nouvelle base de donnée

En premier lieu, l'objectif est de retrouver partiellement l'accès à la base et à ses données pour effectuer un export (dump) de celle-ci.

Créer une base de données (temporaire pour une utilisation finale MySQL 5.5, CF. article d'origine en anglais, si MySQL 5.6, c'est la définitive), qui va servir à effectuer cette opération :

  • Créer une base temporaire (i.e. ma_base) :
    mysql -u root -p CREATE DATABASE ma_base
  • Lancer les requêtes de création des tables données par l'outil en ligne

Nous devons ensuite supprimer la dépendance des fichiers .frm aux 'tablespaces' .idb avec la requête suivante : ALTER TABLE ma_table DISCARD TABLESPACE;

Personnellement, j'utilise un tableur avec en 1er colonne les 'ALTER TABLE', en deuxième, les noms de mes tables (copiées sur PhpMyadmin par exemple) et en troisième 'DISCARD TABLESPACE;'. Je copie-colle le tout dans un éditeur de texte simple et je cherche remplace les tabulations laissées par le tableur par des espaces pour obtenir :

ALTER TABLE ma_table1 DISCARD TABLESPACE;
ALTER TABLE ma_table2 DISCARD TABLESPACE;
ALTER TABLE ma_table3 DISCARD TABLESPACE;

L'auteur de la page originelle donne cette requête pour tout faire d'un coup mais je n'ai pas réussi à la faire fonctionner chez moi.Si quelqu'un a une solution, je suis preneur :) :

USE INFORMATION_SCHEMA;
SELECT 
CONCAT(“ALTER TABLE `”, TABLE_SCHEMA,”`.`”, TABLE_NAME, “` DISCARD TABLESPACE;”) 
AS MySQLCMD FROM TABLES 
WHERE TABLE_SCHEMA = “ma_base”;

Étape 3 : re-lier les fichiers .ibd et .frm

À cette étape, nous devons arrêter MySQL (éteindre le serveur MySQL dans MAMP).

Nous copions-collons les fichiers .ibd de la base sauvegardée dans le dossier de la base temporaire.
Disons que ce dossier ce trouve dans votre dossier HOME :

cp -f ~/ma_base_svg/*.ibd /Library/Application Support/appsolute/MAMP PRO/db/mysql56/ma_base_svg/

Nous redémarrons ensuite le service MySQL. Nous devons ici reconstruire les tablespaces des fichiers .idb pour accéder à nos données. Pour cela, nous allons appliquer la requête suivante :

ALTER TABLE ma_table IMPORT TABLESPACE;

De même que pour la suppression de la dépendance, utiliser un tableur ou bien la requête suivante :

USE INFORMATION_SCHEMA;
SELECT 
CONCAT(“ALTER TABLE `”, TABLE_SCHEMA,”`.`”, TABLE_NAME, “` IMPORT TABLESPACE;”) 
AS MySQLCMD FROM TABLES 
WHERE TABLE_SCHEMA = “ma_base”;

Si vous rencontrez une erreur telle que :

ERROR 1030 (HY000): Got error -1 from storage engine

Essayez une autre méthode et vérifiez que votre système a bien assez de place de stockage (en ligne de commande, dh -f pour connaître l'espace disque restant).
Cet article peut vous aider (en anglais) : http://sq4ind.eu/restoring-corrupted-innodb-mysql-databases/
 

Étape 4 : export et import

Votre base est désormais accessible, avec ses données. La seule chose qu'il vous reste à faire est de l'exporter et la ré-importer dans le cas où vous êtes dans une version antérieure de MySQL (5.5).

Dans le cas où vous êtes déjà en 5.6, votre base temporaire est en fait votre base finale et vous pouvez retrouver votre configuration MySQL habituelle, en éditant de nouveau votre fichier my.cnf (je les commente, au cas où j'en aurais de nouveau besoin) :

[mysqld]
# innodb_file_per_table = 1
# innodb_force_recovery = 1

 

 

Nous écrire

Laissez-nous un mot, nous serons ravis de vous répondre...

Image couteau stylo
CAPTCHA
Cette question vous est posée pour éviter les SPAMS (ou pourriels, mails malveillants).