Ordering: rename a column with zero downtime Intermediate
Estimated reading time: 1 min read
Renaming a column sounds simple: one ALTER TABLE ... RENAME COLUMN statement. But during a rolling deploy, the old and new app versions run at the same time. One of them will read a column that does not exist.
Put the steps below in order. Press Check to see which steps are out of place and what breaks when they are.
Rename column status → payment_status with zero downtime
The orders table has 50 million rows, the app runs 6 pods and deploys with rolling updates: during a rollout, the old and new versions run side by side.
Put the steps in order so that no request fails and you can always roll back.
Use ▲▼ to move each step, or tap a step’s ⠿ and then tap its new position. On a computer you can drag and drop.
- Backfill old rows in batches, then reconcile until mismatches = 0
UPDATE ... WHERE id BETWEEN $1 AND $2 - Deploy an app that writes both columns and still reads
status DROP COLUMN statusin a separate migration- Add the
payment_statuscolumn (nullable) under alock_timeout - Deploy an app that reads
payment_statusand still writes both - Rollback window over: deploy an app that stops writing
statusand removes the column from the ORM
A full explanation of each phase, including NOT NULL and indexes that do not lock the table: Expand–contract migration.