7 min leitura • Guide 366 of 877
Gerenciamento de Migração de Banco de Dados
As migrações de banco de dados são a parte mais arriscada do deployment. Elas afetam dados, nem sempre podem ser desfeitas e impactam aplicações em execução. Um bom gerenciamento de migração mantém os dados seguros enquanto permite evolução. Um gerenciamento inadequado leva a interrupções e perda de dados.
Segurança de Migração
| Risco | Mitigação |
|---|---|
| Perda de dados | Backups, rollback testado |
| Tempo de inatividade | Padrões sem tempo de inatividade |
| Corrupção | Testes em staging |
| Performance | Análise de índices |
Conceitos Básicos de Migração
Controle de Versão
GERENCIAMENTO DE MIGRAÇÃO
═════════════════════════
CONTROLADO POR VERSÃO:
─────────────────────────────────────
migrations/
├── 001_create_users.sql
├── 002_add_email_to_users.sql
├── 003_create_orders.sql
├── 004_add_index_on_orders.sql
└── Sequencial, rastreado
ARQUIVO DE MIGRAÇÃO:
─────────────────────────────────────
-- Migration: 002_add_email_to_users
-- Created: 2024-01-15
-- Author: developer@example.com
-- Up
ALTER TABLE users ADD COLUMN email VARCHAR(255);
-- Down
ALTER TABLE users DROP COLUMN email;
FERRAMENTAS:
─────────────────────────────────────
├── Flyway (migrações SQL)
├── Liquibase (XML/SQL)
├── Laravel Migrations (PHP)
├── Alembic (Python)
├── Knex (Node.js)
├── Rails Migrations (Ruby)
└── Ferramentas específicas do framework
EXECUÇÃO:
─────────────────────────────────────
├── Executar migrações pendentes
├── Rastrear migrações executadas
├── Nunca modificar migrações executadas
├── Novas mudanças = nova migração
└── Histórico imutável
Padrões Sem Tempo de Inatividade
Mudanças Seguras
MIGRAÇÕES SEM TEMPO DE INATIVIDADE
═════════════════════════════════
OPERAÇÕES SEGURAS:
─────────────────────────────────────
Sempre seguras:
├── Adicionar nova tabela
├── Adicionar coluna nullable
├── Adicionar índice (concurrente)
├── Adicionar coluna com padrão
└── Mudanças aditivas
OPERAÇÕES PERIGOSAS:
─────────────────────────────────────
Precisam tratamento cuidadoso:
├── Remover coluna
├── Renomear coluna
├── Mudar tipo de coluna
├── Adicionar restrição NOT NULL
├── Requer abordagem multi-etapa
└── Nunca em migração única
PADRÃO DE RENOMEAR COLUNA:
─────────────────────────────────────
Objetivo: Renomear 'name' para 'full_name'
Etapa 1: Adicionar nova coluna
ALTER TABLE users ADD COLUMN full_name VARCHAR(255);
Etapa 2: Deploy código que escreve em ambos
old_column e new_column
Etapa 3: Backfill de dados
UPDATE users SET full_name = name WHERE full_name IS NULL;
Etapa 4: Deploy código que lê da new_column
Etapa 5: Parar de escrever na coluna antiga
Etapa 6: Remover coluna antiga (depois)
ALTER TABLE users DROP COLUMN name;
Cronograma:
├── Migração 1 (adicionar coluna)
├── Deploy 1 (escrever ambos)
├── Migração 2 (backfill)
├── Deploy 2 (ler novo)
├── Deploy 3 (escrever novo apenas)
├── Migração 3 (remover antigo)
└── Múltiplos deploys, mudança segura
ADICIONANDO NOT NULL:
─────────────────────────────────────
Objetivo: Tornar email obrigatório
Etapa 1: Adicionar coluna nullable
ALTER TABLE users ADD COLUMN email VARCHAR(255);
Etapa 2: Deploy código que requer email
Etapa 3: Backfill de linhas existentes
UPDATE users SET email = 'unknown@example.com'
WHERE email IS NULL;
Etapa 4: Adicionar restrição
ALTER TABLE users
ALTER COLUMN email SET NOT NULL;
Testando Migrações
Antes da Produção
TESTE DE MIGRAÇÃO
═════════════════
TESTE EM STAGING:
─────────────────────────────────────
Requisitos:
├── Volume de dados similar à produção
├── Padrões de dados realistas
├── Mesma versão do banco
├── Testar tempo de migração
├── Testar rollback
└── Simulação de produção
CHECKLIST:
─────────────────────────────────────
Antes da produção:
├── ☐ Testado em staging
├── ☐ Tempo de migração aceitável
├── ☐ Rollback testado
├── ☐ Backup feito
├── ☐ Janela de manutenção se necessário
├── ☐ Equipe em standby
└── Pronto para executar
TESTE DE PERFORMANCE:
─────────────────────────────────────
Para tabelas grandes:
├── Estimar tempo de migração
├── Testar com dados do tamanho da produção
├── Verificar duração de locks
├── Planejar para tamanho da tabela
├── Considerar processamento em lotes
└── Sem surpresas
EXEMPLO:
─────────────────────────────────────
Tabela: orders (50M linhas)
Resultados do teste:
├── Adicionar coluna: 45 segundos
├── Backfill: 15 minutos (em lotes)
├── Adicionar índice: 3 minutos (concurrente)
├── Total: 20 minutos
├── Plano: Janela de baixo tráfego
└── Preparado
Estratégia de Rollback
Plano de Recuperação
ESTRATÉGIA DE ROLLBACK
═══════════════════════
MIGRAÇÕES REVERSÍVEIS:
─────────────────────────────────────
Escrever migração down:
-- Up
ALTER TABLE users ADD COLUMN email VARCHAR(255);
-- Down
ALTER TABLE users DROP COLUMN email;
├── Toda migração tem reverso
├── Testado em staging
├── Um comando para desfazer
└── Rollback fácil
NÃO REVERSÍVEL:
─────────────────────────────────────
Algumas migrações não podem reverter:
├── DROP COLUMN (dados perdidos)
├── Truncar dados
├── Mudanças de tipo com perda de dados
├── Necessário restaurar backup
└── Tratamento especial
PARA NÃO REVERSÍVEL:
─────────────────────────────────────
├── Documentar explicitamente
├── Backup antes de executar
├── Testar procedimento de restauração
├── Script de rollback manual
├── Cautela extra
└── Plano B pronto
ESTRATÉGIA DE BACKUP:
─────────────────────────────────────
Antes da migração:
├── Backup completo ou snapshot
├── Verificar se backup funciona
├── Conhecer tempo de restauração
├── Procedimento de restauração documentado
├── Recuperação point-in-time habilitada
└── Rede de segurança
Migrações de Tabelas Grandes
Lidando com Escala
MIGRAÇÕES DE TABELAS GRANDES
════════════════════════════
PROBLEMAS:
─────────────────────────────────────
Tabelas grandes:
├── Tempos longos de lock
├── Operações lentas
├── Lag de replicação
├── Timeouts de conexão
├── Necessitam tratamento especial
└── Não podem fazer ALTER simples
PROCESSAMENTO EM LOTES:
─────────────────────────────────────
Backfill em lotes:
DO $$
DECLARE
batch_size INT := 10000;
last_id INT := 0;
BEGIN
LOOP
UPDATE users
SET full_name = name
WHERE id > last_id
AND id <= last_id + batch_size
AND full_name IS NULL;
IF NOT FOUND THEN EXIT; END IF;
last_id := last_id + batch_size;
COMMIT;
PERFORM pg_sleep(0.1); -- Controle
END LOOP;
END $$;
├── Processar em pedaços
├── Commit entre lotes
├── Permitir replicação acompanhar
├── Reduzir duração de lock
└── Execução controlada
MUDANÇAS DE ESQUEMA ONLINE:
─────────────────────────────────────
Ferramentas:
├── pt-online-schema-change (MySQL)
├── gh-ost (MySQL)
├── pg_repack (PostgreSQL)
├── Mudanças sem lock
└── Seguro para produção
ÍNDICE CONCORRENTE:
─────────────────────────────────────
PostgreSQL:
CREATE INDEX CONCURRENTLY idx_users_email
ON users(email);
├── Não bloqueia tabela
├── Leva mais tempo
├── Pode falhar (tentar novamente)
├── Seguro para produção
└── Usar para tabelas grandes
Integração com GitScrum
Rastreando Migrações
GITSCRUM PARA MIGRAÇÕES
═══════════════════════
TAREFAS DE MIGRAÇÃO:
─────────────────────────────────────
├── Label: database, migration
├── Vinculado à funcionalidade
├── Checklist para etapas
├── Coordenação de deployment
└── Rastreamento visível
EXEMPLO DE TAREFA:
─────────────────────────────────────
Tarefa: "Adicionar coluna email aos usuários"
Checklist:
├── ☐ Escrever migração
├── ☐ Escrever rollback
├── ☐ Testar em staging
├── ☐ Cronometrar migração em dados prod
├── ☐ Backup produção
├── ☐ Executar migração
├── ☐ Verificar sucesso
└── Completar processo
RUNBOOK:
─────────────────────────────────────
NoteVault:
├── Runbook de migração
├── Procedimentos comuns
├── Procedimentos de rollback
├── Contatos de emergência
└── Processo documentado
Melhores Práticas
Para Migrações
- Controle de versão — Todas as migrações rastreadas
- Padrões sem tempo de inatividade — Mudanças multi-etapa
- Testar thoroughly — Staging com dados reais
- Sempre ter rollback — Migrações down
- Backup primeiro — Rede de segurança
Anti-Padrões
ERROS DE MIGRAÇÃO:
✗ Migrações não testadas
✗ Sem plano de rollback
✗ Renomear em etapa única
✗ Remover coluna com DROP
✗ Locks longos em produção
✗ Sem backups
✗ Editando migrações executadas
✗ Assumindo que vai funcionar