Aller au contenu principal

Processus de Migration Amélioré - Aaperture

Ce document décrit le processus amélioré de gestion des migrations de base de données avec validation, backup automatique, logging et rollback.

📋 Vue d'ensemble

Le système de migration amélioré fournit :

  • Validation automatique des migrations avant exécution
  • Backup automatique avant migration en production
  • Logging complet de toutes les migrations (statut, durée, erreurs)
  • Rollback automatique en cas d'échec
  • Monitoring des migrations (durée, taux de succès)
  • Vérification de l'ordre des migrations

🏗️ Architecture

Table migration_logs

Toutes les migrations sont enregistrées dans la table migration_logs :

CREATE TABLE migration_logs (
id UUID PRIMARY KEY,
changeset_id TEXT NOT NULL, -- ID du changeset Liquibase
author TEXT NOT NULL, -- Auteur de la migration
filename TEXT NOT NULL, -- Nom du fichier de migration
status TEXT NOT NULL, -- 'in_progress', 'completed', 'failed', 'rolled_back'
error_message TEXT, -- Message d'erreur si échec
duration_ms INTEGER, -- Durée en millisecondes
backup_file TEXT, -- Fichier de backup créé avant migration
executed_at TIMESTAMPTZ, -- Date d'exécution
rolled_back_at TIMESTAMPTZ, -- Date de rollback (si applicable)
executed_by TEXT, -- Qui/quoi a exécuté la migration
metadata JSONB, -- Métadonnées supplémentaires
created_at TIMESTAMPTZ
);

Scripts de migration

migrate-improved.sh (recommandé)

Script amélioré avec toutes les fonctionnalités :

ENVIRONMENT=production ./infra/migrate-improved.sh

Fonctionnalités :

  • ✅ Validation automatique
  • ✅ Backup avant migration (production uniquement)
  • ✅ Logging dans migration_logs
  • ✅ Rollback automatique en cas d'échec
  • ✅ Monitoring et reporting

Note : Le script migrate.sh basique existe toujours mais est déprécié. Utilisez migrate-improved.sh pour toutes les migrations.

📝 Processus de migration

1. Création d'une migration

# Créer un nouveau dossier de migration
mkdir -p infra/liquibase/changes/0113_ma_nouvelle_migration

# Créer up.sql
cat > infra/liquibase/changes/0113_ma_nouvelle_migration/up.sql << EOF
-- Description de la migration
CREATE TABLE IF NOT EXISTS ma_table (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
EOF

# Créer down.sql
cat > infra/liquibase/changes/0113_ma_nouvelle_migration/down.sql << EOF
-- Rollback de la migration
DROP TABLE IF EXISTS ma_table;
EOF

2. Ajout au changelog

Ajouter l'entrée dans infra/liquibase/changelog-master.yaml :

- changeSet:
id: 0113-ma-nouvelle-migration
author: aaperture
changes:
- sqlFile:
path: changes/0113_ma_nouvelle_migration/up.sql
relativeToChangelogFile: true
splitStatements: false
rollback:
- sqlFile:
path: changes/0113_ma_nouvelle_migration/down.sql
relativeToChangelogFile: true
splitStatements: false

3. Validation locale

# Valider la syntaxe SQL
cd infra
docker compose run --rm liquibase validate

# Ou utiliser le script amélioré
ENVIRONMENT=development ./migrate-improved.sh

4. Test sur staging

# Sur environnement de staging
ENVIRONMENT=staging ./infra/migrate-improved.sh

5. Migration en production

Le script amélioré s'exécute automatiquement dans le pipeline CI/CD :

# Dans .gitlab-ci.yml
ENVIRONMENT=production ./infra/migrate-improved.sh

Processus automatique :

  1. ✅ Validation des migrations
  2. ✅ Vérification de l'ordre
  3. ✅ Backup automatique de la DB
  4. ✅ Exécution des migrations
  5. ✅ Logging dans migration_logs
  6. ✅ Rollback automatique en cas d'échec

🔍 Monitoring

Requêtes SQL utiles

Dernière migration

SELECT * FROM migration_logs
ORDER BY executed_at DESC
LIMIT 1;

Migrations échouées

SELECT * FROM migration_logs
WHERE status = 'failed'
ORDER BY executed_at DESC;

Statistiques des migrations

SELECT
status,
COUNT(*) as count,
AVG(duration_ms) as avg_duration_ms,
MAX(executed_at) as last_execution
FROM migration_logs
GROUP BY status;

Migrations récentes

SELECT
changeset_id,
author,
status,
duration_ms,
executed_at,
error_message
FROM migration_logs
WHERE executed_at > NOW() - INTERVAL '7 days'
ORDER BY executed_at DESC;

🚨 Gestion des erreurs

Rollback automatique

Si une migration échoue, le script tente automatiquement un rollback :

  1. Détection de l'échec
  2. Tentative de rollback automatique
  3. Mise à jour du statut dans migration_logs
  4. Notification (si configuré)

Rollback manuel

Si le rollback automatique échoue :

# Rollback d'une migration
cd infra
docker compose run --rm liquibase rollbackCount 1

# Rollback jusqu'à un tag spécifique
docker compose run --rm liquibase rollback tag_name

Restauration depuis backup

Si une migration cause des problèmes :

  1. Identifier le backup créé avant la migration :

    SELECT backup_file FROM migration_logs
    WHERE executed_at = '2024-01-01 10:00:00';
  2. Restaurer le backup :

    gunzip -c /path/to/backup/postgres-2024-01-01T10-00-00.sql.gz | \
    psql -h localhost -U postgres -d aaperture
  3. Marquer la migration comme rollback :

    UPDATE migration_logs
    SET status = 'rolled_back', rolled_back_at = NOW()
    WHERE id = 'migration-id';

📊 Bonnes pratiques

1. Toujours créer un down.sql

Chaque migration doit avoir un fichier de rollback :

-- up.sql
CREATE TABLE ma_table (...);

-- down.sql
DROP TABLE IF EXISTS ma_table;

2. Tester localement avant de commiter

# Créer une DB de test
createdb aaperture_test

# Tester la migration
ENVIRONMENT=development ./infra/migrate-improved.sh

3. Vérifier les dépendances

Assurez-vous que les migrations sont dans le bon ordre dans changelog-master.yaml.

4. Documenter les migrations complexes

Ajoutez des commentaires dans les fichiers SQL :

-- Migration: 0113-ma-nouvelle-migration
-- Description: Crée la table ma_table pour stocker...
-- Dependencies: Nécessite la migration 0112-create-migration-logs
-- Breaking changes: Aucun

5. Ne jamais modifier une migration déjà appliquée

Si une migration a été appliquée en production, créez une nouvelle migration pour corriger.

🔧 Configuration

Variables d'environnement

# Environnement (development, staging, production)
ENVIRONMENT=production

# Credentials DB (chargés depuis .env)
POSTGRES_DB=aaperture
POSTGRES_USER=postgres
POSTGRES_PASSWORD=secret

# Image Liquibase (définie dans CI/CD)
CI_REGISTRY_IMAGE=registry.gitlab.com/namespace/project
CI_COMMIT_SHORT_SHA=abc123

# Timeout pour migrations (seconds, défaut: 600 = 10 minutes)
MIGRATION_TIMEOUT=600

Note: Le script migrate-improved.sh applique automatiquement un timeout configurable via MIGRATION_TIMEOUT. Voir TIMEOUT_MANAGEMENT.md pour plus d'informations.

Intégration CI/CD

Le script amélioré est appelé automatiquement dans .gitlab-ci.yml :

# 4) Migrations
- |
ssh "$SERVER_USER@$SERVER_HOST" "\
set -eo pipefail; \
export APP_DIR='$APP_DIR'; \
export ENVIRONMENT='production'; \
export CI_REGISTRY='$CI_REGISTRY' CI_REGISTRY_IMAGE='$CI_REGISTRY_IMAGE' CI_COMMIT_SHORT_SHA='$CI_COMMIT_SHORT_SHA'; \
bash '$APP_DIR/infra/migrate-improved.sh'"

📈 Améliorations futures

  • Interface admin pour visualiser les migrations
  • Alertes automatiques en cas d'échec
  • Tests automatisés de migration dans CI/CD
  • Validation plus poussée (détection de migrations manquantes)
  • Dashboard de monitoring des migrations
  • Intégration avec le système de backup pour restaurer automatiquement

🔗 Références