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
- Replikations-Master / Slave-Setup erstellen
- Konvertieren Sie jede MyISAM-Tabelle auf dem Slave in InnoDB
- 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:
- Führen Sie auf dem Slave aus,
SHOW SLAVE STATUS\G
und stellen Sie sicher, dass Seconds_Behind_Master 0 ist
- 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)
- Auf dem Master ausführen
service mysql stop
(Ausfallzeit beginnt)
- Wiederholen Sie Schritt 1
- 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:
- Führen Sie auf dem Slave aus,
SHOW SLAVE STATUS\G
und stellen Sie sicher, dass Seconds_Behind_Master 0 ist
- 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)
- Richten Sie Ihre App auf den Slave (Ausfallzeit beginnt und endet bei der ersten Verbindung der App)
- Führen Sie auf dem neuen Master aus
STOP SLAVE;
- 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.