it-swarm.com.de

So stellen Sie eine InnoDB-Tabelle wieder her, deren Dateien verschoben wurden

Ich habe also einen Test-Datenbankserver, der in einem Replikationsdatenstrom eingerichtet wurde. Über den Namen kam eine Optimierung, die schnell den Platz auf dem Slaves-Datadir ausfüllte. Mysql wartete pflichtbewusst nur auf etwas mehr Platz.

Dieses Datenverzeichnis ist ein Dateisystem, das NUR als Datenverzeichnis von mysql verwendet wird, sodass nichts anderes freigegeben werden konnte.

Ich hatte eine 4-Gig-Innodb-Testtabelle, die nicht Teil des Replikationsstroms war, also dachte ich, ich würde etwas ausprobieren, um zu sehen, ob es funktionieren würde, und als Testumgebung war ich nicht allzu besorgt, wenn die Dinge schrecklich schief gingen.

Hier sind die Schritte, die ich unternommen habe

  1. Spülte den Tisch, den ich gerade bewegen wollte
  2. Platzierte eine Lesesperre darauf (obwohl nichts darauf schrieb und es nicht im Replikationsstrom war)
  3. Kopierte die .frm und .ibd in ein Dateisystem mit etwas freiem Raum
  4. Schaltete den Tisch frei
  5. Diese Tabelle wurde abgeschnitten. Dadurch wurde genügend Speicherplatz frei, damit die Optimierung abgeschlossen werden kann. Die Replikation beginnt erneut mit dem Tuckern.
  6. Stoppen Sie das Slaven/Herunterfahren von MySQL
  7. Kopieren Sie die Datei aus tmp zurück in das Datenverzeichnis
  8. Starten Sie MySQL neu

Im .err-Protokoll wird nichts angezeigt, die Dinge sehen gut aus. Ich verbinde und benutze mydb; und sieh dir den Tisch an, mit dem ich in den Showtabellen rumgespielt habe. Aber wenn ich es versuche

select * from testtable limit 10;

Ich bekomme den Fehler

ERROR 1146 (42S02): Table 'mydb.testtable' doesn't exist

Nach allem, was ich bisher sagen kann, kann ich aus allen anderen Tabellen gut lesen und die Replikation wurde ohne Beschwerden wieder gestartet.

Kann ich irgendetwas tun, um mich von diesem Punkt zu erholen? Ich kann es bei Bedarf von Grund auf neu aufbauen, war aber neugierig, was andere über dieses Unternehmen im Allgemeinen denken. Gab es irgendetwas an der Reihe von Schritten, die ich unternommen habe, die zu fehlerloseren Ergebnissen geführt hätten?

Was wäre, wenn dies kein Testserver wäre, könnte ich es nicht einfach live machen und sehen, was passiert? Was wäre der beste Weg, um vorübergehend Speicherplatz auf einem Produktionssklaven freizugeben, wenn mir das gefallen müsste?

14
atxdba

Das Größte, was die meisten Leute über TRUNCATE TABLE vergessen, ist, dass TRUNCATE TABLE DDL und nicht DML ist. In InnoDB enthalten die Metadaten in ibdata1 eine nummerierte Liste von InnoDB-Tabellen. Bei Verwendung von TRUNCATE TABLE wird die interne Metadaten-ID der InnoDB-Tabelle verschoben. Dies geschieht, weil TRUNCATE TABLE effektiv Folgendes ausführt:

Beispiel: Zum Abschneiden einer InnoDB-Tabelle mit dem Namen mydb.mytb

USE mydb
CREATE TABLE newtb LIKE mytb;
ALTER TABLE mytb RENAME oldtb;
ALTER TABLE newtb RENAME mytb;
DROP TABLE oldtb;

Das neue mytb hätte daher eine andere interne Metadaten-ID.

Wenn Sie die .ibd-Datei an einen anderen Ort kopiert haben, enthält die .ibd die ursprüngliche interne Metadaten-ID. Das einfache Zurücksetzen der .ibd-Datei führt nicht zu einer Abstimmung der internen Metadaten-ID mit der in ibdata1.

Was Sie hätten tun sollen, ist Folgendes:

Kopieren Sie die .ibd-Datei der InnoDB-Tabelle. Führen Sie dann dies aus

ALTER TABLE tablename DISCARD TABLESPACE;

Um es später wieder herzustellen, kopieren Sie die .ibd-Datei zurück in datadir und führen Sie sie aus

ALTER TABLE tablename IMPORT TABLESPACE;

Dies hätte die interne Metadaten-ID beibehalten.

Stellen Sie sicher, dass .frm immer vorhanden ist.

Ich habe einmal einem Kunden geholfen, 30 InnoDB-Tabellen wiederherzustellen, die er auf die gleiche Weise abgespritzt hat. Ich musste einen anderen DB-Server verwenden und einige Spiele mit Hinzufügen und Löschen von InnoDB-Tabellen spielen, um die richtige interne Metadaten-ID zu ermitteln.

Der Kunde hat diesen Artikel gefunden: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Wir haben es benutzt und es hat sehr geholfen. Ich hoffe es hilft dir.

15
RolandoMySQLDBA