J'ai accidentellement déposé une base de données MySQL sur mon serveur. Existe-t-il des moyens de récupérer une base de données supprimée?
J'ai accidentellement déposé une base de données MySQL sur mon serveur. Existe-t-il des moyens de récupérer une base de données supprimée?
Réponses:
Si vous agissez rapidement, il y a de fortes chances de récupérer votre base de données. La chance est plus élevée pour InnoDB, pour MyISAM, elle est non nulle, mais proche.
Le problème est quand MySQL exécute DROP TABLE ou DROP DATABASE (qui est essentiellement le même) InnoDB n'efface pas les données. Les pages contenant les données sont toujours sur le disque.
Selon le paramètre innodb_file_per_table, le processus de récupération diffère. Si innodb_file_per_table est désactivé (par défaut jusqu'à 5.5), la table supprimée reste dans ibdata1. Si innodb_file_per_table est activé (par défaut à partir de 5.5), la table supprimée se trouvait dans le fichier .ibd respectif. MySQL supprime ce fichier lors de la suppression de la table.
La toute première chose à faire est d'arrêter toutes les écritures possibles afin que votre table ne soit pas écrasée. Si innodb_file_per_table est désactivé, il suffit d'arrêter MySQL (kill -9 est encore mieux, mais assurez-vous de tuer safe_mysqld en premier). Si innodb_file_per_table est activé, alors la partition umount où MySQL stocke ses données. Si le datadir est sur la partition racine, je recommande d'arrêter le serveur ou au moins de prendre une image du disque. Permettez-moi de répéter, le but est d'éviter d'écraser la table perdue par MySQL ou le système d'exploitation.
Il existe un outil qui permet de travailler avec des pages InnoDB à bas niveau, TwinDB data recovery toolkit . Je vais l'utiliser pour illustrer la récupération undrop.
Vous devez prendre le support avec la table supprimée (ibdata1 ou image disque) et y trouver des pages InnoDB. L'outil stream_parser de la boîte à outils le fait.
./stream_parser -f /path/to/disk/image
Il va scanner le fichier, trouver les pages InnoDB et les trier par type et index_id. index_id est un identifiant qu'InnoDB utilise pour faire référence à un index. Une table est stockée dans l'index PRIMARY. Pour trouver quel index_id est votre table supprimée, vous devez récupérer le dictionnaire InnoDB .
Le dictionnaire InnoDB est stocké dans le fichier ibdat1. Vous devez analyser le fichier ibdata1 de la même manière que ci-dessus:
./stream_parser -f /var/lib/mysql/ibdata1
Vous devez maintenant obtenir les enregistrements des tables de dictionnaire InnoDB SYS_TABLES et SYS_INDEXES (disons que votre table est sakila.actor):
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql | grep sakila/actor
000000000B28 2A000001430D4D SYS_TABLES "sakila/actor" 158 4 1 0 0 "" 0
158 est table_id, souvenez-vous-en.
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql | grep 158
000000000B28 2A000001430BCA SYS_INDEXES 158 376 "PRIMARY" 1 3 0 4294967295
000000000B28 2A000001430C3C SYS_INDEXES 158 377 "idx\_actor\_last\_name" 1 0 0 4294967295
Ainsi, index_id de votre table supprimée (sakila.actor) est 376.
Vous pouvez maintenant récupérer les enregistrements de la table supprimée dans InnoDB index_id 376. Vous devez avoir la structure de la table de la table supprimée, exactement l'instruction CREATE TABLE avec laquelle la table a été créée. Où pouvez-vous l'obtenir? Soit à partir d'une ancienne sauvegarde, soit d'ailleurs. Il est également possible de récupérer la structure du dictionnaire InnoDB, mais je ne le couvrirai pas dans cette réponse. Supposons simplement que vous l'avez.
./c_parser -6f pages-ibdata1/FIL_PAGE_INDEX/0000000000000376.page -t actor.sql > dump.tsv 2> load_cmd.sql
c_parser renvoie les enregistrements sous forme de vidage séparé par tabulation vers stdout. Le vidage peut être chargé avec la commande LOAD DATA. c_parser l'imprime sur stderr.
Voir plus de détails dans les articles:
Il n'y a pas de moyen facile de vous le dire. Peu importe si vous avez supprimé une base de données via phpmyadmin ou la ligne de commande. C'est parti.
L'erreur humaine est une raison d'avoir un bon régime de sauvegarde.
Je ne suis pas religieux mais je dirai une prière en espérant que ce n'était pas trop important.
Cela dépend de votre configuration. Il est possible de restaurer si vous configurez correctement votre système. Si vous avez une sauvegarde, vous pouvez la restaurer. puis appliquez les journaux binaires jusqu'au point juste avant de supprimer la table.
http://dev.mysql.com/doc/refman/5.5/en/mysqlbinlog.html
Je vous suggère de le faire sur un autre serveur, une fois la table restaurée, vous pouvez utiliser mysqldump pour l'extraire et l'importer sur votre serveur de production. Ce ne sera pas une restauration rapide, mais vous pouvez récupérer les données.
Si vous ne savez pas ce que vous faites, je suggérerais d'ouvrir un contrat de support avec l'une des sociétés de conseil mysql (pythian, percona, palamino sont probablement les meilleurs) et de les faire vous aider.
Je vous souhaite bonne chance