Re: Caching a partition index's parent OID in the relcache?

From: Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com>
To: Álvaro Herrera <alvherre(at)kurilemu(dot)de>
Cc: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Caching a partition index's parent OID in the relcache?
Date: 2026-07-17 15:41:11
Message-ID: CAJTYsWXquWQR2cY9jjfSjG7nFHhTD_GW1hFO6xnQSXBtfNk3tA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On Fri, 17 Jul 2026 at 19:38, Álvaro Herrera <alvherre(at)kurilemu(dot)de> wrote:

> Hello,
>
> On 2026-Jul-17, Ayush Tiwari wrote:
> > I tried the "other way": keep the immediate parent OID on the relcache
> > entry (a lazily-filled rd_partparent), then use the existing walker above
> > that. This avoids repeatedly scanning the leaf link and eliminates the
> > pg_inherits scan entirely for the common one-level hierarchy. Patch
> > attached (fairly small).
>
> Hmm. Why not cache the entire list of ancestors instead of just the
> immediate one? You could have a union that's either a single
> OID (for the most common case where there's only one ancestor), or a
> pointer to an array of an arbitrary number of ancestors. With such a
> system, you only have to scan pg_inherits for a relation once per
> invalidation, regardless of the number of ancestors.
>
> (Looking at pahole's output for RelationData it's obvious that nobody
> cares too much about how much memory that struct takes.)
>

The union is fine, but I don't think a full list cached on the index has
a valid invalidation. AFAICT it depends on the *ancestors'* links, and
re-parenting an intermediate index doesn't invalidate the leaf:
pg_inherits changes send no relcache inval (only
pg_class/pg_attribute/pg_index/pg_constraint do), and IndexSetParentIndex
flips only the re-parented index's own pg_class row.

-- 3-level r > m > l; warm l's index cache
INSERT INTO r VALUES (1) ON CONFLICT (i) DO NOTHING;
NOTICE: FILL l_pkey ancestors=[m_pkey r_pkey]
ALTER TABLE r DETACH PARTITION m;
ALTER TABLE r2 ATTACH PARTITION m ...; -- m_pkey now under r2_pkey
INSERT INTO r2 VALUES (2) ON CONFLICT (i) DO NOTHING;
NOTICE: HIT l_pkey cached=[m_pkey r_pkey] live=[m_pkey r2_pkey] <-STALE

l_pkey is never invalidated, so the cached list keeps r_pkey and
ExecInitPartitionInfo() would pick the wrong arbiter. The
immediate-parent cache dodges this: it stores only the leaf's own parent
(invalidated when it changes) and walks the rest live.

To make a full list safe we'd need a new invalidation path that, on any
index re-parent, invalidates the whole descendant-index subtree rather
than just the re-parented index, and it only helps 3+ level
hierarchies. Should I explore that?

Regards,
Ayush

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message 신성준 2026-07-17 15:54:53 Re: Add wait events for server logging destination writes
Previous Message Andres Freund 2026-07-17 15:40:14 Re: Heads Up: cirrus-ci is shutting down June 1st