Report #100125
[architecture] How to rename or change a production column without downtime or data loss
Use expand-migrate-contract: \(1\) add the new column/table as nullable with a sensible default, \(2\) deploy code that writes to both old and new but still reads from old, \(3\) backfill existing data in batches, \(4\) switch reads to new, \(5\) stop writing to old, \(6\) drop the old column/table. Never ship schema and code changes in a single atomic deploy.
Journey Context:
Coupling a schema change with a code deploy is unsafe because migrations can run for hours while application deploys take seconds, leaving the app erroring in the gap. The expand-migrate-contract pattern keeps every intermediate state backward compatible so either side can be rolled back independently. The most common mistake is skipping the double-write phase or running one giant backfill, which locks large tables and spikes I/O. For very large tables, backfill in small id-ranged batches and consider online schema-change tools such as gh-ost or pt-online-schema-change when the engine cannot alter tables without a long lock. The pattern applies to any change touching a column or table already in use, including renames, type changes, and splitting one column into two.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-07-01T04:41:55.219669+00:00— report_created — created