From 63c44878957196abfa124b17fe0ddae339e78f14 Mon Sep 17 00:00:00 2001 From: Hayato Kuroda Date: Wed, 7 Oct 2026 15:56:06 +0900 Subject: [PATCH v6 2/4] Avoid adding leader apply context to parallel worker errors Errors from parallel apply workers are relayed through the leader apply worker. Before reporting such an error, ProcessParallelApplyMessage() replaces error_context_stack with a stack saved by LogicalRepApplyLoop(). This avoids running callbacks installed temporarily by whatever the leader is doing when the error arrives. Commit 216a784829c saved that stack after pushing apply_error_callback, intentionally retaining the error context callbacks in effect inside LogicalRepApplyLoop(). However, apply_error_callback describes the leader's own apply state, including its current relation, remote transaction, and replication message. If the leader is applying another transaction when a parallel worker reports an error, the callback therefore adds a misleading CONTEXT line describing the leader's unrelated work. The error relayed from the parallel worker already contains the context of the operation that failed, so running the leader's apply_error_callback provides no useful information. Reverse this part of the choice made by 216a784829c by saving error_context_stack before pushing apply_error_callback. This preserves callbacks outside LogicalRepApplyLoop() while excluding the leader's unrelated apply context. --- .../replication/logical/applyparallelworker.c | 6 +++--- src/backend/replication/logical/worker.c | 13 ++++++++++--- src/include/replication/worker_internal.h | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/backend/replication/logical/applyparallelworker.c b/src/backend/replication/logical/applyparallelworker.c index 96bf499e49c..6a8b91df9d8 100644 --- a/src/backend/replication/logical/applyparallelworker.c +++ b/src/backend/replication/logical/applyparallelworker.c @@ -1046,10 +1046,10 @@ ProcessParallelApplyMessage(StringInfo msg) edata.context = pstrdup(_("logical replication parallel apply worker")); /* - * Context beyond that should use the error context callbacks - * that were in effect in LogicalRepApplyLoop(). + * Use the callbacks saved before the leader's apply error + * context callback was installed. */ - error_context_stack = apply_error_context_stack; + error_context_stack = apply_loop_outer_error_context_stack; /* * The actual error must have been reported by the parallel diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index 37b37500213..a1452686ef1 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -483,7 +483,12 @@ static ApplyRemoteCtx remote_ctx = .origin_name = NULL, }; -ErrorContextCallback *apply_error_context_stack = NULL; +/* + * Error context stack outside LogicalRepApplyLoop(), before + * apply_error_callback is pushed. Used when the leader reports an error + * propagated from a parallel apply worker. + */ +ErrorContextCallback *apply_loop_outer_error_context_stack = NULL; MemoryContext ApplyMessageContext = NULL; MemoryContext ApplyContext = NULL; @@ -4081,6 +4086,9 @@ LogicalRepApplyLoop(XLogRecPtr last_received) /* mark as idle, before starting to loop */ pgstat_report_activity(STATE_IDLE, NULL); + /* Preserve the error context stack outside the apply loop. */ + apply_loop_outer_error_context_stack = error_context_stack; + /* * Push apply error context callback. Fields will be filled while applying * a change. @@ -4088,7 +4096,6 @@ LogicalRepApplyLoop(XLogRecPtr last_received) errcallback.callback = apply_error_callback; errcallback.previous = error_context_stack; error_context_stack = &errcallback; - apply_error_context_stack = error_context_stack; /* This outer loop iterates once per wait. */ for (;;) @@ -4357,7 +4364,7 @@ LogicalRepApplyLoop(XLogRecPtr last_received) /* Pop the error context stack */ error_context_stack = errcallback.previous; - apply_error_context_stack = error_context_stack; + apply_loop_outer_error_context_stack = error_context_stack; /* All done */ walrcv_endstreaming(LogRepWorkerWalRcvConn, &tli); diff --git a/src/include/replication/worker_internal.h b/src/include/replication/worker_internal.h index 88cb7c1e252..febe255c902 100644 --- a/src/include/replication/worker_internal.h +++ b/src/include/replication/worker_internal.h @@ -238,7 +238,7 @@ extern PGDLLIMPORT MemoryContext ApplyContext; extern PGDLLIMPORT MemoryContext ApplyMessageContext; -extern PGDLLIMPORT ErrorContextCallback *apply_error_context_stack; +extern PGDLLIMPORT ErrorContextCallback *apply_loop_outer_error_context_stack; extern PGDLLIMPORT ParallelApplyWorkerShared *MyParallelShared; -- 2.52.0