Skip to content

store: Create postponed indexes in the background#6608

Merged
lutter merged 5 commits into
masterfrom
lutter/postpone
Jun 3, 2026
Merged

store: Create postponed indexes in the background#6608
lutter merged 5 commits into
masterfrom
lutter/postpone

Conversation

@lutter
Copy link
Copy Markdown
Collaborator

@lutter lutter commented May 29, 2026

When a deployment is first created, creation of some attribute indexes is postponed until the subgraph nears the chain head. That work was previously run inline on the block-processing path: the runner awaited create_postponed_indexes, so indexing stalled while the (potentially long-running) CREATE INDEX CONCURRENTLY statements executed.

This PR moves index creation into a background task so block processing continues uninterrupted, and hardens the retry path against invalid indexes left behind by interrupted runs.

A CREATE INDEX CONCURRENTLY that is interrupted (e.g. by a node restart while the build is in flight) leaves behind an invalid index in Postgres. Because postponed indexes are created with IF NOT EXISTS, that leftover would be skipped on retry and never rebuilt, silently leaving the deployment without the index once the flag eventually flips to true.

Index-creation failures are now logged rather than propagated. Previously a failure errored out the subgraph (forcing a restart-and-retry); now the subgraph keeps indexing and the work is retried on the next deployment start (the flag stays false until success).

@lutter lutter force-pushed the lutter/postpone branch from 656d9ed to 5e691b9 Compare May 30, 2026 23:58
lutter added 5 commits June 3, 2026 11:46
The runner used to block block processing while postponed indexes were
created. Since these are built with CREATE INDEX CONCURRENTLY and can take
a long time, spawn the work in a background task so indexing continues.

Errors are only logged; the postponed_indexes_created flag is set only on
success, so a failed run is retried the next time the deployment starts.
A CREATE INDEX CONCURRENTLY that is interrupted (e.g. by a node restart)
leaves an invalid index behind. Because postponed indexes are created with
'if not exists', such a leftover was skipped on retry and never rebuilt,
silently leaving the deployment without that index.

Before creating each postponed index, drop any invalid remnant so the
retry rebuilds it, mirroring what create_manual_index already does.
Acquire a fresh connection for each postponed index instead of holding
one for the whole run, which can take hours. Before starting a
`CREATE INDEX CONCURRENTLY`, wait for any index creation already running
in the deployment's schema to finish, using `index_creation_is_running`
to poll `pg_stat_progress_create_index`.

Have CreateIndex::name return a string slice to avoid an allocation.
This should avoid starving normal subgraph progress if many subgraphs
create indexes
@lutter lutter force-pushed the lutter/postpone branch from 7efcf62 to 51cd0b5 Compare June 3, 2026 19:00
@lutter lutter merged commit 51cd0b5 into master Jun 3, 2026
6 checks passed
@lutter lutter deleted the lutter/postpone branch June 3, 2026 19:06
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.

2 participants