db-migration-safetylisted
Install: claude install-skill KhaledSaeed18/dotclaude
A migration that is correct on an empty dev database can still take a production table offline. Judge every migration by what it does under load on the largest table it touches: what lock it takes, for how long, and what the old application version does while the new schema is live. When any answer is "depends", assume the worst table and the slowest query.
## Step 1: Establish the blast radius
- Read the migration and identify every table it touches, then find out (or ask) roughly how large and how hot each one is. A pattern that is fine on 10k rows is an outage on 100M.
- Identify the engine and version (Postgres, MySQL 8, SQLite, ...) from config; lock behavior differs materially between them, and between versions.
- Identify the deploy model: is the old app version still running while this migration executes (rolling deploy, multiple replicas)? Almost always yes; review under that assumption.
## Step 2: Check the dangerous patterns
Flag any of these, with the safe alternative:
**Locking and rewrites**
- Any statement that rewrites the table or takes an exclusive lock for its duration: changing a column's type, adding a column with a volatile default (pre-Postgres 11), `ALTER TABLE` on MySQL without `ALGORITHM=INPLACE`/`INSTANT` support. Alternative: add a new column, backfill, swap.
- `CREATE INDEX` without `CONCURRENTLY` (Postgres) on a live table blocks writes for the build. `CONCURRENTLY` cannot run inside a transaction; the migration tool must support that (most