Re: Fix "unexpected logical decoding status change" error; from concurrent logical decoding activation - Mailing list pgsql-hackers

From Nisha Moond
Subject Re: Fix "unexpected logical decoding status change" error; from concurrent logical decoding activation
Date
Msg-id CABdArM647g1iw+quYO-nW=5TC8GyqMpVBeDYuKKu6TPMp6xFOA@mail.gmail.com
Whole thread
In response to Re: Fix "unexpected logical decoding status change" error; from concurrent logical decoding activation  (Masahiko Sawada <sawada.mshk@gmail.com>)
List pgsql-hackers
On Sat, Sep 26, 2026 at 3:54 AM Masahiko Sawada <sawada.mshk@gmail.com> wrote:
>
> On Fri, Sep 25, 2026 at 2:28 AM shveta malik <shveta.malik@gmail.com> wrote:
> >
> > On Fri, Sep 25, 2026 at 3:39 AM Masahiko Sawada <sawada.mshk@gmail.com> wrote:
> > >
> > > > I tested the patch and it fixes the problem. I found no critical
> > > > issues. A couple of comments:
> > > > 1) Now that a newly created synced slot is dropped on a failed new
> > > > check rather than kept as RS_TEMPORARY, a standby that is lagging in
> > > > replay can end up creating and dropping the slot on every sync cycle.
> > > > For example, replay is paused with pg_wal_replay_pause() or
> > > > recovery_min_apply_delay is large. After the primary turns logical
> > > > decoding off and then on again, the standby receives the activation
> > > > record but doesn't replay it. Meanwhile the slotsync worker keeps
> > > > fetching the failover slot, creates it, fails the new
> > > > IsLogicalDecodingEnabledSince() check, and drops it. This repeats
> > > > every cycle until the record is replayed.
> > > >
> > > > Each cycle creates the slot on disk and a pgstat entry, then removes
> > > > both again. I think this can be avoided with a cheaper pre-check,
> > > > IsLogicalDecodingEnabledSince(remote_slot->restart_lsn), before
> > > > ReplicationSlotCreate().
> > > >
> > > > Thoughts?
> > >
> > > I agree with your analysis. I think that in this case, the logical
> > > slot doesn't need to be dropped because WAL records after its
> > > restart_lsn are written with logical decoding information. Thinking on
> > > IsLogicalDecodingEnabledSince() further, I think it can work fine for
> > > the slot only when the replay LSN >= slot's restart_lsn. If the slot's
> > > restart_lsn > replay_lsn, we can leave the slot. Such a slot will be
> > > skipped for SS_SKIP_WAL_NOT_FLUSHED anyway. That way, the slot would
> > > have to be recreated only in the disable/re-enable case.
> >
> > I agree with the problem and solution, but I don't think ths slot will
> > later be skipped with 'SS_SKIP_WAL_NOT_FLUSHED' as the WALs are
> > already flushed; it is the replay which is slow and that check
> > compares against GetStandbyFlushRecPtr(), not replay position I think
> > it will wait somewhere in
> > LogicalSlotAdvanceAndCheckSnapState()-->read_local_xlog_page_guts as
> > 'wait_for_wal' is true and standy then waits for replay to happen. If
> > my understanding is correct, slotsync will be stuck on that one slot
> > untli replays happen, but let's see what Nisha has found in her tests.
> > I might be wrong too.
>
> You're right, if only the replay is delayed, it can end up waiting in
> read_local_xlog_page_guts(). But I think this is pre-existing behavior
> for a remote slot whose confirmed_lsn is ahead of the standby's replay
> position.
>

I confirmed the wait with a test. With replay paused on the standby, a
new failover slot 's' whose position is ahead of replay is created on
the standby as temporary. The slotsync worker then waits in
read_local_xlog_page_guts() for replay to catch up. Meanwhile, a
second slot 't', advanced on the primary only up to an LSN the standby
had already replayed, is not synced until replay is resumed.

Call stack of the slotsync worker:

pg_usleep
read_local_xlog_page_guts
read_local_xlog_page
XLogReadRecord
LogicalSlotAdvanceAndCheckSnapState
update_local_synced_slot
update_and_persist_local_synced_slot
synchronize_one_slot
synchronize_slots
ReplSlotSyncWorkerMain
...

I see the same wait on HEAD without the patch too, so I agree that
this is pre-existing.

--
Thanks,
Nisha



pgsql-hackers by date:

Previous
From: jian he
Date:
Subject: Re: NOT NULL NOT ENFORCED
Next
From: "Hayato Kuroda (Fujitsu)"
Date:
Subject: RE: Bug in logical decoding with DDL and subtransactions