Re: Shutdown indefinitely stuck due to unflushed FPI_FOR_HINT record

Andres Freund <andres@anarazel.de>

From: Andres Freund <andres@anarazel.de>
To: Fujii Masao <masao.fujii@gmail.com>
Cc: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>, Alexander Lakhin <exclusion@gmail.com>, PostgreSQL Hackers <pgsql-hackers@postgresql.org>
Date: 2026-03-10T17:11:09Z
Lists: pgsql-hackers
Hi,

On 2026-03-06 16:48:06 +0900, Fujii Masao wrote:
> On Fri, Mar 6, 2026 at 8:46 AM Fujii Masao <masao.fujii@gmail.com> wrote:
> >
> > On Thu, Mar 5, 2026 at 5:40 PM Anthonin Bonnefoy
> > <anthonin.bonnefoy@datadoghq.com> wrote:
> > > So it was relying on GetInsertRecPtr() instead of
> > > GetXLogInsertRecPtr(). As mentioned in the thread, GetInsertRecPtr()
> > > only returns the position of the last full xlog page, meaning it
> > > doesn't fix the issue we have where the last partial page contains a
> > > continuation record.
> > >
> > > Testing the XLogFlush(GetInsertRecPtr()) patch with my script, I still
> > > get the shutdown stuck issue.
> > >
> > > Using GetXLogInsertRecPtr() is required to make sure the last partial
> > > page is correctly flushed.
> >
> > Since GetXLogInsertRecPtr() returns a bogus LSN and XLogFlush() does
> > almost nothing during recovery, I added a !RecoveryInProgress() check
> > as follows. I've attached the latest version of the patch and updated
> > the commit message.
> >
> > - if (got_STOPPING)
> > - XLogBackgroundFlush();
> > + if (got_STOPPING && !RecoveryInProgress())
> > + XLogFlush(GetXLogInsertRecPtr());
> 
> I've pushed the patch. Thanks!

I'm pretty sure this is not correct as-is, it suffers from the same issue as
https://postgr.es/m/vf4hbwrotvhbgcnknrqmfbqlu75oyjkmausvy66ic7x7vuhafx%40e4rvwavtjswo
I.e. it is not safe to use GetXLogInsertRecPtr() to determine up to where to
flush to, due to page boundaries.

Greetings,

Andres Freund



Commits

  1. Fix WAL flush LSN used by logical walsender during shutdown

  2. Use GetXLogInsertEndRecPtr in gistGetFakeLSN

  3. Fix publisher shutdown hang caused by logical walsender busy loop.