Repository navigation
Do not read the catalog in is_age_extension_exists() outside a live transaction - #2581
Open
SpongeRobert wants to merge 1 commit into
Open
SpongeRobert wants to merge 1 commit into
SpongeRobert wants to merge 1 commit into
Conversation
…ransaction
With age in shared_preload_libraries, post_parse_analyze runs for every
statement, the ROLLBACK of a failed transaction included. When the caches of
that backend were reset (the shared invalidation queue overflowed while it
was not reading), the cached answer of is_age_extension_exists() is gone and
get_extension_oid() misses the catcache: pg_extension and pg_class are opened
in TBLOCK_ABORT, after the resource owner of the transaction was released.
The locks are granted on the fast path and ResourceOwnerEnlarge() then fails
("called after release started"). Nothing releases those locks any more; the
backend exits with them in its PGPROC, and every later backend on that PGPROC
fails at connect with "failed to re-find shared lock object" until the
server restarts. With --enable-cassert the same path trips
Assert(IsTransactionState()) in AssertCouldGetRelation().
Return false outside a live transaction and cache nothing, so the next live
transaction asks the catalog again. Only the statements that leave a failed
transaction reach the parser there, and AGE has nothing to analyse in them.
Fixes apache#2580.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2580.
With
ageinshared_preload_libraries, thepost_parse_analyzehook runs for theROLLBACKof a failed transaction too. If the caches of that backend were reset in the meantime,is_age_extension_exists()readspg_extension(andpg_class) inTBLOCK_ABORT, after the resource owner was released:ResourceOwnerEnlarge called after release started. The locks leak into the PGPROC, and every later backend on it fails at connect withfailed to re-find shared lock objectuntil the server restarts. The mechanism, a gdb stack of the failing path and a standalone reproduction are in #2580.The fix returns
falseoutside a live transaction and caches nothing, so the next live transaction asks the catalog again. In an aborted transaction only the statements that leave it reach the parser, and AGE has nothing to analyse in them.Verified on PostgreSQL 18.6,
masteratfa109ef1dd:ROLLBACKno longer fails);make installcheck: 42 of 42 with the change;--enable-cassert(AGEPG18head,e43dc1a): without the change the reproduction tripsAssert("IsTransactionState()")inAssertCouldGetRelation()on theROLLBACK; with it, no assertion failure, no error and no XX000.No regression test is added: the failure needs a backend held stopped while another session overflows the shared invalidation queue, and then every free PGPROC taken, which
pg_regresscannot express. The same change applies cleanly toPG18(e43dc1a), where it was verified the same way.🤖 Generated with Claude Code