Hi,

On Thu, Oct 8, 2026 at 3:54 PM Hayato Kuroda (Fujitsu)
<[email protected]> wrote:
>
> Dear Vignesh,
>
> > While reviewing another thread at [1], I found an issue where an error
> > relayed from a parallel apply worker can get an unrelated CONTEXT line
> > from the leader process.
> > ProcessParallelApplyMessage() in applyparallelworker.c sets
> > error_context_stack to the leader's apply_error_context_stack before
> > calling ereport(ERROR). As a result, when errfinish() processes the
> > error, the leader's error context callback runs again and adds the
> > leader's current replication context. This can be incorrect if the
> > leader is processing a different transaction when it receives the
> > error from the parallel worker.
>
> Good catch and agreed your analysis.
>
> I checked other examples in core, and parallel query seems to handle 
> correctly.
> It has an attribute ParallelContext::error_context_stack which preserves an 
> error
> context at that time, see CreateParallelContext(). When the parallel worker 
> raises
> an ERROR, the leader backend can consume its message and raise it again, and 
> at
> that time the error context is restored from the ParallelContext.
>
> I think the easiest fix is to use apply_error_context_stack for preserving the
> error context before entering the loop, attached patch implements the idea.
> IIUC no contexts can be stacked at the begining of the worker, i.e.,
> apply_error_context_stack can be NULL in any case. So the global variable can 
> be
> removed if we clean up more aggressively. I also felt the name can be changed,
> but it's retained for now because the variable has been exposed.

I think it makes sense to preserve the error context before the loop, to be
consistent with what parallel query does.

But I think we'd better simply save the error context to
apply_error_context_stack before adding the error callback as that
looks better than
indirectly getting the previous one after adding a new one, and it can save
readers a few cycles. E.g.,

+apply_error_context_stack = error_context_stack;
errcallback.callback = apply_error_callback;
...

Best Regards,
Zhijie Hou


Reply via email to