| From: | Manu <manuelreyesbravo(at)gmail(dot)com> |
|---|---|
| To: | Amit Langote <amitlangote09(at)gmail(dot)com> |
| Cc: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Subject: | Re: generic plans and "initial" pruning |
| Date: | 2026-09-23 00:15:41 |
| Message-ID: | 179012254111.1322729.3152961925110452673@gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
Ilmar asked in July whether he was reading the ownership mismatch
correctly, and the entry has been waiting since. He is, and the tree
says so in four places. On v13 applied to master:
prepare.c:198 ExecuteQuery
GetCachedPlan(entry->plansource, paramLI, NULL, NULL)
postgres.c:2055 exec_bind_message
GetCachedPlan(psrc, params, NULL, NULL)
portalmem.c PortalReleaseCachedPlan
ReleaseCachedPlan(portal->cplan, NULL)
pquery.c:1867 PortalLockCachedPlan (new in 0001)
ReleaseCachedPlan(portal->cplan, portal->resowner)
The portal's reference is acquired with a NULL owner on both entry
paths and released with a NULL owner at the end, so the retry path
releasing it against portal->resowner is releasing a reference that
resource owner never owned. That is the error the CFBot prints.
There is a second half to it that has not been mentioned: three lines
below, the replacement plan is acquired with
portal->cplan = GetCachedPlan(..., portal->resowner, ...)
and that reference is the one PortalReleaseCachedPlan() will later
release with NULL. So even if the first call did not error, the new
reference is registered with a resource owner that will not release
it, and released against an owner that does not hold it. The two calls
are wrong in opposite directions.
Attached is the one-line-each change: use NULL for both, leaving
ExecutorPrepAndLock() with portal->resowner, since the locks really do
belong to it.
I could not reproduce the failure on Linux either, and I think I can
say why. I put an elog at the top of that replan branch and ran:
- the test the CFBot fails on, test_plan_advice/001_replan_regress
- make check in full
- a deliberate setup: a prepared statement on a partitioned table at
its generic plan, a second session holding ACCESS EXCLUSIVE on the
partition the plan needs, the EXECUTE blocking on that lock, and
the other session doing ALTER TABLE on it before committing, so
that the invalidation lands while the portal is already open
The branch was not reached once, in any of them. So on Linux nothing
in the suite exercises that path, which also means the new replan
branch has no test coverage here. Whatever gets there on MinGW, it is
not something the tree currently runs.
With the change, make check, test_plan_advice and the isolation suite
all pass, though given the above that says less than I would like: it
shows nothing regressed, not that the path now works. If you have a
way to reach that branch I am happy to run it.
Regards,
Manu
| Attachment | Content-Type | Size |
|---|---|---|
| nocfbot-portal-cplan-owner.diff.txt | text/plain | 1.3 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Thom Brown | 2026-09-23 00:23:11 | REPACK (CONCURRENTLY) can silently lose updates when the toast table is rewritten |
| Previous Message | Manu | 2026-09-23 00:00:41 | Re: Add a test for index_rebuild_count of REPACK (CONCURRENTLY) |