Communitygithub.com

lguidolin/zero-downtime-migrations

Use ao alterar um esquema de banco de dados onde os dados devem sobreviver à mudança — adicionar/remover/renomear colunas, constraints, índices ou fazer backfill. Sintomas — uma migração destrutiva agrupada com um deploy de código, uma coluna NOT NULL com backfill, um UPDATE que trava a tabela ou uma renomeação. Palavras-chave — expandir/contrair, mudança paralela, backfill, NOT VALID, CREATE INDEX CONCURRENTLY, graphile-migrate.

O que é zero-downtime-migrations?

Este skill define uma disciplina de mudança de esquema de banco de dados que mantém um sistema em funcionamento durante um deploy contínuo, sem tempo de inatividade. Durante um rollout, pods antigos e novos compartilham o mesmo banco de dados, exigindo que o esquema seja compatível com ambas as versões do aplicativo simultaneamente. A abordagem fundamental é o padrão Expandir/Contrair (Parallel Change), que divide uma alteração de esquema em três releases distintos: Expandir (adição aditiva e compatível com versões anteriores), Migrar (backfill em lotes limitados e aplicação de constraints de forma segura) e Contrair (remoção do artefato antigo apenas após a aposentadoria completa da versão anterior). O skill também fornece diretrizes específicas para PostgreSQL, como o uso de `CREATE INDEX CONCURRENTLY` e `NOT VALID` para evitar bloqueios de tabela, além de regras de autoramento para manter migrações idempotentes e uma única fonte de verdade para bootstrap. É útil para engenheiros que lidam com esquemas em produção com dados críticos e querem evitar interrupções durante deploys.

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

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Migrações com Zero Downtime

Visão Geral

Disciplina de mudança de esquema que mantém um sistema em funcionamento durante um deploy contínuo. Durante um rollout, pods antigos e novos compartilham um único banco de dados — portanto, o esquema deve ser compatível com ambas as versões do aplicativo ao mesmo tempo. Combinar uma migração destrutiva com o deploy que precisa dela é a clássica interrupção autoinfligida.

Regras de Autoria (todos os projetos)

  • Dois tipos de migração, mantidos distintos: o conjunto idempotente current/ (iteração de desenvolvimento — executado novamente a cada ciclo, CREATE OR REPLACE / IF NOT EXISTS, objetos em forma final, sem ALTER pós-criação) e migrações committed (imutáveis, ordenadas, o que realmente é enviado). ALTER DEFAULT PRIVILEGES é o único ALTER inline aceito.
  • A propriedade vem de como as migrações são executadas, e não de ALTER ... OWNER espalhados.
  • Uma única fonte de verdade para bootstrap compartilhada pelo caminho de inicialização local/Docker e pelo banco de dados sombra/teste — todo ambiente construído de forma idêntica.

Expandir/Contrair (Mudança Paralela)

Aplica-se quando: o banco de dados contém dados que devem sobreviver ao deploy (staging com dados, produção). Isento: projetos locais/fáceis de resetar — mas escreva migrações committed como se isso se aplicasse, para que a promoção nunca seja uma reescrita.

Uma mudança de esquema é dividida em três releases, nunca uma:

  1. Expandir — adicione a nova forma aditivamente, com compatibilidade reversa: nova coluna anulável, nova tabela, nova função. A versão N do aplicativo continua funcionando intocada.
  2. Migrar — faça backfill em lotes limitados (nunca um UPDATE que trava a tabela); escrita dupla a partir do aplicativo N+1 se necessário; mude as leituras para a nova forma. Só agora adicione NOT NULL (adicione a constraint NOT VALID, depois VALIDATE separadamente).
  3. Contrair — somente após a versão N do aplicativo ser totalmente retirada, remova a coluna/constraint antiga em um release posterior.

Armadilhas do Postgres

ArmadilhaAbordagem segura
Coluna NOT NULL com valor padrão volátil/grande backfillAdicione anulável → faça backfill em lotes → adicione constraint NOT VALID → VALIDATE
Adicionar uma constraintAdicione NOT VALID primeiro, depois VALIDATE CONSTRAINT (trava mais fraca)
Construir um índiceCREATE INDEX CONCURRENTLY — não pode ser executado dentro de uma transação; isole do agrupamento de transações da ferramenta de migração
Uma migração bloqueada congelando a produçãoDefina lock_timeout / statement_timeout para que falhe rapidamente
Renomear uma colunaÉ expandir/contrair: adicione nova → faça backfill → mude as leituras → remova a antiga, em releases separados

Por que "CREATE OR REPLACE em forma final" não é suficiente em produção

Essa regra é ergonomia do desenvolvedor e está correta em desenvolvimento. Em produção, com usuários reais e um deploy contínuo, ambas as versões do aplicativo compartilham o esquema durante a duração do rollout — portanto, expandir/contrair é o que torna a mudança segura. Não confunda as duas coisas.

Raciocínio completo: Artigo XVII da constituição, empacotado em engineering-constitution/references/engineering-constitution.md. Pipeline de deploy: 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.

Habilidades Relacionadas