CodePark/ questions / Migrations & schema changes
START PRACTICINGPRACTICE
Backend question · Databases & SQL › Migrations & schema changes

You need to rename users.name to users.full_name on a live system with rolling deploys. Why is ALTER TABLE ... RENAME COLUMN dangerous, and how do you do it with zero downtime?

RENAME COLUMN is dangerous because old app instances break the moment it runs. During a rolling deploy, old and new versions of the app run at the same time. Every old instance still queries name, so its queries start failing. Each schema change must work with both versions.

Use the expand and contract pattern.

Expand:

  • Add full_name as a nullable column.
  • Deploy code that writes to both columns and still reads name. Or keep the two columns in sync with a trigger.
  • Backfill (fill in) existing rows in small batches. Small batches avoid long locks and huge transactions.
  • Deploy code that reads full_name.

Contract:

  • When no running code uses name, stop writing to it.
  • In a later release, drop the name column.

Each step is small and can be reversed. Also set a lock_timeout on the DDL (schema change statements such as ALTER). Then a blocked ALTER fails fast instead of stalling traffic.

  • During a rolling deploy, old and new app versions run side by side.
  • Expand: add the new column, write to both columns, and backfill in batches.
  • Switch reads to the new column, then stop writing the old column.
  • Contract: drop the old column in a later release.
  • Set a lock_timeout on DDL so a blocked change fails fast.