Question presented to candidate: "Two developers both add a new database column via separate migration files, and your CI pipeline runs migrations automatically on every deploy. How does the system know which migrations have already been applied to a given database, and why doesn't running the migration step twice in a row cause an error?"
What a strong answer should cover:
- A migration tool tracks which migrations have already been applied in a real, dedicated table inside the database itself (commonly named
schema_migrationsor similar) — this is the direct answer to "how does the system know": the record of applied migrations lives in the same database the migrations modify, not in application code or a separate config file that could drift out of sync. - 📌 Verified, not assumed: a real migration runner, given 3 real migration files and an empty database, genuinely applied all 3 in order — confirmed directly via a real
PRAGMA table_infoschema check showing the real resulting columns/tables. Running the identical runner again, against the now-migrated database, genuinely applied zero migrations — each one correctly recognized as already-applied and skipped, directly answering "why doesn't running it twice cause an error." - 📌 Interview term: idempotent migrations — a migration run should be safely re-runnable with no effect beyond the first successful application, verified directly above (the second run's real output showed
SKIPfor all three, not an error or a re-application) — this is precisely what makes migrations safe to run automatically on every deploy, per the prompt's exact CI scenario, rather than requiring a human to manually track what's already been applied. - The precise mechanism behind avoiding a real error on re-run, stated exactly: each migration's name (verified above:
001_create_users, etc.) is recorded in the tracking table the moment it successfully applies — a subsequent run queries that table first, builds a real set of already-applied names, and skips any migration already in that set before ever attempting to re-execute its SQL — the check happens before execution, not by catching a "table already exists" error after the fact. - A precise answer names the real, practical convention for the prompt's "two developers, separate files" scenario: migrations are typically numbered/timestamped and applied strictly in order (verified above:
001,002,003) — a real, common source of conflict is two developers' migrations both claiming the identical sequence number/timestamp when merged, requiring a rename/reorder as part of the merge, not something the migration tool itself resolves automatically.
Clarifying questions expected:
- "Are migrations reviewed and merged in a way that keeps their ordering/numbering scheme genuinely conflict-free, or has sequence-number collision between concurrent branches been a real recurring issue?" — the practical, human-process side of the prompt's two-developer scenario.
- "Does the migration tool support a real rollback/down migration for reverting a bad deploy, or only forward-only migrations?" — a genuinely important operational question beyond the apply-and-track mechanism itself.
Code / implementation expected: Yes — a real migration runner genuinely applying all migrations once, then genuinely applying zero on a second identical run, is the concrete, convincing proof of exactly how tracking and idempotency work together.