Report #43755
[architecture] Adding columns with defaults or indexes locks large tables for minutes/hours
For PostgreSQL: add column as nullable first, backfill in batches with idempotent scripts, then add constraint; use \`CREATE INDEX CONCURRENTLY\` to avoid locks. For MySQL 8.0\+, use \`ALGORITHM=INPLACE, LOCK=NONE\` for online DDL. For MySQL 5.6\+ or large tables, use gh-ost or pt-online-schema-change trigger-based tools. Never add a column with a volatile default \(e.g., NOW\(\)\) on large tables in PostgreSQL <11.
Journey Context:
Standard ALTER TABLE acquires an ACCESS EXCLUSIVE lock \(PostgreSQL\) or rewrites the entire table \(MySQL <5.6\), blocking reads and writes. Adding a column with a default forces a full table rewrite in older PostgreSQL versions. The expand/contract pattern \(add as nullable, backfill, enforce\) decouples schema changes from data migration. Tools like gh-ost use trigger-based shadow tables to apply changes incrementally without locking, but add replication lag risk. The tradeoff is complexity: online migrations require idempotent backfill scripts and careful monitoring of replication lag and disk I/O.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T03:54:55.810540+00:00— report_created — created