web-dev-qa-db-fra.com

Modifier la grande table sans interruption

J'ai une très grande table, appelons-la example, et j'essaie d'exécuter une petite commande alter sur cette table:

ALTER TABLE `example` ADD `example_column` TINYINT(1) NOT NULL DEFAULT 0;

Vérification de la progression de la commande alter:

mysql -e 'show engine innodb status \G' | grep 'undo \| log \| entries'

Donnez-moi de bonnes informations sur le temps - plus ou moins cela prendra 17 jours pour terminer ...

Modifier le blocage de la table, donc bloquer la table de production pendant 17 jours n'est pas une bonne option. ;)

J'essaie d'enquêter sur d'excellents outils sur le net, comme:

  1. Pt-online-schema-change - Percona
  2. gh-ost - Migrations de schémas en ligne de GitHub pour MySQL

J'ai également lu la documentation et la section de limitation des outils ci-dessus:

limitations gh-ost

  • ne prend pas du tout en charge les déclencheurs
  • ne prend pas du tout en charge les clés étrangères

limitations de pt-online-schema-change

  • L'utilisation de déclencheurs signifie que l'outil ne fonctionnera pas si des déclencheurs sont déjà définis sur la table.

  • Ne fournit aucun bon moyen de modifier les tables contenant des clés étrangères

Mon exemple de table a des déclencheurs et des clés étrangères ...

Pourriez-vous me donner quelques conseils, comment gérer ce changement?

J'ai MySQL 5.6. J'utilise la réplication GTID (basée sur les lignes).

Je serai très reconnaissant des conseils!

5
crashoverbike

Vous feriez bien mieux d'exécuter ALTER TABLE comme ceci

ALTER TABLE `example` ADD `example_column` TINYINT(1) DEFAULT NULL,
ALGORITHM=INPLACE, LOCK=NONE;

Quel pourrait être l'avantage? La définition d'une colonne dont la valeur par défaut est NULL ne tentera pas d'augmenter la taille de la ligne. Cela est vrai pour VARCHAR. Honnêtement, je ne suis pas sûr que ce soit vrai pour le numérique. (INT, TINYINT, etc.). Vous devez tester cela (j'ai mentionné le tester il y a 2 ans ( InnoDB permet-il d'ajouter des colonnes à une table avec des lignes de lecture/écriture simultanées? )). Par conséquent, il ne devrait pas y avoir de temps d'arrêt.

L'inconvénient serait de changer votre logiciel pour gérer une colonne numérique NULL.

Si vous vous inquiétez des clés étrangères, désactivez-les au préalable dans votre session

SET foreign_key_checks = 0;
ALTER TABLE `example` ADD `example_column` TINYINT(1) DEFAULT NULL,
ALGORITHM=INPLACE, LOCK=NONE;

Si vous avez des déclencheurs et pouvez vivre sans pendant la durée de la charge, supprimez le déclencheur, faites le ALTER TABLE, et recréez le déclencheur.

CAVEAT: assurez-vous que vous utilisez la dernière version de MySQL 5.6 (au moins 5.6.23) pour éviter les problèmes de clé étrangère avec ALTER TABLE.

Veuillez noter que je n'ai pas mentionné l'utilisation d'outils tiers. C'est juste directement MySQL.

ESSAIE !!!

4
RolandoMySQLDBA

Que diriez-vous de zéro temps d'arrêt, aucun problème avec les déclencheurs ou les FK ou la réplication, etc.?

OK, il y a un hic. Vous seriez en train de créer une autre table pour contenir le PK et les nouvelles colonnes. Et les requêtes qui ont besoin des nouvelles colonnes devraient faire un JOIN. Mais, dans certains cas, ce n'est pas un grave inconvénient.

Et, le JOIN devrait généralement être LEFT JOIN pour que vous obteniez NULL lorsqu'il y a (pas encore) une valeur pour la ou les nouvelles colonnes.

Créez la nouvelle table avec les mêmes colonnes PK que la table d'origine, mais sans AUTO_INCREMENT. Ayez la ou les nouvelles colonnes dans le nouveau tableau.

0
Rick James