pg.ddx.io  pgsql-committers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Amit Langote <amitlan@postgresql.org>
To: pgsql-committers@lists.postgresql.org
Subject: pgsql: Fix RI fast-path race with REINDEX CONCURRENTLY
Date: Tue, 18 Aug 2026 08:08:03 +0000
Message-ID: <E1wwEra-000000012Ay-05r6@gemulon.postgresql.org> (raw)

Fix RI fast-path race with REINDEX CONCURRENTLY

The RI fast path reads pg_constraint.conindid before taking
RowShareLock on the referenced table.  REINDEX CONCURRENTLY can
repoint the constraint and mark the old index dead, or drop it,
between those operations.  A backend in that window does not yet
hold a relation lock, so it is not covered by REINDEX CONCURRENTLY's
waits for lockers.

Opening an index that has already been dropped produces "could not open
relation with OID".  Opening one that has only been marked dead can
produce wrong answers: the index is no longer maintained or vacuumed,
so a scan can miss a referenced row or follow a stale entry to a reused
heap line pointer.

After locking the referenced table, reload the constraint and use its
current conindid.  LockRelationOid() processes invalidation messages
after acquiring the lock, so the reload sees a committed index swap.
If the lock was already held, REINDEX CONCURRENTLY cannot mark the old
index dead or drop it until the transaction releases that lock, so
continuing to use the old conindid is safe.

Do this at both RI fast-path call sites.  Add injection-point coverage
for old indexes that have either been dropped or marked dead.

Author: Mihail Nikalayeu <mihailnikalayeu@gmail.com>
Discussion: https://postgr.es/m/CADzfLwUJiVuv69uwuF5z4TrMhNkVwQUXW03q+uVNwmYFLtjEhw@mail.gmail.com
Backpatch-through: 19

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/d02a9084d91015547b831385fc007b6ac0161be5

Modified Files
--------------
src/backend/commands/indexcmds.c                   |   1 +
src/backend/utils/adt/ri_triggers.c                |  20 +++
src/test/modules/injection_points/Makefile         |   1 +
.../expected/ri_fastpath_reindex.out               | 171 +++++++++++++++++++++
src/test/modules/injection_points/meson.build      |   1 +
.../specs/ri_fastpath_reindex.spec                 | 108 +++++++++++++
6 files changed, 302 insertions(+)



view thread (2+ messages)

Message-ID: <E1wwEra-000000012Ay-05r6@gemulon.postgresql.org>
Permalink:  ../E1wwEra-000000012Ay-05r6@gemulon.postgresql.org/
Also on:    postgresql.org/message-id/E1wwEra-000000012Ay-05r6@gemulon.postgresql.org

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-committers@postgresql.org
  Cc: amitlan@postgresql.org, pgsql-committers@lists.postgresql.org
  Subject: Re: pgsql: Fix RI fast-path race with REINDEX CONCURRENTLY
  In-Reply-To: <E1wwEra-000000012Ay-05r6@gemulon.postgresql.org>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox