Communitygithub.com

lguidolin/migrations-sans-temps-mort

À utiliser lors de modifications de schéma de base de données où les données doivent survivre au changement : ajout/suppression/renommage de colonnes, contraintes, index ou remblayage. Symptômes : une migration destructive couplée à un déploiement de code, une colonne NOT NULL avec remblayage, un UPDATE verrouillant la table, ou un renommage. Mots-clés : expand/contract, changement parallèle, remblayage, NOT VALID, CREATE INDEX CONCURRENTLY, graphile-migrate.

Qu'est-ce que migrations-sans-temps-mort ?

Cette compétence, 'Zero-Downtime Migrations' (Migrations sans temps mort), fournit une discipline de modification de schéma pour les ingénieurs backend qui déploient des modifications de base de données sans interrompre un système en production. Elle est conçue pour des plateformes comme Postgres, en s'intégrant à des outils comme graphile-migrate, et garantit que le schéma reste compatible avec les versions anciennes et nouvelles de l'application lors d'un déploiement progressif. Le guide explique en détail la stratégie Expand/Contract (changement parallèle) qui répartit une modification en trois versions distinctes — ajout additif de la nouvelle structure, remplissage progressif par lots, puis suppression des composants obsolètes — afin d'éviter les temps d'arrêt. Il couvre également les pièges courants de Postgres (colonnes NOT NULL, contraintes, index simultanés, temps d'attente) et les règles pour rédiger des migrations idempotentes en développement tout en maintenant des migrations immuables en production. Cette compétence est utile car la plupart des ingénieurs provoquent par inadvertance des pannes en combinant des migrations destructives avec le déploiement qui en a besoin.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/lguidolin/agent-skills/tree/main/skills/zero-downtime-migrations

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Migrations sans temps mort

Vue d'ensemble

Discipline de modification de schéma qui maintient un système en fonctionnement lors d'un déploiement progressif. Durant un déploiement, les anciens pods et les nouveaux pods partagent une seule base de données — le schéma doit donc être compatible avec les deux versions de l'application en même temps. Combiner une migration destructive avec le déploiement qui en a besoin est l'arrêt de service classique auto-infligé.

Règles de rédaction (tous les projets)

  • Deux types de migrations, bien distincts : l'ensemble idempotent current/ (itération en développement — réexécuté à chaque cycle, CREATE OR REPLACE / IF NOT EXISTS, objets sous forme finale, pas de ALTER après création) et les migrations committed (immuables, ordonnées, ce qui est réellement livré). ALTER DEFAULT PRIVILEGES est le seul ALTER accepté en ligne.
  • La propriété vient de la manière dont les migrations sont exécutées, pas de ALTER ... OWNER dispersés.
  • Une seule source de vérité d'amorçage partagée par le chemin d'initialisation local/Docker et la DB de test/ombre — chaque environnement construit à l'identique.

Expand/Contract (Changement parallèle)

S'applique quand : la base de données contient des données qui doivent survivre au déploiement (staging-avec-données, production). Exempt : projets locaux/amicaux à la réinitialisation — mais écrivez les migrations commited comme si cela s'appliquait, afin qu'une promotion ne soit jamais une réécriture.

Une modification de schéma est répartie sur trois versions, jamais une seule :

  1. Expand — ajoutez la nouvelle forme additivement, de manière rétrocompatible : nouvelle colonne nullable, nouvelle table, nouvelle fonction. La version d'application N continue de fonctionner sans changement.
  2. Migrate — remblayez par lots limités (jamais un seul UPDATE verrouillant la table) ; double écriture depuis l'application N+1 si nécessaire ; basculez les lectures vers la nouvelle forme. Ce n'est qu'à ce moment qu'il faut ajouter NOT NULL (ajoutez la contrainte NOT VALID, puis VALIDATE séparément).
  3. Contract — uniquement après que l'application N soit complètement retirée, supprimez l'ancienne colonne/contrainte dans une version ultérieure.

Pièges Postgres

PiègeApproche sûre
Colonne NOT NULL avec valeur par défaut volatile/gros remblayageAjoutez nullable → remblayez par lots → ajoutez la contrainte NOT VALID → VALIDATE
Ajout d'une contrainteAjoutez NOT VALID d'abord, puis VALIDATE CONSTRAINT (verrou plus faible)
Construction d'un indexCREATE INDEX CONCURRENTLY — ne peut pas être exécuté dans une transaction ; isolez de l'encapsulation transactionnelle de l'outil de migration
Une migration bloquée figeant la productionDéfinissez lock_timeout / statement_timeout pour qu'elle échoue rapidement
Renommer une colonneC'est un expand/contract : ajoutez la nouvelle → remblayez → basculez les lectures → supprimez l'ancienne, réparti sur plusieurs versions

Pourquoi "CREATE OR REPLACE sous forme finale" ne suffit pas en production

Cette règle est une ergonomie pour développeurs et est correcte en développement. En production, avec des utilisateurs réels et un déploiement progressif, les deux versions de l'application partagent le schéma pendant toute la durée du déploiement — donc expand/contract est ce qui rend le changement sûr. Ne confondez pas les deux.

Justification complète : Article XVII de la constitution, regroupé dans engineering-constitution/references/engineering-constitution.md. Pipeline de déploiement : cloud-delivery-aks.

Individual skills in this repo

This repo contains 18 individual skills — each has its own dedicated page.

lguidolin/change-hygiene-and-code-craft

Use when writing or refactoring code, structuring a commit or PR, or deciding whether to abstract duplication. Symptoms — mixing reorg with logic changes, a PR doing several things at once, a file growing large, the second copy of similar code, or unsure whether to DRY something up.

lguidolin/cloud-delivery-aks

Use when deploying to Kubernetes or Azure Kubernetes Service (AKS), configuring cloud secrets, setting up progressive rollout/canary, per-PR ephemeral environments, or k8s health probes. Keywords — Kubernetes, AKS, Key Vault, Argo Rollouts, Flagger, canary, blue-green, liveness, readiness, PodDisruptionBudget, HPA, rollback, GHCR.

lguidolin/commit-history-rewrite

Use when an existing repository has messy commit history that needs to conform to conventional commits before adopting release-please, or when intermediate WIP/fixup/merge commits need to be cleaned up.

lguidolin/conventional-commits-and-releases

Use when committing, writing a commit message, opening a PR that will be squash-merged, or configuring automated versioning/changelogs. Keywords — conventional commits, release-please, semver, feat/fix/chore, breaking change, changelog.

lguidolin/defense-in-depth-security

Use when handling untrusted input, secrets, authentication/authorization, or dependencies — or threat-modeling a new surface. Keywords — STRIDE, threat model, least privilege, secrets management, supply chain, dependency scanning, input validation, audit log, defense in depth.

lguidolin/designing-before-building

Use when starting a feature, fixing a non-trivial bug, or about to write implementation code — before any code exists. Symptoms you need this: "this is simple, I'll just code it", reaching for the editor before a design is approved, or an idea that hasn't been turned into a spec and plan.

lguidolin/engineering-constitution

Use when starting work in a project that follows the engineering constitution, orienting to its rules, or deciding which engineering practice applies to a task — spec writing, commits, testing, security, deploys, database, or UI work.

lguidolin/graphql-contract-testing

Use when writing a GraphQL query/mutation that the UI and a test will share, or building route/schema contract or smoke tests. Symptoms — copying a query into a test, a test asserting on query text, schema change that didn't break the UI build, or RLS/permission drift. Keywords — graphql-codegen, typed document, contract test, route smoke test.

lguidolin/init-repo-CI

Use when setting up a new repository with conventional commits, release-please, and CI automation, or when retrofitting an existing repository that lacks automated versioning and PR validation workflows.

lguidolin/interface-craft-and-accessibility

Use when building or styling UI — components, layouts, forms, design tokens — or making accessibility decisions. Keywords — a11y, WCAG, keyboard navigation, focus state, contrast, design system, minimalist UI, component reuse, ARIA, semantic HTML.

lguidolin/merge-gates-and-automation

Use when setting up or changing CI, pre-push hooks, or a task runner, or deciding what must pass before merge. Symptoms — tempted to put authoritative checks only in a local hook, skip CI, bypass with --no-verify, or unsure what gates a merge vs. runs locally.

lguidolin/observability-and-slos

Use when adding logging, metrics, tracing, health checks, SLOs, or alerting — or when building a service surface that needs to be operable and debuggable. Keywords — structured logs, OpenTelemetry, correlation id, RED metrics, liveness, readiness, SLI, SLO, error budget, alerting.

lguidolin/performance-and-scale

Use when working on hot paths, list endpoints, pagination, data-access in loops, or public interfaces/schemas. Symptoms — unbounded queries, N+1 access, no latency budget, optimizing without measuring, or changing an interface many consumers depend on. Keywords — pagination, N+1, Hyrum's Law, performance budget, bundle size.

lguidolin/postgres-postgraphile-rls-and-sql

Use when writing PostgreSQL, PostGraphile config, Row-Level Security policies, SQL schema files, or working on the Browser→App→PostGraphile→Postgres data path. Keywords — RLS, SECURITY DEFINER, search_path, pgSettings, grants, roles, GraphQL depth limit, query cost, statement_timeout, SQL file organization.

lguidolin/recording-decisions

Use when a design or architecture decision has been made and needs to be captured — writing a decision record or ADR, updating a decision index, noting a deferred idea, or superseding a past decision. Keywords — ADR, decision record, rationale, rejected alternatives, dependency index.

lguidolin/resilience-and-deploy-safety

Use when planning a deploy, designing a rollback, or responding to an incident or writing a postmortem. Keywords — deploy safety, rollback, immutable artifact, progressive delivery, canary, blast radius, incident response, blameless postmortem, error budget.

lguidolin/ship-it

Use when the user wants to ship work — push, PR, archive decision records, merge, and clean up. Handles the full lifecycle from committing final changes through post-merge cleanup including converting specs/plans to compact decision records.

lguidolin/tests-as-a-control

Use when writing or modifying tests, when a test breaks during a refactor, or when testing permission/role rules. Symptoms — tempted to edit a test to make it pass, testing only the happy path, a deny-test that started passing, flaky tests, or unsure what to assert.

Skills associés