[2017] Mise à jour: MySQL 5.6 prend en charge les mises à jour d'index en ligne
https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html#online-ddl-index-syntax-notes
Dans MySQL 5.6 et versions ultérieures, la table reste disponible pour les opérations de lecture et d'écriture pendant la création ou la suppression de l'index. L'instruction CREATE INDEX ou DROP INDEX ne se termine qu'après que toutes les transactions qui accèdent à la table sont terminées, de sorte que l'état initial de l'index reflète le contenu le plus récent de la table. Auparavant, la modification de la table pendant la création ou la suppression d'un index entraînait généralement un blocage qui annulait l'instruction INSERT, UPDATE ou DELETE sur la table.
[2015] La mise à jour de la table indique les écritures de blocs dans MySQL 5.5
D'après la réponse ci-dessus:
"Si vous utilisez une version supérieure à 5.1, les index sont créés alors que la base de données est en ligne. Ne vous inquiétez donc pas, vous n'interrompez pas l'utilisation du système de production."
C'est **** FALSE **** (du moins pour les tables MyISAM / InnoDB, ce que 99,999% des gens utilisent. L'édition en cluster est différente.)
Faire des opérations UPDATE sur une table bloquera pendant la création de l'index. MySQL est vraiment, vraiment stupide à ce sujet (et quelques autres choses).
Script de test:
(
for n in {1..50}; do
#(time mysql -uroot -e 'select * from website_development.users where id = 41225\G'>/dev/null) 2>&1 | grep real;
(time mysql -uroot -e 'update website_development.users set bio="" where id = 41225\G'>/dev/null) 2>&1 | grep real;
done
) | cat -n &
PID=$!
sleep 0.05
echo "Index Update - START"
mysql -uroot website_development -e 'alter table users add index ddopsonfu (last_name, email, first_name, confirmation_token, current_sign_in_ip);'
echo "Index Update - FINISH"
sleep 0.05
kill $PID
time mysql -uroot website_development -e 'drop index ddopsonfu on users;'
Mon serveur (InnoDB):
Server version: 5.5.25a Source distribution
Sortie (notez comment la 6ème opération se bloque pendant les ~ 400 ms nécessaires pour terminer la mise à jour de l'index):
1 real 0m0.009s
2 real 0m0.009s
3 real 0m0.009s
4 real 0m0.012s
5 real 0m0.009s
Index Update - START
Index Update - FINISH
6 real 0m0.388s
7 real 0m0.009s
8 real 0m0.009s
9 real 0m0.009s
10 real 0m0.009s
11 real 0m0.009s
Vs lire les opérations qui ne bloquent pas (permuter le commentaire de ligne dans le script):
1 real 0m0.010s
2 real 0m0.009s
3 real 0m0.009s
4 real 0m0.010s
5 real 0m0.009s
Index Update - START
6 real 0m0.010s
7 real 0m0.010s
8 real 0m0.011s
9 real 0m0.010s
...
41 real 0m0.009s
42 real 0m0.010s
43 real 0m0.009s
Index Update - FINISH
44 real 0m0.012s
45 real 0m0.009s
46 real 0m0.009s
47 real 0m0.010s
48 real 0m0.009s
Mettre à jour le schéma de MySQL sans temps d'arrêt
Ainsi, je ne connais qu'une seule méthode pour mettre à jour un schéma MySql et ne pas subir de panne de disponibilité. Maîtres circulaires:
- Master A a votre base de données MySQL en cours d'exécution
- Mettez le maître B en service et faites-le répliquer les écritures du maître A (B est un esclave de A)
- Effectuez la mise à jour du schéma sur Master B.Il prendra du retard lors de la mise à niveau
- Laissez Maître B vous rattraper. Invariant: votre changement de schéma DOIT être capable de traiter les commandes répliquées à partir d'un schéma de downversion. Les changements d'indexation sont éligibles. Les ajouts de colonnes simples sont généralement admissibles. Supprimer une colonne? probablement pas.
- Échanger ATOMIQUEMENT tous les clients du maître A au maître B.Si vous voulez être en sécurité (faites-moi confiance, vous le faites), vous devez vous assurer que la dernière écriture sur A est répliquée sur B AVANTB prend sa première écriture. Si vous autorisez des écritures simultanées vers plus de 2 maîtres, ... vous comprendrez mieux la réplication MySQL à un niveau DEEP ou vous vous dirigez vers un monde de douleur. Douleur extrême. Comme, avez-vous une colonne qui est AUTOINCREMENT ??? vous êtes foutu (sauf si vous utilisez des nombres pairs sur un maître et des cotes sur l'autre). Ne faites PAS confiance à la réplication MySQL pour "faire ce qu'il faut". Ce n'est PAS intelligent et ne vous sauvera pas. C'est juste un peu moins sûr que de copier les journaux de transactions binaires à partir de la ligne de commande et de les relire à la main. Néanmoins, déconnecter tous les clients de l'ancien maître et les basculer vers le nouveau maître peut être effectué en quelques secondes, beaucoup plus rapidement que d'attendre une mise à niveau du schéma de plusieurs heures.
- Maintenant, Master B est votre nouveau maître. Vous avez le nouveau schéma. La vie est belle. Prenez une bière; le pire est passé.
- Répétez le processus avec le maître A, en mettant à niveau son schéma afin qu'il devienne votre nouveau maître secondaire, prêt à prendre le relais au cas où votre maître principal (maître B maintenant) perdrait le pouvoir ou tout simplement en place et mourrait sur vous.
Ce n'est pas un moyen simple de mettre à jour le schéma. Réalisable dans un environnement de production sérieux; Oui, ça l'est. S'il vous plaît, s'il vous plaît, s'il existe un moyen plus simple d'ajouter un index à une table MySQL sans bloquer les écritures, faites le moi savoir.
Googler m'amène à cet article qui décrit une technique similaire. Mieux encore, ils conseillent de boire au même moment de la procédure (notez que j'ai écrit ma réponse avant de lire l'article)!
Changement de schéma pt-en-ligne de Percona
L' article que j'ai lié ci-dessus parle d'un outil, pt-online-schema-change , qui fonctionne comme suit:
- Créez une nouvelle table avec la même structure que l'original.
- Mettre à jour le schéma sur une nouvelle table.
- Ajouter un déclencheur sur la table d'origine afin que les modifications soient synchronisées avec la copie
- Copiez les lignes par lots de la table d'origine.
- Retirez la table d'origine et remplacez-la par une nouvelle table.
- Déposez l'ancienne table.
Je n'ai jamais essayé l'outil moi-même. YMMV
RDS
J'utilise actuellement MySQL via le RDS d'Amazon . C'est un service vraiment astucieux qui encapsule et gère MySQL, vous permettant d'ajouter de nouvelles répliques en lecture avec un seul bouton et de mettre à niveau de manière transparente la base de données à travers les SKU matériels. C'est vraiment pratique. Vous n'obtenez pas un accès SUPER à la base de données, vous ne pouvez donc pas visser directement avec la réplication (est-ce une bénédiction ou une malédiction?). Cependant, vous pouvez utiliser la promotion de réplique en lecture pour apporter des modifications de schéma sur un esclave en lecture seule, puis promouvoir cet esclave pour qu'il devienne votre nouveau maître. Exactement la même astuce que j'ai décrite ci-dessus, juste beaucoup plus facile à exécuter. Ils ne font toujours pas grand-chose pour vous aider avec la transition. Vous devez reconfigurer et redémarrer votre application.