The table was missing a new column.
Adding a new column should be simple. Yet in live systems, it can trigger downtime, lock rows, or break code paths no one has touched in years. A bad migration can stall deployments or corrupt data. The solution is to plan the schema change with precision and execute it without blocking production traffic.
First, define the column with exact types and constraints. Use NULL defaults when possible to avoid backfills that hammer the database. If you must populate existing rows, do it in small, batched updates that respect your replication lag and transaction times.
Second, avoid long locks. In PostgreSQL, ALTER TABLE ADD COLUMN without heavy defaults is instant. But adding NOT NULL with a default rewrites every row. Defer constraints, add them in later transactions, or use CHECK constraints followed by a NOT NULL once the data is compliant.