Laravel & PHP4 min lezen

Laravel-migraties zonder downtime met expand en contract

Een veilige volgorde voor Laravel-schemawijzigingen, online indexen, hervatbare backfills, gemengde versies, validatie en rollback.

JDoor Jeffrey Klaassen van Oorschot

Een migratie kan in milliseconden eindigen en toch productie breken. In het echte systeem draaien oude en nieuwe webprocessen, langlopende queueworkers, scheduled commands, replica's en rollback-images tegelijk. Zero downtime is compatibiliteit tussen releases en niet een eigenschap van één ALTER TABLE-statement.

Classificeer de wijziging vóór je PHP schrijft

Ik beoordeel schemawerk op lockrisico, herschrijfrisico, datavolume, replicatie-impact en compatibiliteit tussen versies. Een nullable kolom toevoegen is iets anders dan een datatype wijzigen. Een index op een drukke tabel is iets anders dan op een lege tabel. Engine en versie zijn belangrijker dan de naam van de Laravel-methode.

Voor productie inspecteer ik de SQL die Laravel uitvoert en test ik met een vergelijkbaar schema en aantal rijen. Ik controleer welk online of in-place gedrag de gebruikte MySQL-versie werkelijk ondersteunt. Frameworkgemak verandert de regels van de database niet.

Expand: voeg eerst een compatibele vorm toe

Eerst voeg ik een nieuwe nullable kolom, tabel of index toe zonder de oude vorm te verwijderen. Nieuwe code kan beide lezen. Tijdens datamigratie vullen nieuwe writes vaak beide vormen, terwijl reads de nieuwe waarde gebruiken en terugvallen op de oude. Tijdelijke dual-write-logica staat op één plek.

Een kolom hernoem ik niet in één release zolang oude code hem nog kan gebruiken. Ik voeg de nieuwe naam toe, kopieer data, schakel reads om, stop writes naar oud en verwijder de oude kolom later. Dat zijn meer stappen, maar rollback blijft begrijpelijk.

Een compatibele eerste migratie
Schema::table('orders', function (Blueprint $table) {
    $table->string('delivery_zone_id')->nullable();
});

$zoneId = $order->delivery_zone_id
    ?? $legacyZoneResolver->forAddress($order->delivery_address);

Behandel een backfill als operationele workload

Een grote backfill hoort niet in een migration callback. Ik maak een hervatbaar command of queued proces dat stabiele primary-key-ranges verwerkt, kleine transacties commit, voortgang opslaat en kan vertragen. Alleen rijen zonder nieuwe waarde worden geselecteerd, zodat herhalen veilig is.

Ik volg latency, database-CPU en I/O, lock waits, replica lag, foutpercentage, batchduur en resterende rijen. De backfill pauzeert wanneer productie er last van heeft. Vannacht klaar zijn is minder belangrijk dan een gezonde applicatie.

  • Gebruik primary-key-volgorde, geen offset pagination
  • Houd transacties kort
  • Maak iedere rij idempotent
  • Bewaar laatst voltooide range en fouten
  • Throttle op databasegezondheid

Schakel reads om met bewijs

Na de backfill vergelijk ik oude en nieuwe representaties en rapporteer ik verschillen. Daarna schakelt een feature flag of kleine release reads om terwijl dual writes doorgaan. Metrics tellen terugval naar het oude veld. Ik wacht langer dan de grootste queuedelay, cachetijd, scheduled interval en rollbackperiode.

Pas wanneer fallbackgebruik nul is en het nieuwe pad normaal verkeer heeft doorstaan, stop ik writes naar oud. Vanaf dat punt kan rollback extra applicatielogica vragen, dus die beslissing is expliciet.

Contract in een aparte release

Verwijderen is een eigen gereviewde migratie. Ik zoek in applicatiecode, jobs, rapporten, exports, analytics en externe consumers naar het oude veld. Constraints en kolommen verdwijnen pas wanneer ieder actief proces compatibel is. Destructieve DDL draait met lockmonitoring en een getest herstelplan.

Voor contract betekent rollback meestal het vorige image deployen. Daarna kan dat image incompatibel zijn. Ik documenteer dat omslagpunt en houd een forward-fix-plan klaar. Doen alsof iedere databasemigratie omkeerbaar is, is minder veilig dan precies beschrijven wat herstel vraagt.

Praktische checklist

  • Inspecteer SQL en lockgedrag
  • Voeg compatibel schema toe vóór readwijzigingen
  • Centraliseer tijdelijke dual writes
  • Backfill hervatbaar op primary-key-ranges
  • Meet verschillen en fallbackgebruik
  • Contract pas na de rollbackperiode

Verder lezen

Laravel & PHP

Betrouwbare webhookverwerking in Laravel

Een praktische Laravel-webhookarchitectuur voor signatures, duplicaten, snelle acknowledgement, queues, ordering, herstel en observability.

5 min lezenLees artikel