You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A second cancel of a parallel_export_parquet to s3:// turns the dispatcher's error into "errstart was not called" #1741
Found while reviewing #1727, and measured on its parent code, so it is not that PR's.
What happens. Cancelling a parallel_export_parquet to an s3:// prefix a second time, while the first cancel's cleanup is still running, makes the dispatcher report
ERROR: errstart was not called
in place of its own error, in 4 runs of 4 on PG17 (a cassert build). One cancel alone reports normally. The server log from the review shows the line beside the workers' terminate messages (logs/1727/hung-store-terminate-workers-head.log, line 175, in the reviewer's scratch).
Likely cause, unverified: a FlushErrorState() in the object-store module's delete path, which drops the error state that ereport is still building when the second cancel arrives during cleanup. Nobody has confirmed it in the code yet.
Next step: a red test that cancels twice and requires the dispatcher's own message (and no errstart was not called in the server log), then the fix.
The direct evidence is in the reviewer's break-parentcode.log (#1727's parent code): [double-cancel] result: ERROR: errstart was not called, on both double-cancel runs in that log. break-head.log shows the same on #1727's head.
@jdatcmd I'll take this, since it's next to #1722/#1727. The cause checks out in the code. pexport_cleanup runs under PG_ENSURE_ERROR_CLEANUP, i.e. inside the dispatcher's PG_CATCH, with its error still on the errordata stack. pexport_remove_outputs then calls the module's DELETE, whose best-effort PG_CATCH calls FlushErrorState() (objstore/columnar_objstore_module.c:2664). With one cancel the DELETE succeeds and nothing is flushed. A second cancel interrupts the DELETE inside os_wait, the inner error is caught, and FlushErrorState() resets the whole stack, the dispatcher's error included. PG_RE_THROW then finds no error: "errstart was not called".
objstore_sink_abort (:2180) has the same shape, and the writers call it from their own PG_CATCH, so it predates #1727 too.
Plan, test-first: an arm that cancels twice and requires the dispatcher's own 57014 message plus no "errstart was not called" in the server log, red on main. The fix will be HOLD_INTERRUPTS() around best-effort cleanup I/O run while an error is in flight, and no stack-wide flush there.
Activity
jdatcmd commentedon Oct 22, 2026
The direct evidence is in the reviewer's
break-parentcode.log(#1727's parent code):[double-cancel] result: ERROR: errstart was not called, on both double-cancel runs in that log.break-head.logshows the same on #1727's head.OffgridwithJD commentedon Oct 22, 2026
@jdatcmd I'll take this, since it's next to #1722/#1727. The cause checks out in the code.
pexport_cleanupruns underPG_ENSURE_ERROR_CLEANUP, i.e. inside the dispatcher'sPG_CATCH, with its error still on the errordata stack.pexport_remove_outputsthen calls the module's DELETE, whose best-effortPG_CATCHcallsFlushErrorState()(objstore/columnar_objstore_module.c:2664). With one cancel the DELETE succeeds and nothing is flushed. A second cancel interrupts the DELETE insideos_wait, the inner error is caught, andFlushErrorState()resets the whole stack, the dispatcher's error included.PG_RE_THROWthen finds no error: "errstart was not called".objstore_sink_abort(:2180) has the same shape, and the writers call it from their ownPG_CATCH, so it predates #1727 too.Plan, test-first: an arm that cancels twice and requires the dispatcher's own 57014 message plus no "errstart was not called" in the server log, red on main. The fix will be
HOLD_INTERRUPTS()around best-effort cleanup I/O run while an error is in flight, and no stack-wide flush there.🤖 Generated with Claude Code
fix: a second cancel during a remote export's cleanup keeps the expor…
fix: a cancelled remote parallel export aborts the uploads its worker…
fix: a second cancel during a remote export's cleanup keeps the expor…
fix: a cancelled remote parallel export aborts the uploads its worker…