Lignes manquantes après la conversion en ligne de MyISAM vers InnoDB

16

Nous avons une base de données relativement petite que nous voulions convertir de MyISAM à InnoDB. En tant que noobs de base de données, nous venons de convertir (en utilisant alter table) sans même supprimer le site.

Maintenant que la conversion est terminée, de nombreuses lignes intermittentes semblent être manquantes. Est-ce peut-être dû à des opérations pendant la conversion? Ou le problème est-il ailleurs?

Yuvi
la source
Quelles tables manquent de lignes? Celles que vous avez converties ou d'autres tables?
longneck

Réponses:

20

Effectuer un ALTER pour changer les moteurs de stockage ne fera pas disparaître les lignes. Cependant, permettez-moi de vous donner quelques conseils puisque vous avez dit que vous étiez des «noobs de base de données» dans votre question.

Lorsque vous modifiez un schéma existant ou faites quoi que ce soit qui pourrait affecter les données, voici quelques conseils de base:

  1. Faites d'abord une sauvegarde.
  2. Ayez un plan de changement.
  3. Testez votre plan sur un hôte hors ligne.
  4. Ayez un plan de test pour comparer les données avant et après.
  5. Planifiez et prenez un temps d'arrêt.
  6. Effectuez une sauvegarde et un instantané immédiatement après l'entrée en vigueur de votre temps d'arrêt et vérifiez que le trafic s'est arrêté.
  7. Si vous exécutez MYISAM, utilisez 'CHECK TABLE' pour évaluer ce que vous traitez avant de MODIFIER.
  8. Copiez la table localement en plus de votre sauvegarde, au cas où.
  9. Continuez avec prudence, activez «--show warnings» et les autres sorties pour avoir une image complète lorsque vous apportez vos modifications.
  10. Si les données sont importantes pour vous, embauchez un administrateur de base de données, ne serait-ce que pour consulter pendant la migration afin d'avoir un vétéran chevronné à vos côtés.

Il y a probablement beaucoup plus que je pourrais aborder, mais ce qui précède vous fournira des options en cas de problème.

En ce qui concerne vos données / lignes manquantes, il n'y a aucun moyen de savoir sans instantané "avant / après" à comparer. Vous pouvez comparer avec votre dernière sauvegarde pour au moins vérifier cela.

randomx
la source
J'ai lu ça. Bon plan DR. Votre réponse obtient +1 pour être plus sensible à la question que moi en plus d'un plan pour l'avenir.
RolandoMySQLDBA
1
@randy A marqué cette question comme favorite en raison de votre bonne réponse
techExplorer
8

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

  1. Créer une configuration maître / esclave de réplication
  2. Convertissez chaque table MyISAM de l'esclave en InnoDB
  3. 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:

  1. Sur l'esclave, exécutez SHOW SLAVE STATUS\Get assurez-vous que Seconds_Behind_Master est 0
  2. 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)
  3. Sur le maître, exécutez service mysql stop(le temps d'arrêt démarre)
  4. Répétez l'étape 1
  5. 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:

  1. Sur l'esclave, exécutez SHOW SLAVE STATUS\Get assurez-vous que Seconds_Behind_Master est 0
  2. 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)
  3. Pointez votre application vers l'esclave (le temps d'arrêt commence et se termine à la première connexion de l'application)
  4. Sur le nouveau maître, exécutez STOP SLAVE;
  5. 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.

RolandoMySQLDBA
la source