| From: | Zhijie Hou <houzhijie22(at)gmail(dot)com> |
|---|---|
| To: | "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com> |
| Cc: | vignesh C <vignesh21(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: Incorrect CONTEXT reported for errors from parallel apply worker in logical replication |
| Date: | 2026-10-08 13:45:50 |
| Message-ID: | CAFvd2n8z_Ki4H-V+g0eVZ-kvjpJn+YY7yt5hEQYW8YJSBYL8Vw@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
On Thu, Oct 8, 2026 at 3:54 PM Hayato Kuroda (Fujitsu)
<kuroda(dot)hayato(at)fujitsu(dot)com> 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
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Robert Haas | 2026-10-08 13:49:26 | Re: pgsql: Teach expr_is_nonnullable() to handle more expression types |
| Previous Message | Andrew Dunstan | 2026-10-08 13:42:09 | Re: [PG19] COPY (query) TO ... (FORMAT json) uses the table's column names |