
Migrações de banco de dados zero-downtime: orquestrando escritas duplas e leituras graduais com os conectores i+1 do useflagly
Como migrar esquemas de dados massivos de forma totalmente segura, utilizando flags de dupla escrita e de leitura gradual com fallback automático.
Migrar bancos de dados de larga escala sem indisponibilidade é um dos maiores desafios de engenharia. A clássica abordagem offline de colocar o sistema em manutenção para rodar scripts de migração não escala em ecossistemas de alta disponibilidade. A solução definitiva é a estratégia de escrita dupla e leitura gradual (Dual-Write/Dual-Read). No entanto, gerenciar o estado dessas transições por meio de variáveis de ambiente estáticas exige deploys constantes e introduz sérios riscos de sincronismo e downtime. Com o Useflagly, você controla essa alternância dinâmica em tempo de execução sem tocar no seu pipeline de CI/CD.
A arquitetura de transição no painel do useflagly
Para mitigar riscos, dividimos a migração em fases claras utilizando o painel do Useflagly. Para fins de organização de equipe, as flags são estruturadas na hierarquia Scenario > Flow > FlowPart > Flag. Criamos o Scenario 'infra-migrations', o Flow 'db-migration-v2' e o FlowPart 'step-transitions'. Dentro desse agrupamento organizacional, residem as duas flags operacionais principais: 'db-dual-write' e 'db-read-new-schema'. Vale lembrar que essa estrutura organizacional superior serve apenas para manter seu painel limpo; toda a inteligência e as validações residem unicamente no nível da Flag.
Configuramos as validações de cada flag usando os conectores i+1 do Useflagly para clicar e direcionar a migração em lotes controlados. Na regra 0, definimos uma validação de tipo 'custom' para o campo 'tenantId' com a condição 'is_in_list'. Na regra 1, configuramos o conector como 'AND' e definimos uma validação de tipo 'percentage' com valor '10'. O parser linear O(N) do Useflagly avaliará a regra 0 e, se válida, combinará o resultado logicamente com a regra de porcentagem de forma sequencial por prioridade crescente. Isso nos permite liberar a dupla escrita e a leitura do novo banco inicialmente apenas para 10% dos usuários dentro dos tenants selecionados.

import { UseFlaglyClient } from '@useflagly/sdk-javascript';
const client = new UseFlaglyClient({
token: process.env.USEFLAGLY_TOKEN || ''
});
async function handleDatabaseMigrationFlow(userId: string, tenantId: string, payload: any) {
const env = 'PRD';
const body = {
identifier: userId,
context: { tenantId }
};
try {
// 1. Decidir se escreve em ambos os bancos (Dual-Write)
const dualWriteRes = await client.validateFlag('db-dual-write', body, env);
const shouldDualWrite = dualWriteRes.statusCode === 200 && dualWriteRes.data['db-dual-write'];
if (shouldDualWrite) {
await Promise.all([
writeToLegacyDatabase(payload),
writeToNewDatabase(payload).catch(err => {
console.error('Falha na escrita assíncrona do novo banco:', err);
})
]);
} else {
await writeToLegacyDatabase(payload);
}
// 2. Decidir se lê do banco novo (Leitura Gradual com Fallback)
const readNewRes = await client.validateFlag('db-read-new-schema', body, env);
const shouldReadNew = readNewRes.statusCode === 200 && readNewRes.data['db-read-new-schema'];
if (shouldReadNew) {
try {
return await readFromNewDatabase(userId);
} catch (error: any) {
// Fallback imediato se houver qualquer oscilação de rede ou indisponibilidade
if (error.isNetworkError || error.statusCode === 0) {
console.warn('Erro de rede detectado no novo banco. Fallback para o legado.');
}
return await readFromLegacyDatabase(userId);
}
}
return await readFromLegacyDatabase(userId);
} catch (error: any) {
if (error.isSubscriptionError) {
console.error('Cota de requests esgotada no Useflagly. Aplicando fallback de segurança.');
}
return await readFromLegacyDatabase(userId);
}
}
Infraestrutura de baixa latência e fallback resiliente
Executar validações dinâmicas a cada escrita ou leitura de banco de dados não pode adicionar latência significativa à sua aplicação. A Useflagly resolve esse gargalo hospedando sua infraestrutura principal no Google Cloud Platform (GCP) na região us-east4, garantindo rotas de rede ultracurtas e tempos de resposta sub-milissegundo para os principais servidores de aplicação modernos. Além disso, o servidor conta com um sistema híbrido de cache duplo: a camada L1 em memória de processo (LRU de até 500 chaves com TTL de 10 minutos) e a camada L2 distribuída via Redis (TTL de 2000 segundos). Essa arquitetura robusta garante respostas em frações de milissegundo diretamente da borda, blindando seus microsserviços sem onerar o seu banco de dados transacional.

⚠️ ⚠️ Alerta de Missão Crítica: A migração zero-downtime só é concluída com segurança quando os dados de escrita estão 100% consistentes em ambos os bancos. Use as flags do Useflagly para manter o dual-write ativo até que todos os dados históricos sejam sincronizados e validados no novo esquema, antes de virar a chave da leitura gradual para 100% dos usuários.
🚩 useflagly.com.br
Posts relacionados

Shadow deploys de código gerado por ia: como executar 'dark launches' silenciosos com useflagly

A morte da dívida de decisão: como flowparts evitam que ias criem condicionais infinitas no seu repositório
