2013-11-13 14:52:59 +0000 2013-11-13 14:52:59 +0000
33
33

MySQL InnoDB hat Tabellen verloren, aber Dateien existieren

Ich habe eine MySQL InnoDB, die alle Datenbanktabellen-Dateien hat, aber MySQL sieht sie nicht und lädt sie nicht.

Das Problem ist entstanden, weil ich diese drei Dateien gelöscht habe: ibdata1, ib_logfile0 und ib_logfile1

, weil ich Probleme mit dem Starten von MySQL hatte, und was ich gelesen habe, war, sie zu entfernen, weil MySQL sie einfach neu generiert (ich weiß, ich hätte sie sichern sollen, habe es aber nicht getan).

Was kann ich tun, um MySQL dazu zu bringen, die Tabellen wieder zu sehen?

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

Antworten (3)

36
36
36
2013-11-14 15:34:22 +0000

Hier ist der Grund, warum MySQL diese Dateien nicht sehen kann: Der System-Tablespace (ibdata1) hat ein Storage-Engine-spezifisches Datenwörterbuch, mit dem InnoDB eine mögliche Tabellennutzung abbildet:

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

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

ALTER TABLE mydb.tags DISCARD TABLESPACE;

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

Portabilitätsüberlegungen für .ibd-Dateien

Sie können .ibd-Dateien nicht frei zwischen Datenbankverzeichnissen verschieben, wie Sie es mit MyISAM-Tabellendateien können. Die im gemeinsamen InnoDB-Tablespace gespeicherte Tabellendefinition enthält den Datenbanknamen. Die in den Tablespace-Dateien gespeicherten Transaktions-IDs und Log-Sequenznummern unterscheiden sich ebenfalls zwischen den Datenbanken.

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

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

Die Tabelle darf nicht gelöscht oder abgeschnitten worden sein, seit Sie die .ibd-Datei kopiert haben, da dies die im Tablespace gespeicherte Tabellen-ID ändert.

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

ALTER TABLE tbl_name DISCARD TABLESPACE; Kopieren Sie die Sicherungs.ibd-Datei in das richtige Datenbankverzeichnis.

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

ALTER TABLE tbl_name IMPORT TABLESPACE; In diesem Zusammenhang ist eine “saubere” .ibd-Dateisicherung eine, bei der die folgenden Anforderungen erfüllt sind:

Es gibt keine unbestätigten Änderungen durch Transaktionen in der .ibd-Datei.

Es gibt keine nicht freigegebenen Einfügepuffereinträge in der .ibd-Datei.

Purge hat alle löschmarkierten Indexeinträge aus der .ibd-Datei entfernt.

mysqld hat alle modifizierten Seiten der .ibd-Datei aus dem Pufferpool in die Datei gespült.

In Anbetracht dieser Vorbehalte und Protokolle ist hier eine vorgeschlagene Vorgehensweise

Für dieses Beispiel lassen Sie uns versuchen, die tags-Tabelle in der mydb-Datenbank wiederherzustellen

SCHRITT #1

Stellen Sie sicher, dass Sie Backups der .frm- und .ibd-Dateien in /tmp/innodb_data

SCHRITT #2

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

SCHRITT #3

Löschen Sie das leere tags.ibd mit MySQL

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

SCHRITT #4

Bringen Sie die Sicherheitskopie von tags.ibd

ALTER TABLE mydb.tags IMPORT TABLESPACE;

SCHRITT #5

Hinzufügen der Tabelle tags zum InnoDB Data Dictionary

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

SCHRITT 6

Testen Sie die Erreichbarkeit der Tabelle

Wenn Sie normale Ergebnisse erhalten, herzlichen Glückwunsch, dass Sie eine InnoDB-Tabelle importieren.

STEP 7

Löschen Sie in Zukunft bitte nicht ibdata1 und seine Logs

Probieren Sie es aus!!!

Ich habe solche Dinge schon einmal besprochen

CAVEAT

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

Es gibt Werkzeuge, um die CREATE TABLE-Anweisung nur über die .frm-Datei zu erhalten. Ich habe dazu auch einen Beitrag geschrieben: Wie kann man das Tabellenschema nur aus der .frm-Datei extrahieren? . In diesem Beitrag habe ich eine .frm-Datei von einem Linux-Rechner auf einen Windows-Rechner kopiert, das Windows-Tool ausgeführt und die CREATE TABLE-Anweisung erhalten.

10
10
10
2014-01-28 02:08:22 +0000

Ich habe die gleiche Situation: Ich kann bestimmte Tabellennamen nicht löschen oder erstellen. Meine Korrekturprozedur ist:

  1. Stoppen Sie MySQL.

  2. Entfernen Sie ib_logfile0 und ib_logfile1.

  3. Entfernen Sie tblname-Dateien. WARNUNG: DAMIT WERDEN IHRE DATEN PERMANENT GELÖSCHT

  4. Starten Sie MySQL.

2
2
2
2019-03-27 11:19:13 +0000

Ich hatte dieses Problem auch. Ich habe ibdata1 versehentlich gelöscht und alle meine Daten waren verloren.

Nach 1-2 Tagen Suche in Google und SO habe ich endlich eine Lösung gefunden, die mir das Leben gerettet hat (ich hatte so viele Datenbanken und Tabellen mit riesigen Datensätzen).

  1. Erstellen Sie ein Backup von /var/lib/mysql

  2. Stellen Sie das Tabellenschema aus der Datei .frm mit dbsake wieder her (es gab noch eine andere Option! mysqlfrm. aber die 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 dem exportierten Schema.

  2. neue Tabellendaten mit diesem Befehl verwerfen:

ALTER TABLE `tbl-new` DISCARD TABLESPACE;
  1. Kopieren Sie die Daten der alten Tabelle und fügen Sie sie anstelle der neuen Tabelle ein und setzen Sie die richtige Berechtigung für sie.
cp tbl.ibd tbl@002dnew.ibd && chown mysql:mysql tbl@002dnew.ibd
  1. Daten in die neue Tabelle importieren.
ALTER TABLE `tbl-new` IMPORT TABLESPACE;
  1. Alles klar! Wir haben Daten in der neuen Tabelle und können die alte Tabelle löschen.
DROP TABLE `tbl`;
  1. prüfen Sie /var/lib/mysql/database-name und wenn es Daten (.ibd Datei) für die alte Tabelle gibt, löschen Sie diese.
rm tbl.ibd
  1. und schließlich die neue Tabelle in den ursprünglichen Namen umbenennen
ALTER TABLE `tbl-new` RENAME `tbl`;