| From: | Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> |
|---|---|
| To: | Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> |
| Cc: | Srinath Reddy Sadipiralla <srinath2133(at)gmail(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | Re: Fix "unexpected logical decoding status change" error; from concurrent logical decoding activation |
| Date: | 2026-07-27 16:05:52 |
| Message-ID: | CAD21AoCoAHrKEOLSEYzNOVMcNGLjY8EkiwOE8X9d_yPJkMfikA@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Fri, Jul 24, 2026 at 12:20 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> On Wed, Jul 22, 2026 at 7:08 PM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
> >
> > *
> > - * CheckLogicalDecodingRequirements() must have already errored out if
> > - * logical decoding is not enabled since we cannot enable the logical
> > - * decoding status during recovery.
> > + * The caller has already checked that logical decoding is enabled via
> > + * CheckLogicalDecodingRequirements(), but the status could have been
> > + * disabled concurrently before our slot being created: either by
> > + * replaying an XLOG_LOGICAL_DECODING_STATUS_CHANGE record, or by
> > + * UpdateLogicalDecodingStatusEndOfRecovery() upon promotion. We
> > + * cannot enable logical decoding during recovery, so raise an error.
> > */
> > - Assert(IsLogicalDecodingEnabled());
> > + if (!IsLogicalDecodingEnabled())
> > + ereport(ERROR,
> > + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
> > + errmsg("logical decoding on standby requires \"effective_wal_level\"
> > >= \"logical\" on the primary"),
> > + errdetail("Logical decoding was concurrently disabled during the
> > logical replication slot creation.")));
> >
> > It is not clear after reading the comment above this check what kind
> > of interlocking would save us from concurrent deactivation by two ways
> > mentioned by you immediately after this check?
> >
>
> I checked that before reaching here, we would have marked the slot as
> in_use, so the invalidation will invalidate such a slot.
Right. Will update the comment to make it clearer.
>
> The other observation I had while looking at this patch was: On a
> standby, InvalidateObsoleteReplicationSlots() can disable logical
> decoding whenever it invalidates the last valid logical slot via
> following check:
>
> if (invalidated_logical && !found_valid_logicalslot)
> RequestDisableLogicalDecoding();
> RequestDisableLogicalDecoding() isn't guarded against recovery, so a
> purely local invalidation (RS_INVAL_HORIZON/WAL_REMOVED/IDLE_TIMEOUT)
> makes the standby disable decoding even though the primary still has
> it enabled. The standby's status is supposed to follow the primary via
> XLOG_LOGICAL_DECODING_STATUS_CHANGE replay, and there's no
> self-healing since the primary never sends an "enable". So, won't that
> be a problem because after that no new slots will be allowed to be
> created on standby and slotsync also won't be able perform sync. Am, I
> missing something? If not then probable the above check needs
> additional check: "!RecoveryInProgress()".
In this case, the checkpointer will try to disable logical decoding
but does nothing as it's still in recovery. See the
RecoveryInProgress() check in DisableLogicalDecodingIfNecessary().
If we skip calling RequestDisableLogicalDecoding() in this case, we
would end up missing the disable request as it can be interleaved with
the promotion process. Imagine:
1. the startup process begins the promotion, decides the
new_status=true as there is a logical slot (in
UpdateLogicalDecodingStatusEndOfRecovery()).
2. a backend process drops the last logical slot and skips calling
RequestDisableLogicalDecoding() as the recovery status is still
in-progress.
3. the startup completes the
UpdateLogicalDecodingStatusEndOfRecovery(). The logical decoding is
enabled even though there is no logical slot.
Regards,
--
Masahiko Sawada
Amazon Web Services: https://aws.amazon.com
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Matthias van de Meent | 2026-07-27 16:06:50 | Re: SQL-level pg_datum_image_equal |
| Previous Message | Dinesh Salve | 2026-07-27 16:04:19 | Re: explain plans for foreign servers |