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 la modification 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 changements.
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 quand je fais juste un 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 en charge les modifications de schéma" rapides, en direct et sales ")
Quelqu'un vient de suggérer Changement de schéma en ligne pour MySQL à partir du script Facebook (avec un tutoriel ici et la source ici ) ... semble être une belle façon de 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?
Lorsque vous émettez un ALTER TABLE
Dans PostgreSQL il faudra un verrou ACCESS EXCLUSIVE
Qui bloque tout, y compris SELECT
. Cependant, ce verrou peut être assez bref si la table ne nécessite pas de réécriture, aucune nouvelle contrainte UNIQUE
, CHECK
ou FOREIGN KEY
Nécessite des analyses de table complète coûteuses 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 TABLE
S'il 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 disposez de la table t
et que vous souhaitez remplacer la colonne customercode integer NOT NULL
Par text
car le client a décidé que tous les codes client doivent maintenant commencer par un X
, vous pourriez é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 d'écrire dans t
pendant le processus; le nom du verrou EXCLUSIVE
est quelque peu trompeur en ce qu'il exclut tout sauf SELECT
; le mode ACCESS EXCLUSIVE
est le seul qui exclut absolument tout. Voir modes de verrouillage . Il y a un risque que cette opération puisse entraîner un blocage mortel 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 ce verrouillage et faire le tout en direct en créant une fonction de déclenchement sur t
qui chaque fois qu'un INSERT
ou UPDATE
entre, remplit automatiquement customercode_new
de customercode
.
Il existe également des outils intégrés tels que CREATE INDEX CONCURRENTLY
et ALTER TABLE ... ADD table_constraint_using_index
qui sont conçus pour permettre aux administrateurs de base de données de réduire les durées de verrouillage exclusives en effectuant des travaux plus lentement de manière conviviale.
L'outil pg_reorg
ou son successeur pg_repack
peut également être utilisé pour certaines opérations de restructuration de table.
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
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 des 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:
Nous avons utilisé cette approche à plusieurs reprises pour modifier de grandes tables de production en direct sans interruption, sans aucun problème.
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.
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 devoir 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