public inbox for [email protected]  
help / color / mirror / Atom feed
From: Kirill Reshke <[email protected]>
To: Amit Langote <[email protected]>
Cc: PostgreSQL-development <[email protected]>
Subject: Re: GetCachedPlan() refactor: move execution lock acquisition out
Date: Tue, 14 Apr 2026 21:08:04 +0500
Message-ID: <CALdSSPh=8qLa1kPsBUnPXMmigaCABiNTwmwg1wH+TmQWH=f_Ww@mail.gmail.com> (raw)
In-Reply-To: <CA+HiwqE1ntHy2h9zJ9v3MwAkoGAveSERcHWkDTTZnP0kxWqbKQ@mail.gmail.com>
References: <CA+HiwqE1ntHy2h9zJ9v3MwAkoGAveSERcHWkDTTZnP0kxWqbKQ@mail.gmail.com>

On Tue, 14 Apr 2026 at 13:20, Amit Langote <[email protected]> wrote:
>
> Over in the "generic plans and initial pruning" thread [1], I came to
> think that the cleanest way to address the architectural issue behind
> that thread is to make GetCachedPlan() do less execution-related work.
> Specifically, it should stop acquiring execution locks itself, and
> leave that decision to callers.
>
> GetCachedPlan() has long combined plan acquisition with execution
> setup, and that coupling makes it harder to improve either side
> cleanly. Tom pointed in this direction back in 2023 [2]:
>
> "...the whole problem arises because the system is wrongly factored.
> We should get rid of AcquireExecutorLocks altogether, allowing the
> plancache to hand back a generic plan that it's not certain of the
> validity of, and instead integrate the responsibility for acquiring
> locks into executor startup."
>
> This patch takes the first half of that suggestion by moving execution
> locking out of the plancache and into its callers.
>
> The attached patch does that, with no intended behavioral change:
>
> * Remove AcquireExecutorLocks() from CheckCachedPlan(), so
> GetCachedPlan() returns a plan without holding execution locks.
>
> * Add a new internal helper in plancache.c, LockCachedPlan(), which
> acquires execution locks, rechecks validity, and returns false if the
> plan was invalidated, so the caller can retry.
>
> * Add GetCachedPlanLocked() as a convenience wrapper that fetches a
> plan, calls LockCachedPlan(), and retries on invalidation. This
> becomes the normal entry point for callers that want a plan ready for
> execution.
>
> * Convert existing GetCachedPlan() callers to use GetCachedPlanLocked().
>
> The second half of Tom's suggestion, moving that responsibility into
> executor startup, is trickier. ExecutorStart() is a stable API with
> extension hooks, so changing its contract has a fairly high bar. I
> tried that route once already [3].
>
> A working variant that adds an ExecutorPrep() entry point, with a
> wrapper implementing pruning-aware locking on top, was discussed in
> the original thread [1].  But rather than propose that whole stack at
> once, I think it is better to do this in phases: first decouple plan
> acquisition from execution locking, then revisit the ExecutorPrep()
> piece separately if this goes in.
>
> The eventual goal is still pruning-aware locking. I'm posting this
> piece separately because the original thread has become fairly long,
> and this part seems easier to review on its own.
>
> [1] https://postgr.es/m/CA+HiwqFGkMSge6TgC9KQzde0ohpAycLQuV7ooitEEpbKB0O_mg@mail.gmail.com
> [2] https://postgr.es/m/4191508.1674157166%40sss.pgh.pa.us
> [3] https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=1722d5eb05d8e5d2e064cd1798abcae4f296c...
>
> --
> Thanks, Amit Langote


Hi! I have slightly checked v1. Can't tell if refactoring does make
cached plan maintenance more straightforward because of lack of
experience in this area, but here's my 2c

> +
> + for (;;)
> + {
> + cplan = GetCachedPlan(plansource, boundParams, owner, queryEnv);
> + if (LockCachedPlan(cplan))
> + break;
> +
> + ReleaseCachedPlan(cplan, owner);
> + }

Should we use CFI here?

> +static bool
> +LockCachedPlan(CachedPlan *cplan)
> +{
> + AcquireExecutorLocks(cplan->stmt_list, true);
> + if (!cplan->is_valid)
> + {
> + AcquireExecutorLocks(cplan->stmt_list, false);
> + return false;
> + }
> + return true;
> +}

simply `return cplan->is_valid ` would be more Postgres-y here, isnt it?

-- 
Best regards,
Kirill Reshke





view thread (6+ messages)  latest in thread

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: [email protected]
  Cc: [email protected], [email protected]
  Subject: Re: GetCachedPlan() refactor: move execution lock acquisition out
  In-Reply-To: <CALdSSPh=8qLa1kPsBUnPXMmigaCABiNTwmwg1wH+TmQWH=f_Ww@mail.gmail.com>

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

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