public inbox for [email protected]  
help / color / mirror / Atom feed
From: Ayush Tiwari <[email protected]>
To: Michael Paquier <[email protected]>
Cc: Radim Marek <[email protected]>
Cc: Andrey Borodin <[email protected]>
Cc: Heikki Linnakangas <[email protected]>
Cc: Marko Tiikkaja <[email protected]>
Cc: PostgreSQL mailing lists <[email protected]>
Subject: Re: BUG #19490: Streaming standby on 16.14 stops applying WAL on MultiXactOffsetSLRU when primary is 16.8
Date: Tue, 26 May 2026 14:00:30 +0530
Message-ID: <CAJTYsWWXvbBJe+WYJZcnoSTyVz9vk5ro3x2qAq_uvXvK2KwaMQ@mail.gmail.com> (raw)
In-Reply-To: <[email protected]>
References: <[email protected]>
	<[email protected]>
	<CAL9smLBMxKBCmsA9UGcmf93bT2_MsZ+POH-oHREuwKdmMU7jfQ@mail.gmail.com>
	<[email protected]>
	<CAJgoLkJfFgL-V+pYB7=R81AbURTE6sMhzVHDQDhVGnfXRSJ9Wg@mail.gmail.com>
	<CAJgoLkKCu0wCwPQZSo5no=XATU-4LMK4QfKBwV928o2uKcxe=g@mail.gmail.com>
	<CAJTYsWU6tdEvVh4YKLxz7+amZ7+Wb7_s-FBjsMMeLNj1fKeSNg@mail.gmail.com>
	<[email protected]>

Hi,

On Tue, 26 May 2026 at 13:32, Michael Paquier <[email protected]> wrote:

> On Fri, May 22, 2026 at 10:21:32PM +0530, Ayush Tiwari wrote:
> > I think the right fix is to remove that SimpleLruWriteAll() call while
> > keeping the missing-page initialization logic.  The flush is only meant
> to
> > make SimpleLruDoesPhysicalPageExist() see pages that exist in SLRU
> buffers
> > but have not reached disk.  In this fallback path, I don't see a way for
> > the tested next_pageno to be in that state: if RecordNewMultiXact()
> itself
> > initializes the page, it writes it synchronously with
> SimpleLruWritePage()
> > before setting last_initialized_offsets_page.
>
> FWIW, I'm having a couple of customers complaining about that as well,
> as cross-version physical replication is a thing for minor upgrade
> flows.  This bug is making suddenly recovery disruptive for some folks
> out there.  :(
>

We had faced a lot of replicas in bad state due to multixact replay with
16.12 release, and had to revert back the minor versions for them  until
16.13 came out which was a blessing. Given the number of CVEs
current one fixes, reverting too is scary.


> > I attached a small patch for REL_16_STABLE.  The same self-deadlock
> pattern
> > is also present on PG 14 and 15.  PG 17 and
> > 18 have the same compatibility call, but SLRU locking is banked
> > there, and RecordNewMultiXact() does not appear to hold the relevant bank
> > lock before calling SimpleLruWriteAll(), so I would not describe those
> > branches as having this exact self-deadlock, but needs more analysis.
>
> So your root argument is that while the SimpleLruWriteAll() is
> defensive, it is not actually necessary because it means that
> last_initialized_offsets_page is -1 we have not yet replayed
> ZERO_OFF_PAGE and that we have no dirty page that could make
> SimpleLruDoesPhysicalPageExis() return an incorrect result, which
> would be bad.  I am not sure to agree that this assumption is correct
> all the time, see for example the WAL message mentioned in the thread
> that has led to 77dff5d937b1:
>
> https://www.postgresql.org/message-id/33319276-e4d0-4773-89e4-09084905fdb0%40iki.fi


Right, agreed.  Thanks for pointing to that case.  My v1 patch removes
the self-deadlock, but the "no relevant dirty pages" assumption is too
strong.

The dirty page does not have to be one initialized by the current
RecordNewMultiXact() call.  It can already contain offsets replayed from
later CREATE_ID records while last_initialized_offsets_page is still -1.
In that state, relying directly on SimpleLruDoesPhysicalPageExist() can
still produce a false negative because it only checks the physical file,
not dirty SLRU buffers.  So removing the flush can maybe reintroduce
the kind of corruption that 77dff5d937b1 was trying to prevent.

A different approach would be to release and re-acquire the
> MultiXactOffsetSLRULock while calling SimpleLruWriteAll(), and I think
> that it should be actually safe.  Even if read-only backends evict
> dirty pages between the moment the lock is released and the moment it
> is re-acquired in SimpleLruWriteAll(), the pages would be would be
> written to disk due to the eviction, which is what we want for
> correctness.  And only the startup process dirties offset pages during
> recovery, AFAIK.  Thoughts?
>

 That sounds like the right direction to me.

Releasing MultiXactOffsetSLRULock around SimpleLruWriteAll() preserves
the flush-before-physical-check rule while avoiding the self-deadlock.
I don't see a partial-state problem from the current record at that
point, since the compatibility check happens before RecordNewMultiXact()
has modified the current offsets page.  And as you said, during recovery
The startup process should be the only process dirtying offset pages; if
a hot standby reader causes eviction while the lock is released, that
should only help by writing the dirty page out.

> Added both Andrey and Heikki in to-mail, since I'm not sure if this
> > is more extreme than the multixact offset issue we had with 16.12, or it
> > is at par with that.
>
> Indeed, let's wait for at least Heikki's input.
>
> Anyway, for any fixes, I don't think that it would be a good idea to
> skip v17 and v18, relying on the SLRU bank locks to not conflict to
> bypass the WriteAll() conflict.  Let's keep all the branches across
> v14~v18 in sync.
>

Agreed.

Regards,
Ayush


reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
  Subject: Re: BUG #19490: Streaming standby on 16.14 stops applying WAL on MultiXactOffsetSLRU when primary is 16.8
  In-Reply-To: <CAJTYsWWXvbBJe+WYJZcnoSTyVz9vk5ro3x2qAq_uvXvK2KwaMQ@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox