Lumen rollback safety for partially applied schema migrations
0 reputation · 08 Aug 2021, 01:51 UTC
0 reputation · 08 Aug 2021, 01:51 UTC
Determine whether Lumen can safely reverse a database schema change after a migration fails partway through on MySQL or MariaDB. Lumen uses Laravel's migration system, recording each batch in the migrations table and expecting down() to invert the changes made by up().
MySQL and MariaDB generally auto-commit DDL statements, so a multi-statement migration can leave tables, columns, or indexes in place even when the batch does not complete. Lumen does not document an automatic, driver-independent guarantee that rollback is atomic or that a partially applied batch is undone without manual work. Safety depends on migration authoring, the down() implementation, and the database driver.
35775 reputation · 08 Aug 2021, 07:42 UTC
1. Rollback only covers fully finished batches. Lumen records a migration in the migrations table as soon as its up() method starts. If the batch stops partway, the table still shows that batch as applied, but the database objects created before the failure remain. The rollback command will still call down() for every migration in that batch, but it will not magically undo the partially applied DDL.
2. Transactions are the only supported safety net. Lumen does not wrap DDL in a transaction by default. If you explicitly start a transaction (e.g., DB::transaction(function () { /* Schema::create, alter, etc. */ }); or Schema::transaction(function () { … });), the parts of DDL that MySQL treats as transactional will be rolled back on failure. CREATE TABLE is non‑transactional, but many ALTER TABLE statements are. Thus, only the transactional subset can be undone.
3. Always verify against your Lumen/Laravel release. The migration engine’s behavior has not changed dramatically across recent releases, but subtle differences in how transactions are handled or how the migrations table is populated can affect rollback. Checking your exact version ensures you are not relying on undocumented assumptions.
When a migration fails after creating a table or adding a column, that object stays in the database. A subsequent php artisan migrate:rollback will run the down() methods in reverse order, but if those methods assume the full up() succeeded, they may either error or leave orphaned objects. This can break later migrations or application code that expects the schema to be in a clean state.
Clone a fresh copy of your database (or use a local test environment).
Run php artisan migrate and let the migration fail after a few statements. Verify that the migrations table still lists the batch as applied.
Inspect the database schema to see which objects remain.
Execute php artisan migrate:rollback and watch the console. Confirm that down() runs for every migration in the batch.
Re‑inspect the schema. Any remaining objects are evidence that the rollback did not fully revert the partial state.
If you used DB::transaction or Schema::transaction in the up() method, repeat the test to see if the transactional part is rolled back on failure.
Adjust the migration to be idempotent (e.g., Schema::dropIfExists in down()) and re‑test.
DB::transaction or Schema::transaction if you need atomicity and are on a database that supports it.down() to handle partial application gracefully—use dropIfExists, dropColumnIfExists, and similar helpers.If you’re unsure whether your current Lumen version treats the migrations table differently or if your database has custom transaction settings, let us know the exact lumen/framework version and MySQL/MariaDB version you’re using. That will help refine the recommendation.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.