Skip to content

Fixed error with indexes when index is dropped during query - #549

Closed
Laykou wants to merge 1 commit into
ankane:masterfrom
Laykou:fix-indexes-dropped-index
Closed

Laykou wants to merge 1 commit into
ankane:masterfrom
Laykou:fix-indexes-dropped-index

Conversation

@Laykou

@Laykou Laykou commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Hi @ankane , thanks for PgHero!

indexes raises NoMethodError: undefined method 'sub' for nil (lib/pghero/methods/indexes.rb:157) when an index is dropped while the query runs. The pg_index row is still visible in the query's snapshot, but pg_get_indexdef(i.indexrelid) reads the current catalog and returns NULL, so columns, using and definition are all NULL for that row. We hit it on the dashboard of a database with thousands of indexes that are created and dropped at runtime (4.0.1, Postgres 18.6).

Deterministic reproduction:

# setup: CREATE TABLE pghero_race (id integer); CREATE INDEX pghero_race_index ON pghero_race (id);
database = PgHero.databases[:primary]
model = database.send(:connection_model)
model.transaction(isolation: :repeatable_read) do
  model.connection.select_value("SELECT 1") # take the snapshot
  # in another session: DROP INDEX pghero_race_index;
  database.indexes # NoMethodError: undefined method 'sub' for nil
end

This PR skips rows whose index no longer exists. With it, the reproduction returns the remaining indexes and leaves the dropped one out. The same race could also reach index[:definition].sub(...) in index_bloat.html.erb if you want the same guard there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ankane ankane closed this in 587966a Oct 18, 2026
@ankane

ankane commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Thanks @Laykou, merged with a fix for index_bloat in the commit above.

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