Modifier la table des bases de données de production en direct

24

Comment le système de base de données le plus "populaire" (MySQL, Postgres ...) gère-t-il la modification des tables sur les bases de données de production en direct (comme l'ajout, la suppression ou le changement du type de colonnes)?

Je sais que la bonne façon est de sauvegarder tout le temps d'arrêt planifié et de faire ensuite les modifications.

Mais ... un système de base de données actuel prend-il en charge ces opérations "en ligne" sans rien arrêter? (peut-être simplement retarder les requêtes qui font référence à une colonne qui vient d'être modifiée / supprimée)

Et que se passe-t-il lorsque je fais juste une ALTER TABLE...sur une base de données en cours d'exécution? Tout s'arrête-t-il lorsque cela se produit? Les données peuvent-elles être corrompues? etc.

Encore une fois, je me réfère principalement à Postgres ou MySQL car ce sont ce que je rencontre.

(Et, oui, à chaque fois que je devais le faire avant de le faire "de la bonne façon", sauvegarder les choses, planifier le downtine, etc. ... mais je veux juste savoir s'il est possible de faire ce genre de choses "rapidement et sale "ou s'il existe un système de base de données qui prend réellement en charge les modifications de schéma" rapides, en direct et sales ")


Quelqu'un vient de suggérer un changement de schéma en ligne pour MySQL à partir du script Facebook (avec un tutoriel ici et la source ici ) ... semble être une bonne façon d'automatiser un ensemble de façons "hacky" de le faire ... quelqu'un l'a-t-il déjà utilisé dans quelque chose qui ressemble à une production?

NeuronQ
la source
3
Remarque: la "bonne façon" spécifiée est relative à MySQL et non à PostgreSQL. La "bonne façon" dans PostgreSQL est généralement très facile, bien qu'elle puisse être impliquée. L'utilisation de pg_reorgpeut aider dans les scénarios les plus difficiles.
Sean
J'aurais aimé avoir une vidéo détaillée à ce sujet, avec quelqu'un expliquant autant de stratégies que possible.
Sandeepan Nath

Réponses:

22

Lorsque vous émettez un ALTER TABLEdans PostgreSQL, il faudra un ACCESS EXCLUSIVEverrou qui bloque tout, y comprisSELECT . Cependant, ce verrou peut être bref si la table ne nécessite pas ré-écriture, aucune nouvelle UNIQUE, CHECKou les FOREIGN KEYcontraintes ont besoin des analyses coûteuses tables complet pour vérifier, etc.

En cas de doute, vous pouvez généralement l'essayer! Tous les DDL dans PostgreSQL sont transactionnels, il est donc très bien d'annuler un ALTER TABLEsi cela prend trop de temps et commence à suspendre d'autres requêtes. Les niveaux de verrouillage requis par diverses commandes sont documentés dans la page de verrouillage .

Certaines opérations normalement lentes peuvent être accélérées pour être exécutées en toute sécurité sans temps d'arrêt. Par exemple, si vous avez une table tet que vous souhaitez remplacer la colonne customercode integer NOT NULLpar textparce que le client a décidé que tous les codes client doivent maintenant commencer par un X, vous pouvez écrire:

ALTER TABLE t ALTER COLUMN customercode TYPE text USING ( 'X'||customercode::text );

... mais cela verrouillerait toute la table pour la réécriture. Il en va de même pour l'ajout d'une colonne avec un DEFAULT. Cela peut être fait en quelques étapes pour éviter le verrouillage long, mais les applications doivent être capables de faire face à la duplication temporaire:

ALTER TABLE t ADD COLUMN customercode_new text;
BEGIN;
LOCK TABLE t IN EXCLUSIVE MODE;
UPDATE t SET customercode_new = 'X'||customercode::text;
ALTER TABLE t DROP COLUMN customercode;
ALTER TABLE t RENAME COLUMN customercode_new TO customercode;
COMMIT;

Cela empêchera seulement écrit au tcours du processus; le nom de la serrure EXCLUSIVEest quelque peu trompeur en ce qu'il exclut tout saufSELECT ; le ACCESS EXCLUSIVEmode est le seul qui exclut absolument tout. Voir les modes de verrouillage . Il y a un risque que cette opération puisse entraîner un blocage-retour en raison de la mise à niveau du verrou requise par le ALTER TABLE, mais au pire, vous devrez simplement la refaire.

Vous pouvez même éviter que le verrouillage et faire le tout en direct en créant une fonction de déclenchement sur tque chaque fois qu'un INSERTou UPDATEarrive, automatiquement Remplit customercode_newde customercode.

Il existe également des outils intégrés tels que CREATE INDEX CONCURRENTLYet qui ALTER TABLE ... ADD table_constraint_using_indexsont conçus pour permettre aux administrateurs de base de données de réduire les durées de verrouillage exclusives en travaillant plus lentement de manière conviviale.

L' pg_reorgoutil ou son successeur pg_repackpeut également être utilisé pour certaines opérations de restructuration de tables.

Craig Ringer
la source
1
L'essentiel dans ce qu'a dit @Craig était: "si cela ne nécessite pas de réécriture". L'utilisation d'un ALTER TABLE t ADD COLUMN i INTest une opération rapide (généralement <1 ms) une fois le verrou acquis. L'acquisition du verrou peut cependant mettre en file d'attente les connexions, donc ce n'est pas "gratuit" ... bien que ce soit mieux que ce que vous devez faire dans MySQL. Ajouter une NOT NULLcontrainte est plus difficile et pas pour le feint de cœur.
Sean
Il semble que ce pg_repacksoit le meilleur successeur de pg_reorg.
Erwin Brandstetter
Bonne réponse, concernant l'ajout d'une colonne avec une méthode par défaut (ou calculée) moins "bloquante" est de créer une nouvelle table entière, de bloquer l'ancienne table pour insérer / mettre à jour / supprimer mais en autorisant les sélections et en remplissant la nouvelle. Enfin, émettez un bref verrou exclusif sur l'ancienne table pour la sélectionner, supprimez-la et renommez l'ancien en ancien. Selon votre scénario, vous pouvez même commencer à remplir le nouveau sans bloquer les insertions dans l'ancien et émettre ce verrou exclusif juste en résolvant le différentiel (en espérant simplement insérer quelques nouveaux enregistrements)
jean
7

Percona propose son propre outil pour effectuer des modifications de schéma en ligne

L'outil s'appelle pt-online-schema-change

Cela implique des déclencheurs, veuillez donc lire attentivement la documentation.

Selon la documentation, les principales opérations effectuées sont

  • Contrôles de santé mentale
  • Chunking
  • Changement de schéma en ligne
    • Créer et modifier une table temporaire
    • Capturez les modifications de la table vers la table temporaire
    • Copiez des lignes de la table dans la table temporaire
    • Synchroniser la table et la table temporaire
    • Échanger / renommer la table et la table temporaire
    • Nettoyer
RolandoMySQLDBA
la source
merci, semble être une version "soldifiée" de l'approche de Facebook à laquelle je pourrais faire plus confiance ...
NeuronQ
pt-online-schema-change est certainement la façon préférée de le faire si vous utilisez votre propre serveur MySQL. À partir de Percona Tools 2.2, (malheureusement), ils ne prennent pas en charge RDS / Aurora sur AWS. pt-online-schema-change insère un déclencheur sur la table source pour copier les lignes (faible priorité pour MyISAM) dans la destination table_temp et effectue un seul verrouillage rapide et renomme à la fin lorsque toutes les lignes sont synchronisées entre la source et la destination les tables.
phpguru
6

Arrêter le système et effectuer toutes les modifications en même temps peut être très risqué. Si quelque chose ne va pas, et souvent, il n'y a pas de moyen facile de revenir en arrière.

En tant que développeur Agile, j'ai parfois besoin de refactoriser les tables sans aucun temps d'arrêt, car ces tables sont en cours de modification et de lecture.

L'approche suivante présente un faible risque, car le changement se fait en plusieurs étapes à faible risque qui sont très faciles à annuler:

  • Assurez-vous que tous les modules accédant à la table sont bien couverts par des tests automatisés.
  • Créez une nouvelle table. Modifiez toutes les procédures qui modifient l'ancienne table, afin qu'elles modifient à la fois les anciennes et les nouvelles tables.
  • Migrez les données existantes dans une nouvelle structure. Faites-le par petits lots, afin que cela n'affecte pas sérieusement les performances globales du serveur.
  • Vérifiez que la migration des données a réussi.
  • Redirigez certaines des procédures de sélection de l'ancienne table vers les nouvelles. Utilisez des tests automatisés pour vous assurer que les modules modifiés sont toujours corrects. Assurez-vous que leurs performances sont acceptables. Déployez les procédures modifiées.
  • Répétez l'étape précédente jusqu'à ce que tous les rapports utilisent le nouveau tableau.
  • Modifiez les procédures qui modifient les tables afin qu'elles n'accèdent qu'à la nouvelle table.
  • Archivez l'ancienne table et supprimez-la du système.

Nous avons utilisé cette approche à plusieurs reprises pour modifier de grandes tables de production en direct sans interruption, sans aucun problème.

AK
la source
3
génial ... mais c'est exactement le type de "douleur" que je cherche à éviter :)
NeuronQ
@NeuronQ " Il n'y a pas de moyen de revenir en arrière " - il y en a dans Postgres: mettez tout simplement dans une transaction et rollbacksi quelque chose se passe mal.
a_horse_with_no_name
2

Oui, de nombreuses bases de données modernes vous permettront d'ajouter simplement une colonne ou de modifier les caractéristiques d'une colonne, comme l'ajout ou la suppression de nullable.

Si vous supprimez une colonne, les données seront perdues, mais il n'y a pas beaucoup de peur de la corruption.

Marlin Pierce
la source
0

L'outil Percona utilise des déclencheurs pour faciliter sa modification, et il ne fonctionne pas correctement si votre table a déjà des déclencheurs existants. J'ai fini par en écrire un qui gère bien les déclencheurs existants, car ils sont très importants pour notre base de données https://github.com/StirlingMarketingGroup/smg-live-alter

Brian dit de réintégrer Monica
la source
-1

Pour répondre à la question de savoir ce qui se passe avec une ALTER TABLEdéclaration, cela dépend de l'étendue de vos modifications. Dans des cas spécifiques, si vous ajoutez une nouvelle colonne, au moins dans MS SQL Server, le moteur crée une copie temporaire de la table, tandis qu'il crée la nouvelle définition de table, puis insère les données à l'intérieur. Pendant la durée du changement, le tableau serait donc inaccessible aux utilisateurs.

Un exemple des opérations spécifiques pour le serveur MSSQL est ici: http://support.microsoft.com/kb/956176/en-us

Je suppose que d'autres RMDB ont des méthodes similaires, bien que l'implémentation exacte soit quelque chose que vous devrez vérifier avec la documentation du fournisseur.

SchmitzIT
la source
-1 Ceci est complètement faux pour SQL Server: "Si vous ajoutez une nouvelle colonne, au moins dans MS SQL Server, le moteur créera une copie temporaire de la table, tandis qu'il crée la nouvelle définition de table, puis réinsère les données là-dedans "
AK
@AlexKuznetsov - J'ai pensé que la ligne précédente, ainsi que le lien avec certains des cas répertoriés, clarifierait que cela ne se produit pas toujours. J'ai modifié la phrase pour mieux refléter cela.
SchmitzIT
1
Vous mentionnez le comportement de l'interface graphique, SSMS, pas le comportement de SQL Server lui-même. Suite à votre lien, le conseil est d'utiliser directement T-SQL pour effectuer des modifications DDL. SSMS n'est pas un très bon outil pour changer DDL.
AK
@AlexKuznetsov - J'ai lu l'article comme disant qu'il y avait des risques, mais pas comme un découragement. Quoi qu'il en soit, je n'ai pas lié l'article pour le bit GUI, mais comme indication de certaines des opérations qui ont conduit à une instruction ALTER conduisant à la création d'une table temporaire en raison de changements dans la structure de données sous-jacente. Je n'ai pas testé si exactement la même chose s'applique lors de l'émission de l'instruction directement à partir de T-SQL, mais je pense que le processus est assez similaire et que SL Server fait le travail en coulisses.
SchmitzIT
Vous pouvez démarrer Profiler, exécuter directement l'instruction ALTER TABLE et voir ce qui se passe. Ensuite, vous pouvez modifier un tableau via une boîte de dialogue et voir par vous-même les commandes en cours d'exécution.
AK