7 min lecture • Guide 366 of 877
Gestion des Migrations de Base de Données
Les migrations de base de données sont la partie la plus risquée du déploiement. Elles touchent aux données, ne peuvent pas toujours être annulées et affectent les applications en cours d'exécution. Une bonne gestion des migrations garde les données en sécurité tout en permettant l'évolution. Une mauvaise gestion mène à des pannes et des pertes de données.
Sécurité des Migrations
| Risque | Mitigation |
|---|---|
| Perte de données | Backups, rollback testé |
| Temps d'arrêt | Patterns zero-downtime |
| Corruption | Tests en staging |
| Performance | Analyse des index |
Bases des Migrations
Contrôle de Version
GESTION DES MIGRATIONS
══════════════════════
VERSIONNÉES:
─────────────────────────────────────
migrations/
├── 001_create_users.sql
├── 002_add_email_to_users.sql
├── 003_create_orders.sql
├── 004_add_index_on_orders.sql
└── Séquentielles, suivies
FICHIER DE MIGRATION:
─────────────────────────────────────
-- Migration: 002_add_email_to_users
-- Créée: 2024-01-15
-- Auteur: developer@example.com
-- Up
ALTER TABLE users ADD COLUMN email VARCHAR(255);
-- Down
ALTER TABLE users DROP COLUMN email;
OUTILS:
─────────────────────────────────────
├── Flyway (migrations SQL)
├── Liquibase (XML/SQL)
├── Laravel Migrations (PHP)
├── Alembic (Python)
├── Knex (Node.js)
├── Rails Migrations (Ruby)
└── Outils spécifiques au framework
EXÉCUTION:
─────────────────────────────────────
├── Exécuter migrations en attente
├── Suivre migrations exécutées
├── Ne jamais modifier migrations exécutées
├── Nouveaux changements = nouvelle migration
└── Historique immuable
Patterns Zero-Downtime
Changements Sûrs
MIGRATIONS ZERO-DOWNTIME
════════════════════════
OPÉRATIONS SÛRES:
─────────────────────────────────────
Toujours sûres:
├── Ajouter nouvelle table
├── Ajouter colonne nullable
├── Ajouter index (concurrent)
├── Ajouter colonne avec défaut
└── Changements additifs
OPÉRATIONS DANGEREUSES:
─────────────────────────────────────
Nécessitent gestion attentive:
├── Supprimer colonne
├── Renommer colonne
├── Changer type de colonne
├── Ajouter contrainte NOT NULL
├── Nécessitent approche multi-étapes
└── Jamais en une seule migration
PATTERN RENOMMAGE DE COLONNE:
─────────────────────────────────────
Objectif: Renommer 'name' en 'full_name'
Étape 1: Ajouter nouvelle colonne
ALTER TABLE users ADD COLUMN full_name VARCHAR(255);
Étape 2: Déployer code qui écrit dans les deux
old_column et new_column
Étape 3: Remplir les données
UPDATE users SET full_name = name WHERE full_name IS NULL;
Étape 4: Déployer code qui lit depuis new_column
Étape 5: Arrêter d'écrire dans ancienne colonne
Étape 6: Supprimer ancienne colonne (plus tard)
ALTER TABLE users DROP COLUMN name;
Timeline:
├── Migration 1 (ajouter colonne)
├── Déploiement 1 (écrire deux)
├── Migration 2 (remplir)
├── Déploiement 2 (lire nouveau)
├── Déploiement 3 (écrire nouveau seulement)
├── Migration 3 (supprimer ancien)
└── Plusieurs déploiements, changement sûr
AJOUTER NOT NULL:
─────────────────────────────────────
Objectif: Rendre email requis
Étape 1: Ajouter colonne nullable
ALTER TABLE users ADD COLUMN email VARCHAR(255);
Étape 2: Déployer code exigeant email
Étape 3: Remplir lignes existantes
UPDATE users SET email = 'unknown@example.com'
WHERE email IS NULL;
Étape 4: Ajouter contrainte
ALTER TABLE users
ALTER COLUMN email SET NOT NULL;
Tester les Migrations
Avant la Production
TESTS DE MIGRATION
══════════════════
TESTS EN STAGING:
─────────────────────────────────────
Exigences:
├── Volume de données similaire production
├── Patterns de données réalistes
├── Même version de base de données
├── Tester temps de migration
├── Tester rollback
└── Simulation production
CHECKLIST:
─────────────────────────────────────
Avant production:
├── ☐ Testé en staging
├── ☐ Temps de migration acceptable
├── ☐ Rollback testé
├── ☐ Backup effectué
├── ☐ Fenêtre de maintenance si nécessaire
├── ☐ Équipe en standby
└── Prêt à exécuter
TESTS DE PERFORMANCE:
─────────────────────────────────────
Pour grandes tables:
├── Estimer temps de migration
├── Tester sur données taille production
├── Vérifier durée des locks
├── Planifier pour taille de table
├── Considérer batching
└── Pas de surprises
EXEMPLE:
─────────────────────────────────────
Table: orders (50M lignes)
Résultats tests:
├── Ajout colonne: 45 secondes
├── Remplissage: 15 minutes (batché)
├── Ajout index: 3 minutes (concurrent)
├── Total: 20 minutes
├── Plan: Fenêtre faible trafic
└── Préparé
Stratégie de Rollback
Plan de Récupération
STRATÉGIE DE ROLLBACK
═════════════════════
MIGRATIONS RÉVERSIBLES:
─────────────────────────────────────
Écrire migration down:
-- Up
ALTER TABLE users ADD COLUMN email VARCHAR(255);
-- Down
ALTER TABLE users DROP COLUMN email;
├── Chaque migration a son inverse
├── Testé en staging
├── Une commande pour annuler
└── Rollback facile
NON-RÉVERSIBLES:
─────────────────────────────────────
Certaines migrations ne peuvent pas s'inverser:
├── DROP COLUMN (données parties)
├── Tronquer données
├── Changements de type avec perte de données
├── Nécessitent restauration backup
└── Gestion spéciale
POUR NON-RÉVERSIBLES:
─────────────────────────────────────
├── Documenter explicitement
├── Backup avant exécution
├── Tester procédure de restauration
├── Script rollback manuel
├── Prudence supplémentaire
└── Plan B prêt
STRATÉGIE DE BACKUP:
─────────────────────────────────────
Avant migration:
├── Backup complet ou snapshot
├── Vérifier que backup fonctionne
├── Connaître temps de restauration
├── Procédure restauration documentée
├── Récupération point-in-time activée
└── Filet de sécurité
Migrations de Grandes Tables
Gérer l'Échelle
MIGRATIONS GRANDES TABLES
═════════════════════════
PROBLÈMES:
─────────────────────────────────────
Grandes tables:
├── Longs temps de lock
├── Opérations lentes
├── Lag de réplication
├── Timeouts de connexion
├── Nécessitent gestion spéciale
└── Impossible de faire simple ALTER
BATCHING:
─────────────────────────────────────
Remplir par lots:
DO $$
DECLARE
batch_size INT := 10000;
last_id INT := 0;
BEGIN
LOOP
UPDATE users
SET full_name = name
WHERE id > last_id
AND id <= last_id + batch_size
AND full_name IS NULL;
IF NOT FOUND THEN EXIT; END IF;
last_id := last_id + batch_size;
COMMIT;
PERFORM pg_sleep(0.1); -- Throttle
END LOOP;
END $$;
├── Traiter par chunks
├── Commit entre lots
├── Permettre réplication de rattraper
├── Réduire durée des locks
└── Exécution contrôlée
CHANGEMENTS SCHÉMA ONLINE:
─────────────────────────────────────
Outils:
├── pt-online-schema-change (MySQL)
├── gh-ost (MySQL)
├── pg_repack (PostgreSQL)
├── Changements sans lock
└── Production-safe
INDEX CONCURRENT:
─────────────────────────────────────
PostgreSQL:
CREATE INDEX CONCURRENTLY idx_users_email
ON users(email);
├── Ne lock pas la table
├── Prend plus longtemps
├── Peut échouer (réessayer)
├── Production-safe
└── Utiliser pour grandes tables
Intégration GitScrum
Suivre les Migrations
GITSCRUM POUR MIGRATIONS
════════════════════════
TÂCHES DE MIGRATION:
─────────────────────────────────────
├── Label: database, migration
├── Liée à la fonctionnalité
├── Checklist pour les étapes
├── Coordination du déploiement
└── Suivi visible
EXEMPLE DE TÂCHE:
─────────────────────────────────────
Tâche: "Ajouter colonne email aux users"
Checklist:
├── ☐ Écrire migration
├── ☐ Écrire rollback
├── ☐ Tester en staging
├── ☐ Timer migration sur données taille prod
├── ☐ Backup production
├── ☐ Exécuter migration
├── ☐ Vérifier succès
└── Processus complet
RUNBOOK:
─────────────────────────────────────
NoteVault:
├── Runbook migration
├── Procédures communes
├── Procédures rollback
├── Contacts urgence
└── Processus documenté
Meilleures Pratiques
Pour les Migrations
- Contrôle de version — Toutes migrations suivies
- Patterns zero-downtime — Changements multi-étapes
- Tester minutieusement — Staging avec vraies données
- Toujours avoir rollback — Migrations down
- Backup d'abord — Filet de sécurité
Anti-Patterns
ERREURS DE MIGRATION:
✗ Migrations non testées
✗ Pas de plan de rollback
✗ Renommer en une seule étape
✗ Supprimer colonne avec DROP direct
✗ Longs locks en production
✗ Pas de backups
✗ Modifier migrations exécutées
✗ Supposer que ça va marcher