Skip to content

fix(migration): drop CONCURRENTLY in 000165 — golang-migrate wraps ea…#64

Merged
0xmanhnv merged 1 commit into
mainfrom
develop
Apr 28, 2026
Merged

fix(migration): drop CONCURRENTLY in 000165 — golang-migrate wraps ea…#64
0xmanhnv merged 1 commit into
mainfrom
develop

Conversation

@0xmanhnv
Copy link
Copy Markdown
Collaborator

…ch file in a tx

golang-migrate executes every up.sql inside a single transaction unless explicitly told otherwise. CREATE INDEX CONCURRENTLY refuses to run inside a transaction, so 000165's third statement aborted the migration:

error: migration failed: CREATE INDEX CONCURRENTLY cannot run
inside a transaction block in line 0

Symptoms: API container failed migrate-up on startup; prod deploy of main would have left schema_migrations stuck at 165 dirty=true with no index. Local was already in this state — we cleared the dirty flag manually and re-applied the fixed migration.

Fix: regular CREATE INDEX inside the same BEGIN/COMMIT block as the ALTER TABLE statements. The assets table is small enough at launch that a brief AccessExclusiveLock during index build is acceptable. If/when scale grows past ~10M rows, ship a follow-up migration that drops this index and recreates it CONCURRENTLY out of band (run via psql, never through migrate-up).

Reference comment in 000099_asset_performance_indexes.up.sql documented the same constraint two years ago — this one slipped through review because the file was structured with the intent of splitting transactions internally, which the runner does not honour.

…ch file in a tx

golang-migrate executes every up.sql inside a single transaction
unless explicitly told otherwise. CREATE INDEX CONCURRENTLY refuses
to run inside a transaction, so 000165's third statement aborted
the migration:

  error: migration failed: CREATE INDEX CONCURRENTLY cannot run
  inside a transaction block in line 0

Symptoms: API container failed migrate-up on startup; prod deploy
of main would have left schema_migrations stuck at 165 dirty=true
with no index. Local was already in this state — we cleared the
dirty flag manually and re-applied the fixed migration.

Fix: regular CREATE INDEX inside the same BEGIN/COMMIT block as
the ALTER TABLE statements. The assets table is small enough at
launch that a brief AccessExclusiveLock during index build is
acceptable. If/when scale grows past ~10M rows, ship a follow-up
migration that drops this index and recreates it CONCURRENTLY out
of band (run via psql, never through migrate-up).

Reference comment in 000099_asset_performance_indexes.up.sql
documented the same constraint two years ago — this one slipped
through review because the file was structured with the intent of
splitting transactions internally, which the runner does not honour.
@0xmanhnv 0xmanhnv merged commit 3d474df into main Apr 28, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant