Re: generic plans and "initial" pruning

From: Amit Langote <amitlangote09(at)gmail(dot)com>
To: Junwang Zhao <zhjwpku(at)gmail(dot)com>
Cc: Robert Haas <robertmhaas(at)gmail(dot)com>, Alvaro Herrera <alvherre(at)alvh(dot)no-ip(dot)org>, Andres Freund <andres(at)anarazel(dot)de>, Daniel Gustafsson <daniel(at)yesql(dot)se>, David Rowley <dgrowleyml(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>, Thom Brown <thom(at)linux(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Subject: Re: generic plans and "initial" pruning
Date: 2024-09-05 09:55:47
Message-ID: CA+HiwqGSOge3eT3kcm_nxCSA3Ut+d0jtchi8g8J9uXi-kyC7Jw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon, Sep 2, 2024 at 5:19 PM Amit Langote <amitlangote09(at)gmail(dot)com> wrote:
> On Sat, Aug 31, 2024 at 9:30 PM Junwang Zhao <zhjwpku(at)gmail(dot)com> wrote:
> > @@ -1241,7 +1244,7 @@ GetCachedPlan(CachedPlanSource *plansource,
> > ParamListInfo boundParams,
> > if (customplan)
> > {
> > /* Build a custom plan */
> > - plan = BuildCachedPlan(plansource, qlist, boundParams, queryEnv);
> > + plan = BuildCachedPlan(plansource, qlist, boundParams, queryEnv, true);
> >
> > Is the *true* here a typo? Seems it should be *false* for custom plan?
>
> That's correct, thanks for catching that. Will fix.

Done.

I've also rewritten the new GetSingleCachedPlan() function in 0003.
The most glaring bug in the previous version was that the transient
CachedPlan it creates cannot be seen by PlanCacheRelCallback() et al
functions because it was intentionally not linked to the
CachedPlanSource, so if the CachedPlan would not be invalidated even
if some prunable relation got changed before it is locked during
ExecutorStart(). I've added a new list standalone_plan_list to add
these to and changed the inval callback functions to invalidate any
plans contained in them.

Another thing I found out through testing is that CachedPlanSource can
have become invalid since leaving GetCachedPlan() (actually even
before returning from that function) because of
PlanCacheSysCallback(), which drops/invalidates *all* plans when a
syscache is invalidated. There are comments in plancache.c (see
BuildCachedPlan()) saying that such invalidations are, in theory,
false positives, but that gave me a pause nonetheless.

Finally, instead of calling GetCachedPlan() from GetSingleCachedPlan()
to create a plan for only the query whose plan got invalidated, which
required a bunch of care to ensure that the CachedPlanSource is not
overwritten with the information about this single-query planning,
I've made GetSingleCachedPlan() create the PlannedStmt and the
detached CachedPlan object on its own, borrowing the minimal necessary
code from BuildCachedPlan() to do so.

--
Thanks, Amit Langote

Attachment Content-Type Size
v52-0001-Defer-locking-of-runtime-prunable-relations-to-e.patch application/octet-stream 32.8 KB
v52-0002-Assorted-tightening-in-various-ExecEnd-routines.patch application/octet-stream 31.3 KB
v52-0003-Handle-CachedPlan-invalidation-in-the-executor.patch application/octet-stream 92.1 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Amit Kapila 2024-09-05 10:34:16 Re: long-standing data loss bug in initial sync of logical replication
Previous Message Aleksander Alekseev 2024-09-05 09:41:42 Re: [PATCH] Add roman support for to_number function