| 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
| 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() |