Gibt es eine Möglichkeit, eine abgelegte MySQL-Datenbank wiederherzustellen?

8

Ich habe versehentlich eine MySQL-Datenbank auf meinem Server gelöscht. Gibt es Möglichkeiten, eine gelöschte Datenbank wiederherzustellen?

Kewl
quelle
Auf welcher Plattform läuft Ihre MySQL-Datenbank?
Jack sagt, versuchen Sie es mit topanswers.xyz
Gibt es eine Chance, dass das Laufwerk, auf dem sich Ihre Datenbank befindet, gesichert wird und der Serveradministrator Sie retten kann?
Kenneth Fisher
Es gibt eine Vielzahl von Tools auf dem Markt, mit denen beschädigte MySQL-Datenbanken repariert werden können. Für die besten und getesteten Ergebnisse können Sie sich jedoch immer auf Stellar-Tools verlassen, um Ihre Datenbank reparieren zu lassen. Das Tool kann InnoDB- und MyISAM-Tabellen der MySQL-Datenbank reparieren. Sie können auch eine Vorschau der reparierten Datenbankobjekte erhalten, um einen Überblick über die wiederhergestellten Daten zu erhalten. Die Testversion der Software ist kostenlos verfügbar, um die Datenbank mit vollständiger Integrität und Originalformatierung zu reparieren und so Datenverlust zu vermeiden.
Mitchel

Antworten:

16

Wenn Sie schnell handeln, besteht eine hohe Wahrscheinlichkeit, dass Sie Ihre Datenbank zurückerhalten. Die Chance ist für InnoDB höher, für MyISAM ist es nicht Null, aber nahe.

Die Sache ist, wenn MySQL DROP TABLE oder DROP DATABASE ausführt (was im Wesentlichen dasselbe ist). InnoDB löscht die Daten nicht. Seiten mit den Daten befinden sich noch auf der Festplatte.

Abhängig von der Einstellung innodb_file_per_table unterscheidet sich der Wiederherstellungsprozess. Wenn innodb_file_per_table AUS ist (Standard bis 5.5), bleibt die abgelegte Tabelle in ibdata1. Wenn innodb_file_per_table auf ON gesetzt ist (Standard ab 5.5), befand sich die abgelegte Tabelle in der entsprechenden .ibd-Datei. MySQL entfernt diese Datei, wenn die Tabelle gelöscht wird.

Das allererste, was Sie tun müssen, ist, mögliche Schreibvorgänge zu stoppen, damit Ihre Tabelle nicht überschrieben wird. Wenn innodb_file_per_table deaktiviert ist, reicht es aus, MySQL zu stoppen (kill -9 ist noch besser, aber stellen Sie sicher, dass Sie safe_mysqld zuerst beenden). Wenn innodb_file_per_table aktiviert ist, wird die Partition umount, in der MySQL seine Daten speichert. Wenn sich der Datenverzeichnis auf der Root-Partition befindet, empfehle ich, den Server herunterzufahren oder zumindest ein Image der Festplatte zu erstellen. Lassen Sie mich wiederholen, das Ziel ist es, das Überschreiben von gelöschten Tabellen durch MySQL oder das Betriebssystem zu verhindern.

Es gibt ein Tool, das die Arbeit mit InnoDB-Seiten auf niedriger Ebene ermöglicht, das TwinDB-Toolkit zur Datenwiederherstellung . Ich werde es verwenden, um die Undrop-Erholung zu veranschaulichen.

Sie müssen das Medium mit der abgelegten Tabelle (entweder ibdata1 oder Disk-Image) nehmen und InnoDB-Seiten darauf finden. Das stream_parser-Tool aus dem Toolkit erledigt dies.

./stream_parser -f /path/to/disk/image

Es scannt die Datei, findet die InnoDB-Seiten und sortiert sie nach Typ und Index-ID. index_id ist eine Kennung, mit der InnoDB auf einen Index verweist. Eine Tabelle wird im Index PRIMARY gespeichert. Um herauszufinden, welche index_id Ihre abgelegte Tabelle ist, müssen Sie das InnoDB-Wörterbuch wiederherstellen .

Das InnoDB-Wörterbuch wird in der Datei ibdat1 gespeichert. Sie müssen die Datei ibdata1 auf die gleiche Weise wie oben scannen:

./stream_parser -f /var/lib/mysql/ibdata1

Jetzt müssen Sie Datensätze aus den InnoDB-Wörterbuchtabellen SYS_TABLES und SYS_INDEXES abrufen (sagen wir, Ihre Tabelle ist 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 ist table_id, erinnere dich daran.

./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

Die index_id Ihrer abgelegten Tabelle (sakila.actor) lautet also 376.

Jetzt können Sie Datensätze der gelöschten Tabelle aus InnoDB index_id 376 abrufen. Sie benötigen die Tabellenstruktur der abgelegten Tabelle, genau die Anweisung CREATE TABLE, mit der die Tabelle erstellt wurde. Wo kann man es bekommen? Entweder aus einem alten Backup oder von einem anderen Ort. Es ist auch möglich, die Struktur aus dem InnoDB-Wörterbuch wiederherzustellen, aber ich werde sie in dieser Antwort nicht behandeln. Nehmen wir einfach an, Sie haben es.

./c_parser -6f pages-ibdata1/FIL_PAGE_INDEX/0000000000000376.page -t actor.sql > dump.tsv 2> load_cmd.sql

c_parser gibt Datensätze als tabulatorgetrennten Speicherauszug an stdout aus. Der Speicherauszug kann mit dem Befehl LOAD DATA geladen werden. c_parser druckt es an stderr.

Weitere Details finden Sie in den Beiträgen:

akuzminsky
quelle
Ist es immer noch wiederherstellbar, wenn ich nach dem Löschen der Tabelle eine neue Tabelle erstelle und neue Datensätze einfüge?
Oki Erie Rinaldi
In diesem Fall verlieren Sie index_id, weil CREATE den ursprünglichen Wert überschreibt. Sie müssen es irgendwie finden. Normalerweise grep ich bekannte Strings. Die folgenden INSERTs können die Daten überschreiben oder nicht. Wenn nicht, ist es wiederherstellbar. Sie müssen versuchen, es gibt keine Möglichkeit, vorher zu sagen
akuzminsky
Dieser Link gibt eine 404 !!
Nie mehr
@akuzminsky Ich habe bis zum Teil "dictionary / SYS_INDEXES.sql | grep 158". Und es gibt mir eine index_id für meine Tabelle, aber es heißt, dass es keine Auslagerungsdatei mit meiner index_id gibt. Beispiel: 0000000000000376.page (wenn ich diesen c_parser -6f starte)
Sampath Sri Anuradha
@SampathSriAnuradha Es muss sich schlecht anfühlen, wenn Fortune nicht auf deiner Seite ist. Es tut mir Leid.
Akuzminsky
11

Es gibt keine einfache Möglichkeit, dies für Sie zu brechen. Es spielt keine Rolle, ob Sie eine Datenbank über phpmyadmin oder die Befehlszeile gelöscht haben. Es ist weg.

Menschliches Versagen ist ein Grund für ein gutes Backup-Regime.

Ich bin nicht religiös, aber ich werde ein Gebet sprechen, in der Hoffnung, dass es nicht allzu wichtig ist.

atxdba
quelle
Es war sehr wichtig, dass jede Menge Transaktionen verloren gehen
Kewl
8
In diesem Fall kann ich nur empfehlen, das Dateisystem zu deaktivieren, in dem sich Ihr Datenverzeichnis befand. Fahren Sie den Server bei Bedarf herunter. Rufen Sie einen Datenwiederherstellungsdienst an und seien Sie bereit, Tausende, wenn nicht Dutzende zu berappen, während Sie für ein Mist-Shooting ohne Garauntees bezahlen: - \
atxdba
3
Wenn jemand in einer ähnlichen Situation dies in Zukunft liest, ist es meiner Meinung nach auch sinnvoll, darauf hinzuweisen, dass es wichtig ist, das Dateisystem so schnell wie möglich zu entfernen oder schreibgeschützt zu machen, wenn Sie eine Datenrettungsfirma beauftragen. Je länger das Schreiben im Dateisystem dauert, desto wahrscheinlicher ist es, dass die Cluster, die Ihre gelöschten Dateien enthalten, überschrieben werden.
James L
2

Hängt von Ihrem Setup ab. Eine Wiederherstellung ist möglich, wenn Sie Ihr System korrekt eingerichtet haben. Wenn Sie ein Backup haben, können Sie es wiederherstellen. Wenden Sie dann die Binärprotokolle bis zu dem Punkt an, an dem Sie die Tabelle gelöscht haben.

http://dev.mysql.com/doc/refman/5.5/en/mysqlbinlog.html

Ich schlage vor, Sie tun dies auf einem anderen Server. Sobald Sie die Tabelle wiederhergestellt haben, können Sie sie mit mysqldump extrahieren und wieder auf Ihren Produktionsserver importieren. Dies ist keine schnelle Wiederherstellung, aber Sie können die Daten wiederherstellen.

Wenn Sie nicht wissen, was Sie tun, würde ich vorschlagen, einen Supportvertrag mit einem der MySQL-Beratungsunternehmen (Python, Percona, Palamino sind wahrscheinlich die besten) abzuschließen und sich dabei helfen zu lassen.

Ich wünsche Ihnen viel Glück

Allen Kinnard
quelle