MySQL InnoDB hat Tabellen verloren, aber Dateien existieren

33

Ich habe eine MySQL InnoDB, die alle Datenbanktabellendateien enthält, aber MySQL sieht sie nicht und lädt sie nicht.

Das Problem geschah , weil ich diese drei Dateien gelöscht: ibdata1, ib_logfile0undib_logfile1

weil ich Probleme mit dem Start von mysql hatte und ich las, dass ich sie entfernen wollte, weil MySQL sie einfach neu generiert (ich weiß, ich hätte sie sichern sollen, tat es aber nicht).

Was kann ich tun, damit MySQL die Tabellen wieder anzeigt?

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
Geh von meinem Rasen runter
quelle
Haben Sie versucht, diese Dateien wiederherzustellen? Die Protokolldateien können gelöscht bleiben. Du hättest ibdata1
Ramhound 13.11.13
Ich habe die Datei von einer alten MySQL-Version kopiert, in der sich die Datei befand, aber die Tabellen werden nicht angezeigt.
Steigen Sie

Antworten:

36

Dies ist der Grund, warum MySQL diese Dateien nicht sehen kann: Der System-Tablespace (ibdata1) verfügt über ein Storage-Engine-spezifisches Datenwörterbuch, mit dem InnoDB die potenzielle Verwendung von Tabellen ermitteln kann:

InnoDB-Architektur

Das Verschieben von InnoDB-Tabellen von einem Ort an einen anderen erfordert Befehle wie

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

Hier ist ein Teil der MySQL 5.5-Dokumentation, in der erklärt wird, was zu beachten ist

Überlegungen zur Portabilität von .ibd-Dateien

Sie können .ibd-Dateien nicht wie bei MyISAM-Tabellendateien frei zwischen Datenbankverzeichnissen verschieben. Die im gemeinsam genutzten InnoDB-Tabellenbereich gespeicherte Tabellendefinition enthält den Datenbanknamen. Die in den Tablespace-Dateien gespeicherten Transaktions-IDs und Protokollfolgenummern unterscheiden sich auch zwischen den Datenbanken.

Verwenden Sie eine Anweisung RENAME TABLE, um eine .ibd-Datei und die zugehörige Tabelle von einer Datenbank in eine andere zu verschieben:

RENAME TABLE db1.tbl_name TO db2.tbl_name; Wenn Sie eine "saubere" Sicherung einer .ibd-Datei haben, können Sie diese in der MySQL-Installation wiederherstellen, aus der sie wie folgt stammt:

Die Tabelle darf seit dem Kopieren der .ibd-Datei nicht gelöscht oder abgeschnitten worden sein, da dadurch die im Tablespace gespeicherte Tabellen-ID geändert wird.

Setzen Sie diese ALTER TABLE-Anweisung ab, um die aktuelle .ibd-Datei zu löschen:

ALTER TABLE Tabellenname DISCARD TABLESPACE; Kopieren Sie die .ibd-Sicherungsdatei in das richtige Datenbankverzeichnis.

Setzen Sie diese ALTER TABLE-Anweisung ab, um InnoDB anzuweisen, die neue .ibd-Datei für die Tabelle zu verwenden:

ALTER TABLE Tabellenname IMPORT TABLESPACE; In diesem Zusammenhang ist eine "saubere" .ibd-Dateisicherung eine, für die die folgenden Anforderungen erfüllt sind:

Es gibt keine nicht festgeschriebenen Änderungen durch Transaktionen in der .ibd-Datei.

Die .ibd-Datei enthält keine nicht zusammengeführten Einfügepuffereinträge.

Purge hat alle mit Löschzeichen versehenen Indexdatensätze aus der .ibd-Datei entfernt.

mysqld hat alle geänderten Seiten der .ibd-Datei aus dem Pufferpool in die Datei geleert.

In Anbetracht dieser Einschränkungen und Protokolle wird hier eine Vorgehensweise vorgeschlagen

In diesem Beispiel versuchen wir, die tagsTabelle in der mydbDatenbank wiederherzustellen

SCHRITT 1

Stellen Sie sicher, dass Sie Sicherungen von diesen .frmund .ibdDateien in haben/tmp/innodb_data

SCHRITT 2

Holen Sie sich die CREATE TABLE tagsAnweisung und führen Sie sie aus als CREATE TABLE mydb.tags .... Stellen Sie sicher, dass es sich genau um die gleiche Struktur wie das Original handelttags.frm

SCHRITT 3

Löschen Sie die leere tags.ibdmit MySQL

ALTER TABLE mydb.tags DISCARD TABLESPACE;

SCHRITT 4

Bringen Sie die Sicherungskopie von tags.ibd

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

SCHRITT 5

Fügen Sie tagsdem InnoDB Data Dictionary eine Tabelle hinzu

ALTER TABLE mydb.tags IMPORT TABLESPACE;

SCHRITT 6

Testen Sie die Zugänglichkeit der Tabelle

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

Wenn Sie normale Ergebnisse erhalten, gratulieren Sie zum Import einer InnoDB-Tabelle.

SCHRITT 7

Bitte löschen Sie in Zukunft ibdata1 und seine Protokolle nicht mehr

Versuche es !!!

Ich habe solche Dinge schon einmal besprochen

VORBEHALT

Was ist, wenn Sie die Tabellenstruktur der nicht kennen tags?

Es gibt Tools, mit denen die Anweisung CREATE TABLE nur mithilfe der .frmDatei abgerufen werden kann. Ich habe auch dazu einen Beitrag geschrieben: Wie kann ich das Tabellenschema nur aus der .frm-Datei extrahieren? . In diesem Beitrag habe ich eine .frm-Datei von einer Linux-Box auf einen Windows-Computer kopiert, das Windows-Tool ausgeführt und die CREATE TABLEAnweisung erhalten.

RolandoMySQLDBA
quelle
Danke für die tolle Antwort! Ich bin immer noch dabei, eine Tabelle zu importieren, weil ich immer wieder Probleme verursache, aber ich werde es irgendwann schaffen und Sie wissen lassen, wie es funktioniert! Vielen Dank!
Steigen Sie
1
Wenn ich das create ausführe, erhalte ich: ERROR 1813 (HY000): Tablespace for table ' weblyize. tags'existiert. Bitte verwerfen Sie den Tablespace vor dem Import. Also versuche ich zuerst den alter Tablespace auszuführen und erhalte diesen Fehler: FEHLER 1146 (42S02): Die Tabelle 'weblyize.tags' existiert nicht . Was kann ich tun?
Steigen Sie
Vielen Dank! Um meinen Fehler zu beheben, habe ich eine neue Datenbank erstellt und bin CREATE TABLE ...dann Ihren Schritten gefolgt! Sie haben mich davor bewahrt, sie zu 100% von Grund auf neu schreiben zu müssen! Es wurden keine Fremdschlüssel importiert, aber das ist in Ordnung. Ich kann das selbst tun! Noch einmal Danke!
meinem Rasen
Was ist, wenn ich 100 Tische habe, die auf diese Weise repariert werden sollten? Ich werde nicht für jeden Tisch von Hand operieren. Wie könnte es automatisiert werden?
Oleg Abrazhaev
10

Ich habe die gleiche Situation, kann nicht löschen oder bestimmte tblname erstellen. Mein Fixverfahren ist:

  1. Stoppen Sie MySQL.

    service mysql stop
    
  2. Entfernen Sie ib_logfile0 und ib_logfile1.

    cd /var/lib/mysql;
    rm ib_logfile0 ib_logfile1
    
  3. Tblname-Dateien entfernen. WARNUNG: Dadurch werden Ihre Daten dauerhaft gelöscht

    cd /var/lib/mysql/dbname;
    rm tblname*
    
  4. Starten Sie MySQL.

    service mysql start
    
user293871
quelle
1
Vielen Dank, dass dies mein Problem behoben hat. Ich habe Schritt 3 nicht ausgeführt. Ich habe einfach die Protokolldateien entfernt und mit der Sicherung von MySQL begonnen.
Jeff Wilbert
Du bist absolut fantastisch! Löste mein Problem.
Alex GP
2

Ich hatte auch dieses Problem. Ich habe versehentlich gelöscht ibdata1und alle meine Daten gingen verloren.

Nach ein bis zwei Tagen Suche in Google und SO fand ich endlich eine Lösung, die mir das Leben rettete (ich hatte so viele Datenbanken und Tabellen mit riesigen Datensätzen).

  1. Erstellen Sie eine Sicherungskopie von /var/lib/mysql

  2. Wiederherstellen des Tabellenschemas aus einer .frmDatei mit dbsake (es gab eine andere Option! mysqlfrm . Aber es hat bei mir nicht funktioniert)

dbsake frmdump --type-codes /var/lib/mysql/database-name/tbl.frm
  1. Erstellen Sie eine neue Tabelle (mit neuem Namen) mit exportiertem Schema.

  2. Verwerfen Sie neue Tabellendaten mit diesem Befehl:

ALTER TABLE `tbl-new` DISCARD TABLESPACE;
  1. Kopieren Sie die Daten der alten Tabelle und fügen Sie sie anstelle der neuen ein und legen Sie die entsprechenden Berechtigungen fest.
cp tbl.ibd [email protected] && chown mysql:mysql [email protected]
  1. Daten in neue Tabelle importieren.
ALTER TABLE `tbl-new` IMPORT TABLESPACE;
  1. in Ordung! Wir haben Daten in einer neuen Tabelle und können die alte löschen.
DROP TABLE `tbl`;
  1. Überprüfen Sie, /var/lib/mysql/database-nameob Daten ( .ibdDateien) für alte Tabellen vorhanden sind, und löschen Sie sie.
rm tbl.ibd
  1. und benennen Sie schließlich die neue Tabelle in den ursprünglichen Namen um
ALTER TABLE `tbl-new` RENAME `tbl`;
mostafaznv
quelle