| 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
| 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 |