Checkpoints stuck after a failed bulk write inside a savepoint

From: shihao zhong <zhong950419(at)gmail(dot)com>
To: pgsql-hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Cc: Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
Subject: Checkpoints stuck after a failed bulk write inside a savepoint
Date: 2026-11-03 05:02:30
Message-ID: CAGRkXqQ=W7TE2c+hpcBADdRYs0Vvdvcz51aV3gSwtQeBsPL=xg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi hackers,

smgr_bulk_finish() sets DELAY_CHKPT_START outside a critical section
and then calls smgrregistersync(). That call can raise an ERROR, for
example when lseek() fails on a bad disk or memory runs out.

If a savepoint catches that error, the flag stays set.
AbortSubTransaction()
does not clear the flag. So every checkpoint waits in CheckpointDelayStart
until the transaction ends. With assertions enabled, COMMIT fails an Assert.

TRAP: failed Assert("(MyProc->delayChkptFlags & DELAY_CHKPT_IN_COMMIT) ==
0"),
File: "xact.c", Line: 1473

The flag closes a gap between reading the redo pointer and registering
the sync request.

0001 removes the gap instead. It registers the request first and then
checks
the redo pointer. If the pointer has not moved, a later checkpoint will
pick up
our request before it syncs. If it has moved, we fsync the file ourselves
as
before. So the flag is not needed.

The patch is the fix only and the noncfbot-repro.patch include the
injection point
and reproduction.

Thanks,
Shihao

Attachment Content-Type Size
noncfbot-repro.patch application/octet-stream 4.3 KB
v1-0001-Avoid-DELAY_CHKPT_START-in-smgr_bulk_finish.patch application/octet-stream 2.2 KB

Browse pgsql-hackers by date

  From Date Subject
Next Message Chao Li 2026-11-03 05:21:17 extension_control_path: ignore empty elements and deduplicate directories
Previous Message Raja Sai pranav 2026-11-03 04:56:32 Re: Re: Assertion failure in WAL summarizer