L'une des meilleures façons de convertir MyISAM en InnoDB sans beaucoup de temps d'arrêt n'a qu'une seule condition préalable: utiliser un esclave de réplication.
Voici une vue plongeante du plan
- Créer une configuration maître / esclave de réplication
- Convertissez chaque table MyISAM de l'esclave en InnoDB
- Dirigez votre application vers l'esclave
Cela semble simple? Il y a beaucoup de détails derrière cela.
Créer une configuration maître / esclave de réplication
Il existe un moyen simple de créer un esclave sans trop déranger le maître. J'ai écrit deux articles:
Plutôt que de détailler comment utiliser rsync, veuillez lire ces deux articles.
Convertissez chaque table MyISAM de l'esclave en InnoDB
Sur l'esclave DB, vous pouvez l'instruction SQL suivante:
Pour 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 pour MySQL antérieure à 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');
En utilisant la sortie de la requête, vous disposez d'un script de conversion pour l'esclave.
Vous devez mettre ces deux lignes en haut du script:
SET SQL_LOG_BIN = 0;
STOP SLAVE;
Le script désactivera d'abord la journalisation binaire (si vous avez configuré l'esclave pour avoir des journaux binaires), arrêtera la réplication et convertira chaque table MyISAM en InnoDB.
Voici comment créer ce script et l'exécuter:
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}
Dirigez votre application vers l'esclave
Exécutez des requêtes SELECT depuis l'esclave. Si vous êtes satisfait du contenu des données sur l'esclave, n'hésitez pas à pointer votre application vers l'esclave comme suit:
- Sur l'esclave, exécutez
SHOW SLAVE STATUS\G
et assurez-vous que Seconds_Behind_Master est 0
- Sur l'esclave, mysqldump -h (IP de l'esclave) -u ... -p ... --single-transaction --routines --triggers --all-databases> MySQLBackup.sql (Hé, une sauvegarde serait bien maintenant)
- Sur le maître, exécutez
service mysql stop
(le temps d'arrêt démarre)
- Répétez l'étape 1
- Pointez votre application vers l'esclave (le temps d'arrêt se termine à la première connexion de l'application)
Si vous êtes parvenu à ce point indemne, FÉLICITATIONS !!!
BONUS AJOUTÉ : Si vous configurez la réplication maître / maître (aka réplication circulaire) au lieu de maître / esclave, vous pouvez le faire à la place:
- Sur l'esclave, exécutez
SHOW SLAVE STATUS\G
et assurez-vous que Seconds_Behind_Master est 0
- Sur l'esclave, mysqldump -h (IP de l'esclave) -u ... -p ... --single-transaction --routines --triggers --all-databases> MySQLBackup.sql (Hé, une sauvegarde serait bien maintenant)
- Pointez votre application vers l'esclave (le temps d'arrêt commence et se termine à la première connexion de l'application)
- Sur le nouveau maître, exécutez
STOP SLAVE;
- Sur le nouveau maître, exécutez
CHANGE MASTER TO MASTER_HOST='';
Ce que vous avez maintenant, c'est Master / Slave à l'envers. Le nouveau maître a des données InnoDB et l'ancien maître est maintenant un esclave avec des données MyISAM. Si vous divisez les lectures et les écritures, les lectures peuvent être effectuées à partir de l'esclave (les lectures sont plus rapides à partir de MyISAM qu'InnoDB) et les écritures vont au maître (prise en charge transactionnelle pour InnoDB). Comme Hannah Montana chante, vous obtenez le meilleur des deux mondes (Oui, j'ai deux filles qui aiment le spectacle) !!!
UN AUTRE BONUS AJOUTÉ : Parce que le Master est maintenant InnoDB, vous pouvez faire mysqldump depuis le Master sans temps d'arrêt et sans interférer avec les transactions. Le seul inconvénient est d'augmenter les E / S du processeur et du disque. Vous pouvez donc accéder à un mysqldump de structures de table uniquement sur le maître (InnoDB) et à un mysqldump des données uniquement sur l'esclave (un tel vidage n'aura aucune référence à InnoDB ou MyISAM. Ce ne seront que des données) plus un mysqldump du structures de table pour l'esclave d'avoir la disposition MyISAM.
Les possibilités peuvent continuer grâce à cette nouvelle configuration ...
MISE À JOUR 2011-08-27 19:50 EDT
Mes excuses. Je n'ai pas entièrement lu la question. Vous avez déjà effectué la conversation .
Ce n'est que si vous avez déjà activé la journalisation binaire et que vous disposez d'une sauvegarde préalable que vous pouvez
- restaurer / var / lib / mysql vers un autre emplacement, comme / var / lib / mysql2
- courir
service mysql stop
- courir
service mysql start --datadir=/var/lib/mysql2
- mysqldump la base de données de cette sauvegarde dans /root/olddata.sql
- exécutez mysqlbinlog sur tous les journaux binaires dans / var / lib / mysql (pas / var / lib / mysql2) à partir du point dans le temps depuis la dernière sauvegarde dans /root/changes.sql
- Chargez changes.sql dans mysql (car il pointe toujours vers / var / lib / mysql2)
Cela devrait capturer tout ce qui a été enregistré et la conversion devrait démarrer. Encore une fois, tout cela est contigent si vous avez déjà activé la journalisation binaire avant la dernière sauvegarde . Sinon, mes condoléances.