chore(migrations): delete 0001, and drop the duplicate indexes it created - #139
Merged
Conversation
…ated 0001_add_query_indexes re-declared indexes that GORM's AutoMigrate already creates from index: struct tags on the models. Same columns, different names: AutoMigrate emits "docScope", the migration emitted "idx_restcol_documents_docscope", both over (model_project_id, model_collection_id, created_at). Same for the two collection indexes. Because CREATE INDEX IF NOT EXISTS matches on name and the names differ, its guard never fired: applying it produced a second index over identical columns rather than doing nothing. Measured on a database built by AutoMigrate and then migrated - six indexes where three suffice, costing write throughput and disk for no read benefit. Evidence in FootprintAI/grandturks#986. So 0001 was not merely unapplied, as grandturks#984 concluded from the manifests - it was better left unapplied. Deleting it rather than renaming its indexes to match: a migration that re-declares what the models already declare is a second source of truth for one schema, and the models are the one that services actually run. 0003 removes the duplicates on environments that did apply it. That is not hypothetical: grandturks#987 added a demo-box runner that applies every migrations/*.up.sql in order, so any box brought up on an existing volume since then has them. Only the migration-created names are dropped; the AutoMigrate ones are the real indexes and stay. The two sets are distinguishable because GORM quotes the hyphenated table name where 0001 used underscores. Verified end to end on a real postgres: seeded with AutoMigrate, applied the old 0001 to reproduce the damaged state (6 indexes), applied 0003, confirmed the 3 survivors are AutoMigrate's over the expected columns, and confirmed a second run is a no-op. Numbering is not reused - 0003 follows 0002 - so no environment that recorded a version sees a different migration under an old number. Note for consumers: grandturks copies these files into deploy/demo/restcol-migrations/ with a drift test, so it needs the copy of 0001 removed when it next bumps. Refs: FootprintAI/grandturks#986, FootprintAI/grandturks#984, FootprintAI/grandturks#987 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was wrong with 0001
0001_add_query_indexesre-declared indexes that GORM'sAutoMigratealready creates fromindex:struct tags on the models:Same columns, different names —
AutoMigrateemitsdocScope, the migration emittedidx_restcol_documents_docscope, both over(model_project_id, model_collection_id, created_at). Same story for the two collection indexes.Because
CREATE INDEX IF NOT EXISTSmatches on name and the names differ, its guard never fired. Applying it produced a second index over identical columns rather than doing nothing:Six indexes where three suffice — write throughput and disk for no read benefit. Evidence: FootprintAI/grandturks#986.
So
0001was not merely unapplied, which is what FootprintAI/grandturks#984 concluded from the manifests. It was better left unapplied.Why delete rather than rename its indexes to match
A migration that re-declares what the models already declare is a second source of truth for one schema — and the models are the copy that services actually run. Renaming would keep both in sync by hand forever.
The README now says so, so nobody re-adds it:
Why 0003 as well
Deleting
0001stops the duplicates being created; it does not remove them where they exist. And they do exist: FootprintAI/grandturks#987 added a demo-box runner that applies everymigrations/*.up.sqlin order, so any box brought up on an existing volume since then has them.0003drops only the migration-created names. TheAutoMigrateones are the real indexes and stay — the two sets are distinguishable because GORM quotes the hyphenated table name (idx_restcol-collections_…) where0001used underscores (idx_restcol_collections_…).Its down migration is a documented no-op, as with
0002: recreating duplicates would restore the problem, so a truthful revert does nothing.Verified end to end on a real postgres
AutoMigrate→ 3 indexes0001to reproduce the damaged state → 6 indexes0003→ 3 indexes, and confirmed the survivors areAutoMigrate's over the expected columns0003→ no-opNumbering is not reused (
0003follows0002), so no environment that recorded a version sees a different migration under an old number.For consumers
grandturks copies these files into
deploy/demo/restcol-migrations/with a drift test, so it needs the copy of0001removed when it next bumps the pin. Flagging rather than leaving it to a red test.Refs: FootprintAI/grandturks#986, FootprintAI/grandturks#984, FootprintAI/grandturks#987