summaryrefslogtreecommitdiff
path: root/src/backend/replication/logical/logical.c
diff options
context:
space:
mode:
authorÁlvaro Herrera <alvherre@kurilemu.de>2025-09-12 18:47:25 +0200
committerÁlvaro Herrera <alvherre@kurilemu.de>2025-09-12 18:47:25 +0200
commit7dcea51c2a4dcf7c512bbd4f618d1d3620f9d3d7 (patch)
tree8ede9809c7008a0df2643781cdf2eb2aa456d131 /src/backend/replication/logical/logical.c
parent20d541a200e9dfed8affef9e798ff35ca0f30b8e (diff)
Avoid unexpected changes of CurrentResourceOwner and CurrentMemoryContext
Users of logical decoding can encounter an unexpected change of CurrentResourceOwner and CurrentMemoryContext. The problem is that, unlike other call sites of RollbackAndReleaseCurrentSubTransaction(), in reorderbuffer.c we fail to restore the original values of these global variables after being clobbered by subtransaction abort. This patch saves the values prior to the call and restores them eventually. In addition, logical.c and logicalfuncs.c had a hack to restore resource owner, presumably because of lack of this restore. Remove that. Instead, because the test coverage here is not very consistent, add an Assert() to ensure that the resowner is kept identical; this would make it easy to detect other cases of bugs were we fail to restore resowner properly. This could be removed later. This is arguably an old bug, but there appears to be no reason to backpatch it and it's risky to do so, so refrain for now. Author: Antonin Houska <ah@cybertec.at> Reported-by: Mihail Nikalayeu <mihailnikalayeu@gmail.com> Reviewed-by: Euler Taveira <euler@eulerto.com> Discussion: https://postgr.es/m/119497.1756892972@localhost
Diffstat (limited to 'src/backend/replication/logical/logical.c')
-rw-r--r--src/backend/replication/logical/logical.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c
index 7e363a7c05b..c68c0481f42 100644
--- a/src/backend/replication/logical/logical.c
+++ b/src/backend/replication/logical/logical.c
@@ -2082,7 +2082,7 @@ LogicalSlotAdvanceAndCheckSnapState(XLogRecPtr moveto,
bool *found_consistent_snapshot)
{
LogicalDecodingContext *ctx;
- ResourceOwner old_resowner = CurrentResourceOwner;
+ ResourceOwner old_resowner PG_USED_FOR_ASSERTS_ONLY = CurrentResourceOwner;
XLogRecPtr retlsn;
Assert(moveto != InvalidXLogRecPtr);
@@ -2141,21 +2141,24 @@ LogicalSlotAdvanceAndCheckSnapState(XLogRecPtr moveto,
* might still have critical updates to do.
*/
if (record)
+ {
LogicalDecodingProcessRecord(ctx, ctx->reader);
+ /*
+ * We used to have bugs where logical decoding would fail to
+ * preserve the resource owner. That's important here, so
+ * verify that that doesn't happen anymore. XXX this could be
+ * removed once it's been battle-tested.
+ */
+ Assert(CurrentResourceOwner == old_resowner);
+ }
+
CHECK_FOR_INTERRUPTS();
}
if (found_consistent_snapshot && DecodingContextReady(ctx))
*found_consistent_snapshot = true;
- /*
- * Logical decoding could have clobbered CurrentResourceOwner during
- * transaction management, so restore the executor's value. (This is
- * a kluge, but it's not worth cleaning up right now.)
- */
- CurrentResourceOwner = old_resowner;
-
if (ctx->reader->EndRecPtr != InvalidXLogRecPtr)
{
LogicalConfirmReceivedLocation(moveto);