Use expand and contract, also called parallel change. Never rename the column in one step. During a rolling deploy, the old app version is still running, and it would break the moment fullname disappears.
Expand:
- Add
display_nameas a new nullable column. This breaks nothing. - Deploy a version that writes both columns and still reads
fullname. - Backfill the existing rows, which means copying old values into the new column. Do it in batches, so the database does not hold long locks.
- Deploy a version that reads
display_nameand still writes both columns. Because it still writes both, a rollback stays safe.
Contract:
- When no running version reads
fullnameany more, deploy a version that stops writing it. - Finally, in a later release, drop the old column.
Each step is backward compatible with the previous app version. So you can roll back any single deploy. Run migrations as a separate pipeline step, not when each instance starts up.
- Never rename a column in one step during a rolling deploy.
- Expand: add the new column, write to both columns, and backfill in batches.
- Switch reads to the new column, but keep writing both so rollback stays safe.
- Contract: stop writing the old column, then drop it in a later release.
- Every step must work with the previous app version.
Read more