Des migrations de base de données sans interruption, en cinq étapes

La plupart des pannes liées aux migrations viennent de la même erreur : le schéma et le code changent dans le même déploiement. Pendant quelques secondes, d’anciennes instances tournent sur le nouveau schéma, ou de nouvelles instances sur l’ancien, et des requêtes échouent. La solution : ne jamais laisser les deux dépendre l’un de l’autre au même moment.

Prenons un exemple : renommer users.name en users.full_name sur une table très sollicitée.

Ajouter la nouvelle colonne

Ajoutez la colonne en l’autorisant à être nulle, sans valeur par défaut qui obligerait à réécrire la table. L’opération est rapide et ne bloque pas les écritures.

migrations/001_add_full_name.sql
ALTER TABLE users ADD COLUMN full_name text;

Écrire dans les deux colonnes

Déployez un code qui écrit chaque modification à la fois dans name et dans full_name, mais qui lit toujours name. Anciennes et nouvelles instances peuvent tourner ensemble, car les anciennes ne lisent jamais full_name.

Recopier par lots

Copiez les lignes existantes par petits lots, pour que la recopie ne garde jamais de verrou longtemps et ne sature pas le journal d’écriture.

migrations/002_backfill_full_name.sql
UPDATE users
SET full_name = name
WHERE id IN (
  SELECT id FROM users
  WHERE full_name IS NULL
  LIMIT 5000
);

Exécutez-la en boucle jusqu’à ce qu’elle ne modifie plus aucune ligne. Un workflow durable s’y prête bien, car il peut se mettre en pause et reprendre entre deux lots.

Lire la nouvelle colonne

Une fois la recopie terminée et les deux colonnes identiques, déployez un code qui lit full_name. Continuez à écrire dans les deux colonnes pendant un déploiement de plus, pour pouvoir revenir en arrière sans perte de données.

Supprimer l’ancienne colonne

Quand plus aucune instance ne lit ni n’écrit name, arrêtez d’y écrire, déployez, puis supprimez-la.

Ne supprimez pas la colonne dans le même déploiement

Les instances encore en cours d’arrêt exécutent la version précédente. Si la colonne disparaît avant leur arrêt, leurs requêtes échouent.

migrations/003_drop_name.sql
ALTER TABLE users DROP COLUMN name;

La règle derrière ces étapes

Chaque déploiement doit fonctionner avec le schéma d’avant et avec celui d’après. Tant que cette règle est respectée, l’ordre des déploiements et des migrations n’a plus d’importance, et un retour arrière reste à un clic.

Partager :

Écrit par

Daniel Okafor

Ingénieur principal, Runtime

Daniel travaille sur le runtime et la couche base de données. Daniel écrit sur les démarrages à froid, les migrations et la mesure des performances en production.

Newsletter

Nos notes d'ingénierie, une fois par mois

Les nouveautés marquantes, des analyses de l'équipe plateforme et des guides utilisables le jour même. Sans spam.

gats-fo-lex

Désinscription à tout moment. Consultez notre politique de confidentialité.

Offre gratuite · Sans carte bancaire

Poussez votre code aujourd'hui. En ligne avant que votre café refroidisse.

Connectez un dépôt, choisissez une région et obtenez une URL de production avec HTTPS, logs et autoscaling déjà activés.

$ git push origin main

  1. Build34 s
  2. Déploiement12 s
  3. Contrôles de santé3 s

your-app.example.com

Buy NowTheme Details