gistkillitems can LP_DEAD-mark the wrong tuples on a rescan

From: Peter Geoghegan <pg(at)bowt(dot)ie>
To: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Cc: Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
Subject: gistkillitems can LP_DEAD-mark the wrong tuples on a rescan
Date: 2026-08-15 22:06:25
Message-ID: CAH2-WzmwEThnQf17Ju+t0N9_KJLsEQSXzYrFnaS2=s4KnGGrqw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Attached patch adds a failing test case that shows wrong answers,
authored by Opus 5. The failures stem from GiST not invalidating
killedItems/numKilled across rescans: it's possible for the wrong
index tuples to have their LP_DEAD bits set due to state from a
previous rescan (namely killedItems and numKilled) getting mixed
together with state from the current rescan ( namely curBlkno and
curPageLSN). At a minimum, we should invalidate the
gistkillitems-related state across rescans.

Apparently the test case makes GiST mark index tuples that contain
downlinks in internal pages LP_DEAD, which is enough to make
gistScanPage() completely ignore whole subtrees. This is possible even
though such an index tuple should never be LP_DEAD marked in general
(obviously only tuples that point to heap TIDs should ever get
LP_DEAD-marked). gistScanPage has fairly uniform handling for leaf
pages and internal pages, which is what makes the "ignore whole
subtree" misbehavior possible.

This is *probably* only a bug on master, since only master has commit
9c9ddf109, which taught gistkillitems to run against a single-page
GiST index. However, we don't correctly reset the state on a rescan in
any version, which seems dicey even without commit 9c9ddf109.

I think that the proper fix here is have GiST deal with gistkillitems
in the same way that nbtree deals with _bt_killitems: gistkillitems
should be called in gistrescan and in gistendscan (not just in
gistgettuple), so that we correctly invalidate the state, *without*
neglecting to LP_DEAD-mark index tuples that really are dead-to-all.

--
Peter Geoghegan

Attachment Content-Type Size
0001-Add-a-test-for-GiST-killtuples-state-left-over-by-a-.patch application/octet-stream 5.3 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Peter Geoghegan 2026-08-15 23:31:01 GiST wal_consistency_checking issue
Previous Message Jeff Davis 2026-08-15 21:53:39 Re: Crash issue in PG18.5 regression