Disciplina em migrações de banco para projetos que evoluem rápido
Deploys não trocam o sistema inteiro num instante. Em uma atualização gradual, versões antiga e nova podem acessar o mesmo banco; workers podem ficar para trás; rollback de código não desfaz transformações de dados. Trate mudanças de esquema como uma transição compatível entre versões, não como um comando DDL junto ao deploy.
Publicado em 28 de setembro de 202614 min de leituraEvolução de esquema e entrega segura
Use expandir, migrar e contrair
As versões ativas precisam funcionar em cada etapa intermediária
1 / ExpandirAdicione estrutura compatível e nullable.
2 / CompatibilizarPublique código que lê formatos antigo e novo.
3 / PreencherMigre em lotes limitados e retomáveis.
4 / VirarVerifique paridade e adote o formato novo.
5 / ContrairRemova o antigo após migrar os consumidores.
Mudança
Sequência mais segura
Risco a verificar
Renomear coluna
Adicionar, suportar ambos, preencher, trocar e remover depois
Workers e relatórios antigos ainda consultam a coluna
Mudar significado
Adicionar campo versionado e transformar com validação
Unidades, nulos ou arredondamento diferentes
Exigir novo valor
Adicionar nullable, preencher, validar e só então restringir
Varredura grande ou lock ao impor constraint
Apagar tabela
Parar gravações, observar leituras, arquivar e remover por último
Jobs e exports não documentados dependem dela
Documente quais versões da aplicação suportam cada fase. Inclua jobs agendados, ferramentas de relatório e scripts administrativos. Rollback de código só é seguro se o esquema expandido continuar compatível e os dados não tiverem cruzado uma fronteira irreversível.
Faça backfill pensando no tráfego real
Backfills devem ser idempotentes, retomáveis e limitados por quantidade ou duração. Use cursor estável, checkpoints e indicadores de progresso, falhas e pendências. Reduza o ritmo se latência ou atraso de réplica ultrapassarem limites. Compare totais e amostras dos valores transformados antes de trocar as leituras.
Em tabelas grandes, evite transação única que segura locks e gera WAL excessivo. Escolha lotes medindo em volume próximo da produção. Mantenha gravações antigas e novas coerentes durante a sobreposição e use consulta de reconciliação para achar divergências.
Entenda locks e falhas de DDL
“Online” não significa sem lock. O nível necessário depende do banco e do subcomando; até uma alteração de metadados pode esperar transações longas ou bloquear brevemente requisições. Consulte a documentação da versão, configure timeouts quando disponíveis, observe filas de lock e separe mudanças arriscadas.
Separe alteração de esquema de backfill quando duração e falhas forem diferentes. Decida se a recuperação é retry, avanço corretivo ou restauração. Transformações de produção muitas vezes são mais seguras com roll-forward. Backup só ajuda se tempo e perda de dados forem aceitáveis; teste a restauração.
Automatize com um responsável único
Execute migrações uma vez em uma etapa controlada, não em cada réplica. Serialize, registre versão e duração e alerte falhas. Não edite migrações já executadas: acrescente outra corretiva. Revise SQL gerado e teste atualização tanto do esquema atual quanto de um banco vazio.
Em resumo
Migrações seguras respeitam versões simultâneas, tráfego e mudanças de dados que talvez não sejam reversíveis. Expanda com compatibilidade, preencha em lotes, verifique antes de virar e contraia quando consumidores antigos sumirem. Etapas pequenas e previsíveis são mais rápidas do que juntar esquema, transformação e limpeza num deploy só.