110 votes

ALTER TABLE sans verrouillage de la table?

Lorsque vous faites une instruction ALTER TABLE dans MySQL, l'ensemble du tableau est verrouillé en lecture pour la durée de l'instruction. Si c'est un grand tableau, cela signifie que d'insérer ou de mettre à jour les déclarations peuvent être verrouillés pour un looooong moment. Est-il un moyen de faire un "alter", comme l'ajout d'une colonne dans une telle manière que la table est toujours mis à jour tout au long du processus?

Surtout, je suis intéressé par une solution de MySQL, mais je serais intéressé par d'autres SGBDR si MySQL ne peut pas le faire.

Pour préciser, mon but est simplement d'éviter les temps d'arrêt lorsqu'une nouvelle fonctionnalité qui nécessite une colonne de la table est poussé à la production. Tout schéma de base de données va changer au fil du temps, c'est juste un fait de vie. Je ne vois pas pourquoi nous devrions accepter que ces changements doivent inévitablement entraîner des temps d'arrêt; c'est tout simplement faible.

63voto

MatBailie Points 37610

La seule autre option est de faire manuellement ce que de nombreux systèmes SGBDR faire de toute façon...
- Créer une nouvelle table

Vous pouvez ensuite copier le contenu de l'ancienne table sur un morceau à la fois. Tout en étant toujours prudent de toutes les INSERT/UPDATE/DELETE sur la table source. (Peut être géré par un déclencheur. Bien que ce serait la cause d'un ralentissement, ce n'est pas un verrou...)

Une fois terminé, changez le nom de la table source, puis modifier le nom de la nouvelle table. De préférence dans une transaction.

Une fois terminé, recompiler toutes les procédures stockées, etc qui utilisent cette table. Les plans d'exécution seront probablement de ne plus être valide.

EDIT:

Certains commentaires ont été faits sur cette limitation étant un peu pauvre. Donc, j'ai pensé mettre une nouvelle perspective sur les choses à montrer pourquoi il est comme ça...

  • L'ajout d'un nouveau champ est comme changer un champ sur chaque ligne.
  • Champ de Serrures serait beaucoup plus difficile que les verrous de Ligne, jamais l'esprit des verrous de table.

  • Vous êtes en train de modifier la structure physique sur le disque, chaque enregistrement se déplace.
  • C'est vraiment comme une mise à JOUR sur l'Ensemble de la table, mais avec plus d'impact...

42voto

SeanDowney Points 5299

Percona fait un outil appelé pt-online-schéma de changement qui permet de le faire.

Il en fait essentiellement une copie de la table et modifie la nouvelle table. Pour garder la nouvelle table en synchronisation avec l'original, il utilise des déclencheurs pour la mise à jour. Cela permet à la table d'origine pour être accessible, tandis que la nouvelle table est préparée dans l'arrière-plan.

Ceci est similaire à Dems méthode proposée ci-dessus, mais ce fait de manière automatisée.

Certains de leurs outils ont une courbe d'apprentissage, à savoir la connexion à la base de données, mais une fois que vous avez cela, ils sont d'excellents outils pour ont.

Ex:

pt-online-schema-change --alter "ADD COLUMN c1 INT" D=db,t=numbers_are_friends

17voto

Steven Soroka Points 8446

Voir Facebook en ligne du schéma de changement de l'outil.

http://www.facebook.com/notes/mysql-at-facebook/online-schema-change-for-mysql/430801045932

Pas pour les faibles de cœur, mais il va faire le travail.

14voto

mikelikespie Points 2560

Je recommande Postgres si c'est une option. Avec postgres il n'y a pratiquement aucun temps d'arrêt avec les procédures suivantes:

Autre grande caractéristique est que la plupart des instructions DDL sont transactionnelles, de sorte que vous pourrait faire toute une migration à l'intérieur d'une transaction SQL, et si quelque chose va mal, toute la chose est annulée.

J'ai écrit cela il y a quelques temps, peut-être qu'il peut faire plus de perspicacité sur le bien-fondé.

7voto

WW. Points 11335

Depuis que vous avez demandé sur d'autres bases de données, voici quelques informations sur Oracle.

L'ajout d'une colonne NULL à une table Oracle est un moyen très rapide d'utilisation, comme cela ne met à jour le dictionnaire de données. Ceci est un verrou exclusif sur la table pour une très courte période de temps. Il sera toutefois invalider toute depedant procédures stockées, vues, triggers, etc. Ces obtiendrez de recompiler automatiquement.

À partir de là, si nécessaire, vous pouvez créer des index de l'aide en LIGNE de la clause. Encore une fois, très peu de données dictionnaire de serrures. Il va lire l'ensemble de la table à la recherche de choses à l'index, mais ne bloque pas la personne tout en faisant cela.

Si vous devez ajouter une clé étrangère, vous pouvez le faire et obtenir de l'Oracle de confiance vous que les données sont correctes. Sinon, il faut lire l'ensemble de la table et de valider toutes les valeurs qui peut être lent (créer votre index en premier).

Si vous avez besoin de mettre une valeur par défaut ou la valeur calculée dans chaque ligne de la nouvelle colonne, vous aurez besoin de lancer une mise à jour massive ou peut-être un petit programme utilitaire qui remplit les nouvelles données. Cela peut être long, surtout si les lignes d'obtenir beaucoup plus grand et ne rentrent plus dans leurs blocs. Le verrouillage peut être géré au cours de ce processus. Depuis l'ancien versino de votre application, qui est toujours en cours d'exécution, ne savent pas à propos de cette colonne, vous pourriez avoir besoin d'un sournois de déclenchement ou de spécifier une valeur par défaut.

À partir de là, vous pouvez faire un switcharoo sur vos serveurs d'application à la nouvelle version du code, et il va continuer à courir. Déposer vos sournois déclencheur.

Alternativement, vous pouvez utiliser DBMS_REDEFINITION qui est une boîte noire conçu pour faire ce genre de chose.

Tout cela est tellement la peine de tester, etc que nous avons juste un dimanche matin panne à chaque fois que la sortie d'une version majeure.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X