As migrations do Laravel que quebram produção — e os padrões seguros que usamos no lugar
27 de maio de 2026 · 1 min de leitura · por Sudhanshu K.
Existe uma categoria de migrations do Laravel que sempre funciona no staging e frequentemente quebra produção: renomear uma coluna, dropar uma coluna, mudar um tipo, adicionar um NOT NULL em uma tabela populada. O padrão é o mesmo em cada caso — a mudança de schema exige um lock total da tabela ou um cutover coordenado com o deploy, e os defaults do Laravel não te dão nenhum dos dois.
Esta é a disciplina de segurança de migration que aplicamos em cada cliente Laravel gerenciado com banco não trivial.
O rename seguro em duas etapas
// Migration 1 — deploy
Schema::table('users', function (Blueprint $t) {
$t->string('email_address')->nullable(); // adicionar a nova coluna
});
// Backfill via queue job, não na migration
// Migration 2 — só deployada depois que o backfill terminar
Schema::table('users', function (Blueprint $t) {
$t->string('email_address')->nullable(false)->change();
$t->dropColumn('email'); // dropar a coluna antiga
});A regra: todo «rename» ou «mudança de tipo» vira dois deploys com um backfill no meio. O primeiro deploy adiciona a nova coluna. O código de aplicação aprende a ler e escrever ambas. Um job em background faz o backfill. Depois que o backfill termina e a aplicação não está mais lendo a coluna antiga, o deploy dois a remove.
O artigo completo cobre:
- A armadilha «funciona na pequena tabela de staging» (locks de tabela escalam com row count)
- Disciplina
--pretend— ler o SQL real antes de rodar - Ferramentas de online schema change (gh-ost, pt-online-schema-change) para os casos onde migrations do Laravel não bastam
- Fazer backfill via queue jobs, não via migrations
- O template de migration que padronizamos para clientes
- Estratégia de rollback quando uma migration já rodou e o deploy falha
Fale conosco se sua última janela de migration foi mais longa do que deveria.
Full article available
Read the full article