Nach der Online-Konvertierung von MyISAM nach InnoDB fehlen Zeilen

16

Wir haben eine ziemlich kleine Datenbank, die wir von MyISAM nach InnoDB konvertieren wollten. Da wir keine Datenbankbenutzer sind, haben wir nur mithilfe von alter table konvertiert, ohne die Site zu entfernen.

Nachdem die Konvertierung abgeschlossen ist, scheinen viele intermittierende Zeilen zu fehlen. Ist dies möglicherweise auf Operationen während der Konvertierung zurückzuführen? Oder liegt das Problem woanders?

Yuvi
quelle
In welchen Tabellen fehlen Zeilen? Die Sie konvertiert oder andere Tabellen?
Longneck

Antworten:

20

Durch Ausführen von ALTER zum Ändern von Speicher-Engines werden Zeilen nicht ausgeblendet. Lassen Sie mich jedoch einige Ratschläge geben, da Sie in Ihrer Frage angegeben haben, dass Sie 'Datenbank-Noobs' sind.

Im Folgenden finden Sie einige grundlegende Ratschläge zum Ändern eines vorhandenen Schemas oder zu Maßnahmen, die sich auf die Daten auswirken können:

  1. Erstellen Sie zuerst eine Sicherungskopie.
  2. Hab einen Änderungsplan.
  3. Testen Sie Ihren Plan auf einem Offline-Host.
  4. Haben Sie einen Testplan zum Vergleichen vor und nach Daten.
  5. Planen Sie und nehmen Sie eine Ausfallzeit.
  6. Erstellen Sie sofort nach Inkrafttreten Ihrer Ausfallzeit ein Backup und einen Snapshot, und stellen Sie sicher, dass der Datenverkehr gestoppt wurde.
  7. Wenn Sie MYISAM ausführen, können Sie mit 'CHECK TABLE' bewerten, womit Sie es zu tun haben, bevor Sie ALTER starten.
  8. Kopieren Sie die Tabelle zusätzlich zu Ihrer Sicherung für alle Fälle lokal.
  9. Fahren Sie mit Vorsicht fort, aktivieren Sie "--show warnings" und andere Ausgaben, damit Sie beim Vornehmen Ihrer Änderungen das vollständige Bild haben.
  10. Wenn die Daten für Sie wichtig sind, mieten Sie einen DBA, auch wenn Sie sich nur während der Migration beraten lassen müssen, damit Sie einen erfahrenen Veteranen an Ihrer Seite haben.

Es gibt wahrscheinlich noch viel mehr, auf das ich mich einlassen könnte, aber das Obige bietet Ihnen Optionen, wenn etwas schief geht.

Was Ihre fehlenden Daten / Zeilen betrifft, gibt es keine Möglichkeit, ohne einen "Vorher / Nachher" -Snapshot zu wissen, der verglichen werden kann. Sie können mit Ihrer letzten Sicherung vergleichen, um zumindest zu überprüfen, ob dies der Fall ist.

randomx
quelle
Ich lese das. Guter DR-Plan. Ihre Antwort erhält +1, weil Sie für die Frage sensibler sind als ich, zusätzlich zu einem Zukunftsplan.
RolandoMySQLDBA
1
@randy Markierte dies als Lieblingsfrage wegen deiner guten Antwort
techExplorer
8

Eine der besten Möglichkeiten, MyISAM ohne viel Ausfallzeit nach InnoDB zu konvertieren, ist nur eine Voraussetzung: Verwenden Sie einen Replication Slave.

Hier ist eine Vogelperspektive des Plans

  1. Replikations-Master / Slave-Setup erstellen
  2. Konvertieren Sie jede MyISAM-Tabelle auf dem Slave in InnoDB
  3. Richten Sie Ihre App auf den Slave

Hört sich einfach an? Dahinter stecken viele Details.

Replikations-Master / Slave-Setup erstellen

Es gibt eine clevere Möglichkeit, einen Slave zu erstellen, ohne den Master zu stören. Ich habe zwei Posts geschrieben:

Lesen Sie diese beiden Beiträge, anstatt zu erläutern, wie Sie rsync verwenden.

Konvertieren Sie jede MyISAM-Tabelle auf dem Slave in InnoDB

Auf dem DB-Slave können Sie die folgende SQL-Anweisung ausführen:

Für MySQL 5.5:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema');

Version für MySQL vor MySQL 5.5

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql');

Mit der Ausgabe der Abfrage haben Sie ein Konvertierungsskript für den Slave.

Sie müssen diese beiden Zeilen oben im Skript einfügen:

SET SQL_LOG_BIN = 0;
STOP SLAVE;

Das Skript deaktiviert zuerst die Binärprotokollierung (wenn Sie den Slave für Binärprotokolle konfiguriert haben), stoppt die Replikation und konvertiert jede MyISAM-Tabelle in InnoDB.

So erstellen Sie das Skript und führen es aus:

SQLSTMT="SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema')"
INNODB_CONV_SCRIPT=MassConvertMyISAMTablesToInnoDB.sql
echo "SET SQL_LOG_BIN = 0;" > ${INNODB_CONV_SCRIPT}
echo "STOP SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Master) -u... -p... --skip-column-names -A -e"${SQL}" >> ${INNODB_CONV_SCRIPT}
echo "START SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Slave) -u... -p... --skip-column-names -A < ${INNODB_CONV_SCRIPT}

Richten Sie Ihre App auf den Slave

Führen Sie SELECT-Abfragen vom Slave aus. Wenn Sie mit dem Dateninhalt auf dem Slave zufrieden sind, können Sie Ihre App wie folgt auf den Slave richten:

  1. Führen Sie auf dem Slave aus, SHOW SLAVE STATUS\Gund stellen Sie sicher, dass Seconds_Behind_Master 0 ist
  2. Auf dem Slave, mysqldump -h (IP des Slaves) -u ... -p ... --single-transaction --routines --triggers --all-databases> MySQLBackup.sql (Hey, ein Backup wäre gut richtig über Jetzt)
  3. Auf dem Master ausführen service mysql stop(Ausfallzeit beginnt)
  4. Wiederholen Sie Schritt 1
  5. Richten Sie Ihre App auf den Slave (Ausfallzeit endet bei der ersten Verbindung der App)

Wenn Sie bis zu diesem Punkt unversehrt gemacht haben, HERZLICHEN GLÜCKWUNSCH !!!

ADDED BONUS : Wenn Sie Master / Master-Replikation (auch als zirkuläre Replikation bezeichnet) anstelle von Master / Slave einrichten , können Sie dies stattdessen tun:

  1. Führen Sie auf dem Slave aus, SHOW SLAVE STATUS\Gund stellen Sie sicher, dass Seconds_Behind_Master 0 ist
  2. Auf dem Slave, mysqldump -h (IP des Slaves) -u ... -p ... --single-transaction --routines --triggers --all-databases> MySQLBackup.sql (Hey, ein Backup wäre gut richtig über Jetzt)
  3. Richten Sie Ihre App auf den Slave (Ausfallzeit beginnt und endet bei der ersten Verbindung der App)
  4. Führen Sie auf dem neuen Master aus STOP SLAVE;
  5. Führen Sie auf dem neuen Master aus CHANGE MASTER TO MASTER_HOST='';

Was Sie jetzt haben, ist Master / Slave in umgekehrter Richtung. Der neue Master verfügt über InnoDB-Daten und der alte Master ist jetzt ein Slave mit MyISAM-Daten. Wenn Sie Lese- und Schreibvorgänge aufteilen, können Lesevorgänge vom Slave (Lesevorgänge von MyISAM sind schneller als von InnoDB) und Schreibvorgänge vom Master (Transaktionsunterstützung für InnoDB) ausgeführt werden. Wie Hannah Montana singt, bekommen Sie das Beste aus beiden Welten (Ja, ich habe zwei Töchter, die die Show lieben) !!!

EIN WEITERER HINZUGEFÜGTER BONUS : Da der Master jetzt InnoDB ist, können Sie vom Master einen Mysqldump ausführen, ohne Ausfallzeiten zu haben und ohne die Transaktionen zu stören. Einziger Nachteil ist die Erhöhung der CPU- und Festplatten-E / A. Sie könnten also einen mysqldump von Tabellenstrukturen nur auf dem Master (InnoDB) und einen mysqldump der Daten nur auf dem Slave (Ein solcher Dump enthält keine Verweise auf InnoDB oder MyISAM. Es handelt sich nur um Daten) plus einen mysqldump des Tabellenstrukturen für den Slave mit dem MyISAM-Layout.

Die Möglichkeiten können durch dieses neue Setup weitergehen ...

UPDATE 2011-08-27 19:50 EDT

Entschuldigen Sie. Ich habe die Frage nicht vollständig gelesen. Sie haben das Gespräch bereits geführt .

Nur wenn Sie bereits die binäre Protokollierung aktiviert hatten und zuvor eine Sicherung durchgeführt haben, können Sie dies tun

  • Stellen Sie / var / lib / mysql an einem anderen Ort wie / var / lib / mysql2 wieder her
  • Lauf service mysql stop
  • Lauf service mysql start --datadir=/var/lib/mysql2
  • mysqldump die Datenbank von dieser Sicherung nach /root/olddata.sql
  • Führen Sie mysqlbinlog für alle Binärprotokolle in / var / lib / mysql (nicht / var / lib / mysql2) ab dem Zeitpunkt seit der letzten Sicherung in /root/changes.sql aus
  • Lade changes.sql in mysql (da es immer noch auf / var / lib / mysql2 zeigt)

Dies sollte alles auffangen, was aufgezeichnet wurde, und die Konvertierung sollte ansetzen. Dies ist wiederum problematisch, wenn Sie vor der letzten Sicherung bereits die binäre Protokollierung aktiviert hatten . Ansonsten mein Beileid.

RolandoMySQLDBA
quelle