Alterar a estrutura de um banco de dados em produção sempre foi motivo de ansiedade para equipes de desenvolvimento. Renomear uma coluna, mudar um tipo de dado ou dividir uma tabela pode parecer simples em teoria, mas em um sistema com milhões de registros e usuários ativos 24 horas por dia, qualquer descuido pode gerar indisponibilidade ou, pior, perda de dados. Neste artigo, apresentamos técnicas consolidadas para migrar esquemas e dados sem interromper o serviço.
Por que migrações "diretas" são arriscadas
A abordagem ingênua de migração — alterar a estrutura da tabela e o código da aplicação ao mesmo tempo, em um único deploy — funciona em ambientes de baixo tráfego, mas se torna perigosa em produção. Durante o intervalo entre a alteração do banco e a atualização completa de todas as instâncias da aplicação (que normalmente não acontece instantaneamente), há uma janela onde código antigo pode tentar operar em um esquema já modificado, gerando erros ou inconsistência de dados.
O padrão expand-contract
A técnica mais confiável para migrações sem downtime é conhecida como expand-contract (também chamada de parallel change). Em vez de alterar a estrutura de uma vez, o processo é dividido em fases:
Fase de expansão: adiciona a nova estrutura (nova coluna, nova tabela) sem remover a antiga, mantendo compatibilidade com o código atual.
Fase de sincronização (backfill): popula a nova estrutura com os dados existentes, gradualmente e sem bloquear a tabela inteira de uma vez.
Fase de transição: o código da aplicação passa a escrever em ambas as estruturas simultaneamente (old e new), e depois passa a ler apenas da nova, validando que os dados estão corretos.
Fase de contração: somente depois que a nova estrutura está validada em produção por um período seguro, a estrutura antiga é removida.
-- Fase de expansão: adicionar nova coluna sem remover a antiga
ALTER TABLE usuarios ADD COLUMN email_normalizado VARCHAR(255);
-- Fase de backfill: popular em lotes, sem travar a tabela inteira
UPDATE usuarios SET email_normalizado = LOWER(email)
WHERE id BETWEEN 1 AND 10000 AND email_normalizado IS NULL;
Migração sem downtime não é sobre executar rápido — é sobre garantir que, a qualquer momento durante o processo, o sistema continue funcionando com dados consistentes.
Backfill em lotes, não em uma única transação
Atualizar milhões de registros em uma única transação massiva pode travar a tabela por minutos ou horas, além de arriscar timeout ou consumo excessivo de memória no banco. A prática recomendada é processar os dados em lotes menores (por exemplo, mil registros por vez), com pequenas pausas entre cada lote, permitindo que outras operações no banco continuem sendo processadas normalmente durante a migração.
Migrações reversíveis: sempre tenha um caminho de volta
Toda migração de esquema deve ter uma forma clara de ser revertida caso algo dê errado após o deploy. Isso significa evitar operações destrutivas irreversíveis (como DROP COLUMN) até ter certeza absoluta de que a nova estrutura está funcionando corretamente em produção — a fase de contração do padrão expand-contract deve ser sempre a última etapa, executada com folga de tempo depois da validação.
Cuidado com locks em tabelas grandes
Alguns tipos de alteração de esquema — como adicionar uma coluna com valor padrão em determinados bancos de dados, ou criar um índice — podem exigir um lock exclusivo na tabela, bloqueando leituras e escritas durante a operação. Em tabelas grandes, isso pode levar minutos, o que é inaceitável em produção. Ferramentas específicas para migração online, como pt-online-schema-change (MySQL) ou a criação de índices com CONCURRENTLY no PostgreSQL, evitam esse bloqueio ao construir a estrutura em paralelo e trocá-la de forma quase instantânea ao final.
Teste a migração em um ambiente com volume real de dados
Uma migração que roda em segundos em um banco de desenvolvimento com poucos registros pode levar horas em produção com milhões de linhas. Sempre que possível, teste o processo completo de migração em um ambiente de staging com volume de dados equivalente (ou uma cópia real, se possível dentro das políticas de privacidade) para estimar corretamente o tempo de execução e identificar gargalos antes do deploy real.
Considerações finais
Migrações de banco de dados sem downtime exigem planejamento em etapas, paciência para não pular a fase de validação e ferramentas adequadas para lidar com tabelas grandes. O padrão expand-contract, aplicado com disciplina, permite evoluir o esquema de um sistema em produção sem expor usuários a indisponibilidade ou risco de perda de dados. Se sua empresa precisa migrar ou evoluir a estrutura de um banco de dados em produção, a equipe da ASL Software Engineering pode ajudar a planejar esse processo com segurança. Fale com a gente.