From dbdbd2dad1d449b1d23af3a1e5414077af0f194c Mon Sep 17 00:00:00 2001 From: shihao zhong Date: Wed, 14 Oct 2026 08:22:27 -0400 Subject: [PATCH v2 1/2] Absorb ProcSignalBarriers while waiting for the client A backend blocked writing to or reading from a client that stopped responding never absorbed barriers, so promotion, standby replay and DROP DATABASE waited for it without limit. Absorb them in that wait. We may be in the middle of a message, so make any error FATAL. Diagnosed-by: Manuel Reyes Bravo --- src/backend/tcop/postgres.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index b6bdfe213fe..0c5fcd9db92 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -502,6 +502,34 @@ ReadCommand(StringInfo inBuf) return result; } +/* + * Absorb ProcSignalBarriers while blocked on a client read or write, so that + * a client that stops sending or reading can't hold up the processes waiting + * for them. We might be in the middle of a protocol message, so make any + * error FATAL and don't send it to the client. + */ +static void +ProcessClientBarrierInterrupt(void) +{ + bool save_ExitOnAnyError; + CommandDest save_whereToSendOutput; + + if (!ProcSignalBarrierPending || + InterruptHoldoffCount != 0 || CritSectionCount != 0) + return; + + save_ExitOnAnyError = ExitOnAnyError; + save_whereToSendOutput = whereToSendOutput; + ExitOnAnyError = true; + if (whereToSendOutput == DestRemote) + whereToSendOutput = DestNone; + + ProcessProcSignalBarrier(); + + ExitOnAnyError = save_ExitOnAnyError; + whereToSendOutput = save_whereToSendOutput; +} + /* * ProcessClientReadInterrupt() - Process interrupts specific to client reads * @@ -544,6 +572,8 @@ ProcessClientReadInterrupt(bool blocked) else SetLatch(MyLatch); } + else if (blocked) + ProcessClientBarrierInterrupt(); errno = save_errno; } @@ -596,6 +626,8 @@ ProcessClientWriteInterrupt(bool blocked) else SetLatch(MyLatch); } + else if (blocked) + ProcessClientBarrierInterrupt(); errno = save_errno; } -- 2.37.1 (Apple Git-137.1)