Skip to content

Return B_SYSTEM_BG_WORKER slots to the bgworker pool on release#74

Open
ironman5366 wants to merge 1 commit into
orioledb:patches18from
ironman5366:will/fix-system-bgworker-slot-release
Open

Return B_SYSTEM_BG_WORKER slots to the bgworker pool on release#74
ironman5366 wants to merge 1 commit into
orioledb:patches18from
ironman5366:will/fix-system-bgworker-slot-release

Conversation

@ironman5366

Copy link
Copy Markdown

See orioledb/orioledb#979.

The below, and the patch, is written by Claude, and I don't have enough context on the codebase to vouch for it. Apologies if it is slop, I am leaving in case it is useful given it does seem to fix the issue I encountered:


System background workers (BGWORKER_CLASS_SYSTEM, used by orioledb's S3 workers) get their postmaster child slot from the B_BG_WORKER pool in do_start_bgworker() and are then retyped to B_SYSTEM_BG_WORKER so the shutdown state machine lets them keep running. On exit, however, ReleasePostmasterChildSlot() returned the slot to the pool of the current backend type: the separate size-1 B_SYSTEM_BG_WORKER pool that nothing ever allocates from. The slot number is from the B_BG_WORKER range, so the pool range sanity check failed and the postmaster itself exited with 'pmchild freelist for backend type 6 is corrupt' - any S3 worker exit (a clean SIGTERM, or the FATAL that any S3 request error raises) took down the entire cluster.

Remap B_SYSTEM_BG_WORKER to the B_BG_WORKER pool on release, exactly like the B_WAL_SENDER -> B_BACKEND remap above it, and drop the unused (and mis-sized: there can be s3_num_workers of these) size-1 pool. B_WAL_SENDER analogously has no pool of its own, and AssignPostmasterChildSlot() reports an error for zero-size pools if anything ever tries to allocate from it directly.

Reproduced by test/t/s3_transient_error_test.py (orioledb repo): one injected 500 on one S3 PUT kills the whole cluster on PG18 builds, while PG17 builds (no pmchild.c, no B_SYSTEM_BG_WORKER) survive the same event with a worker restart.

System background workers (BGWORKER_CLASS_SYSTEM, used by orioledb's S3
workers) get their postmaster child slot from the B_BG_WORKER pool in
do_start_bgworker() and are then retyped to B_SYSTEM_BG_WORKER so the
shutdown state machine lets them keep running. On exit, however,
ReleasePostmasterChildSlot() returned the slot to the pool of the
current backend type: the separate size-1 B_SYSTEM_BG_WORKER pool that
nothing ever allocates from. The slot number is from the B_BG_WORKER
range, so the pool range sanity check failed and the postmaster itself
exited with 'pmchild freelist for backend type 6 is corrupt' - any S3
worker exit (a clean SIGTERM, or the FATAL that any S3 request error
raises) took down the entire cluster.

Remap B_SYSTEM_BG_WORKER to the B_BG_WORKER pool on release, exactly
like the B_WAL_SENDER -> B_BACKEND remap above it, and drop the unused
(and mis-sized: there can be s3_num_workers of these) size-1 pool.
B_WAL_SENDER analogously has no pool of its own, and
AssignPostmasterChildSlot() reports an error for zero-size pools if
anything ever tries to allocate from it directly.

Reproduced by test/t/s3_transient_error_test.py (orioledb repo): one
injected 500 on one S3 PUT kills the whole cluster on PG18 builds,
while PG17 builds (no pmchild.c, no B_SYSTEM_BG_WORKER) survive the
same event with a worker restart.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants