Re: hang during shutdown

From: Anthonin Bonnefoy <anthonin(dot)bonnefoy(at)datadoghq(dot)com>
To: Jeremy Schneider <schneider(at)ardentperf(dot)com>
Cc: Jakub Wartak <jakub(dot)wartak(at)enterprisedb(dot)com>, Srinath Reddy Sadipiralla <srinath2133(at)gmail(dot)com>, PostgreSQL mailing lists <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: hang during shutdown
Date: 2026-07-09 07:09:25
Message-ID: CAO6_XqrUbM+FNMHGksmezKNPftwD41EwW6Li=iqfzr-GmcF+fg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu, Jul 9, 2026 at 4:49 AM Jeremy Schneider
<schneider(at)ardentperf(dot)com> wrote:
> Between log messages and wal contents, it appears
> PostmasterStateMachine transitioned into PM_WAIT_BACKENDS but never
> progressed beyond this. I don't think walsenders are involved until it
> transitions into PM_WAIT_XLOG_SHUTDOWN which doesn't start until after
> the shutdown checkpoint (which never arrived in the wal).
>
> I remain pretty stumped :)

The walsender logical bug happens when pmState is in PM_SHUTDOWN,
after sending a SIGUSR2 to the checkpointer.
The checkpointer then asks the walsender to stop through
WalSndInitStopping() in ShutdownXLOG and wait for them to finish,
before creating the shutdown checkpoint. If the walsender is stuck in
an infinite loop, the shutdown sequence is stuck in this state.

As you didn't have a shutdown checkpoint, the symptoms look very
similar (though you didn't confirm whether you were using logical
replication, so I'm gonna assume you do).

Just looking at the logs won't tell you much, the most visible symptom
would be the walsender process stuck at 100%. Another signal would be
a OVERWRITE_CONTRECORD record written just after restart, as the last
record would have been partially. Looking at the last WAL record when
the instance was stuck could be interesting, though if it's a partial
record, it won't be visible with pg_waldump.

If you want to compare, you can reproduce the walsender bug with this
query (you also need an active logical walsender):

-- Start from a fresh segment
SELECT pg_switch_wal();
BEGIN;
-- A logical message record is:
-- 24 bytes of record header
-- 5 bytes fragment header
-- 24 bytes xl_logical_message
-- 2 bytes NULL for prefix + message
-- x bytes message length
-- Total size of a WAL logical message is 55 bytes + message length
-- With WAL long header, the first page has 8152 bytes available
-- With WAL short header, the second page has 8168 bytes available
-- We need to write 16320 bytes (+/- 8 bytes of alignment)
SELECT pg_logical_emit_message(false, '', repeat('a', 16294));
ROLLBACK;

And immediately try to restart (this needs to be the last WAL record),
the shutdown should hang.

Regards,
Anthonin Bonnefoy

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Kyotaro Horiguchi 2026-07-09 07:15:42 Re: Fix data checksum processing for temp relations and dropped databases
Previous Message Bertrand Drouvot 2026-07-09 07:05:54 Re: Fix races conditions in DropRole() and GrantRole()