synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Started by SATYANARAYANA NARLAPURAMabout 2 months ago73 messageshackers
Jump to latest
#1SATYANARAYANA NARLAPURAM
satyanarlapuram@gmail.com

Hi hackers,

synchronized_standby_slots requires that every physical slot listed in the
GUC has caught up before a logical failover slot is allowed to proceed with
decoding. This is an ALL-of-N slots semantic. The logical slot
availability model does not align with quorum replication semantics set
using synchronous_standby_names which can be configured for quorum commit
(ANY M of N).

In a typical 3 Node HA deployment with quorum sync rep:

Primary, standby1 (corresponds to sb1_slot), standby2 (corresponds to
sb2_slot)
synchronized_standby_slots = ' sb1_slot, sb2_slot'
synchronous_standby_names = 'Any 1 ('standby1','standby2')'

If standby1 goes down, synchronous commits still succeed because standby2
satisfies the quorum. However, logical decoding blocks indefinitely in
WaitForStandbyConfirmation(), waiting for sb1_slot (corresponds to
standby1) to catch up — even though the transaction is already safely
committed on a quorum of synchronous standbys. This blocks logical decoding
consumers from progressing and is inconsistent with the availability
guarantee the DBA intended by choosing quorum commit. This scenario is
constructed in the TAP test (052_synchronized_standby_slots_quorum.pl) in
the attached patch.

*Proposal:*

Make synchronized_standby_slots quorum aware i.e. extend the GUC to accept
an ANY M (slot1, slot2, ...) syntax similar to synchronous_standby_names,
so StandbySlotsHaveCaughtup() can return true when M of N slots (where M <=
N and M >= 1) have caught up. I still prefer two different GUCs for this as
the list of slots to be synchronized can still be different (for example,
DBA may want to ensure Geo standby to be sync before allowing the logical
decoding client to read the changes). I kept synchronized_standby_slots
parse logic similar to synchronous_standby_names to keep things simple.
The default behavior is also not changed for synchronized_standby_slots.

Added a draft patch (AI assisted). Please let me know your Thoughts.

Thanks,
Satya

Attachments:

0001-Add-quorum-support-to-synchronized_standby_slots.patchapplication/octet-stream; name=0001-Add-quorum-support-to-synchronized_standby_slots.patchDownload+519-97
#2Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: SATYANARAYANA NARLAPURAM (#1)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi Satya,

On Wed, Feb 25, 2026 at 3:38 AM SATYANARAYANA NARLAPURAM
<satyanarlapuram@gmail.com> wrote:

Hi hackers,

synchronized_standby_slots requires that every physical slot listed in the GUC has caught up before a logical failover slot is allowed to proceed with decoding. This is an ALL-of-N slots semantic. The logical slot availability model does not align with quorum replication semantics set using synchronous_standby_names which can be configured for quorum commit (ANY M of N).

In a typical 3 Node HA deployment with quorum sync rep:

Primary, standby1 (corresponds to sb1_slot), standby2 (corresponds to sb2_slot)
synchronized_standby_slots = ' sb1_slot, sb2_slot'
synchronous_standby_names = 'Any 1 ('standby1','standby2')'

If standby1 goes down, synchronous commits still succeed because standby2 satisfies the quorum. However, logical decoding blocks indefinitely in WaitForStandbyConfirmation(), waiting for sb1_slot (corresponds to standby1) to catch up — even though the transaction is already safely committed on a quorum of synchronous standbys. This blocks logical decoding consumers from progressing and is inconsistent with the availability guarantee the DBA intended by choosing quorum commit.

+1. This can indeed be a blocker for failover enabled logical
replication. It not only has the potential to disrupt logical
replication, but can also impact the primary server. Over time, it may
silently lead to significant WAL accumulation on the primary,
eventually causing disk-full scenarios and degrading the performance
of applications running on the primary instance. Therefore, I too
strongly believe this needs to be addressed to prevent such
potentially disruptive situations.

Proposal:

Make synchronized_standby_slots quorum aware i.e. extend the GUC to accept an ANY M (slot1, slot2, ...) syntax similar to synchronous_standby_names, so StandbySlotsHaveCaughtup() can return true when M of N slots (where M <= N and M >= 1) have caught up. I still prefer two different GUCs for this as the list of slots to be synchronized can still be different (for example, DBA may want to ensure Geo standby to be sync before allowing the logical decoding client to read the changes). I kept synchronized_standby_slots parse logic similar to synchronous_standby_names to keep things simple. The default behavior is also not changed for synchronized_standby_slots.

Thank you for the proposal. I can spend some time reviewing the
changes and help take this forward. I would also be happy to hear
others' thoughts and feedback on the proposal.

--
With Regards,
Ashutosh Sharma.

#3Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: Ashutosh Sharma (#2)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi,

On Wed, Feb 25, 2026 at 7:21 PM Ashutosh Sharma <ashu.coek88@gmail.com> wrote:

Hi Satya,

On Wed, Feb 25, 2026 at 3:38 AM SATYANARAYANA NARLAPURAM
<satyanarlapuram@gmail.com> wrote:

Hi hackers,

synchronized_standby_slots requires that every physical slot listed in the GUC has caught up before a logical failover slot is allowed to proceed with decoding. This is an ALL-of-N slots semantic. The logical slot availability model does not align with quorum replication semantics set using synchronous_standby_names which can be configured for quorum commit (ANY M of N).

In a typical 3 Node HA deployment with quorum sync rep:

Primary, standby1 (corresponds to sb1_slot), standby2 (corresponds to sb2_slot)
synchronized_standby_slots = ' sb1_slot, sb2_slot'
synchronous_standby_names = 'Any 1 ('standby1','standby2')'

If standby1 goes down, synchronous commits still succeed because standby2 satisfies the quorum. However, logical decoding blocks indefinitely in WaitForStandbyConfirmation(), waiting for sb1_slot (corresponds to standby1) to catch up — even though the transaction is already safely committed on a quorum of synchronous standbys. This blocks logical decoding consumers from progressing and is inconsistent with the availability guarantee the DBA intended by choosing quorum commit.

+1. This can indeed be a blocker for failover enabled logical
replication. It not only has the potential to disrupt logical
replication, but can also impact the primary server. Over time, it may
silently lead to significant WAL accumulation on the primary,
eventually causing disk-full scenarios and degrading the performance
of applications running on the primary instance. Therefore, I too
strongly believe this needs to be addressed to prevent such
potentially disruptive situations.

Proposal:

Make synchronized_standby_slots quorum aware i.e. extend the GUC to accept an ANY M (slot1, slot2, ...) syntax similar to synchronous_standby_names, so StandbySlotsHaveCaughtup() can return true when M of N slots (where M <= N and M >= 1) have caught up. I still prefer two different GUCs for this as the list of slots to be synchronized can still be different (for example, DBA may want to ensure Geo standby to be sync before allowing the logical decoding client to read the changes). I kept synchronized_standby_slots parse logic similar to synchronous_standby_names to keep things simple. The default behavior is also not changed for synchronized_standby_slots.

Thank you for the proposal. I can spend some time reviewing the
changes and help take this forward. I would also be happy to hear
others' thoughts and feedback on the proposal.

Thinking about this further, using quorum settings for
synchronized_standby_slots can/will certainly result in at least one
sync standby lagging behind the logical replica, making it probably
impossible to continue with the existing logical replication setup
after a failover to the standby that lags behind. Here is what I am
mean:

Let's say we have 2 synchronous standbys with
"synchronized_standby_slots" configured as ANY 1 (sync_standby1,
sync_standby2). With this quorum setting, WAL only needs to be
confirmed by any one of the two standbys before it can be forwarded to
the logical replica. Now consider a scenario where sync_standby1 is
ahead of sync_standby2, new WAL gets confirmed by sync_standby1 and
subsequently delivered to the logical replica. If sync_standby1 then
goes down and we failover to sync_standby2, the new primary will be at
a lower LSN than the logical replica, since sync_standby2 never
received that WAL. At this point, the logical replication slot on the
new primary is essentially stale, and the logical replication setup
that existed before the failover cannot be resumed. Hence, I think
it's important to ensure that the WAL (including all the necessary
data needed for logical replication) gets delivered to all the
servers/slots specified in synchronized_standby_slots before it gets
delivered to the logical replica.

While I agree that not allowing quorum like settings for this has the
potential to accumulate WAL and impact logical replication, I think we
can explore other ways to mitigate that concern separately.

Let's see what experts have to say on this.

--
With Regards,
Ashutosh Sharma.

#4Amit Kapila
amit.kapila16@gmail.com
In reply to: Ashutosh Sharma (#3)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

On Thu, Feb 26, 2026 at 10:28 AM Ashutosh Sharma <ashu.coek88@gmail.com> wrote:

Proposal:

Make synchronized_standby_slots quorum aware i.e. extend the GUC to accept an ANY M (slot1, slot2, ...) syntax similar to synchronous_standby_names, so StandbySlotsHaveCaughtup() can return true when M of N slots (where M <= N and M >= 1) have caught up. I still prefer two different GUCs for this as the list of slots to be synchronized can still be different (for example, DBA may want to ensure Geo standby to be sync before allowing the logical decoding client to read the changes). I kept synchronized_standby_slots parse logic similar to synchronous_standby_names to keep things simple. The default behavior is also not changed for synchronized_standby_slots.

...

Thinking about this further, using quorum settings for
synchronized_standby_slots can/will certainly result in at least one
sync standby lagging behind the logical replica, making it probably
impossible to continue with the existing logical replication setup
after a failover to the standby that lags behind. Here is what I am
mean:

But won't that be true even for synchronous_standby_names? I think in
the case of quorum, it is the responsibility of the failover solution
to select the most recent synced standby among all the standby's
specified in synchronous_standby_names. Similarly here before failing
over logical subscriber to one of physical standby, the failover tool
needs to ensure it is switching over to the synced replica. We have
given steps in the docs [1]https://www.postgresql.org/docs/current/logical-replication-failover.html that could be used to identify the replica
where the subscriber can switchover. Will that address your concern?

BTW, I have also suggested this idea in thread [2]/messages/by-id/CAA4eK1KLFdmj8CLrZNL0D4phqyQihb7NXOjmqvrU5DT8moQn9Q@mail.gmail.com. I don't recall all
the ideas/points discussed in that thread but it would be good to
check that thread for any alternative ideas and points raised, so that
we don't miss anything.

[1]: https://www.postgresql.org/docs/current/logical-replication-failover.html
[2]: /messages/by-id/CAA4eK1KLFdmj8CLrZNL0D4phqyQihb7NXOjmqvrU5DT8moQn9Q@mail.gmail.com

--
With Regards,
Amit Kapila.

#5Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: Amit Kapila (#4)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi Amit,

On Thu, Feb 26, 2026 at 11:50 AM Amit Kapila <amit.kapila16@gmail.com> wrote:

On Thu, Feb 26, 2026 at 10:28 AM Ashutosh Sharma <ashu.coek88@gmail.com> wrote:

Proposal:

Make synchronized_standby_slots quorum aware i.e. extend the GUC to accept an ANY M (slot1, slot2, ...) syntax similar to synchronous_standby_names, so StandbySlotsHaveCaughtup() can return true when M of N slots (where M <= N and M >= 1) have caught up. I still prefer two different GUCs for this as the list of slots to be synchronized can still be different (for example, DBA may want to ensure Geo standby to be sync before allowing the logical decoding client to read the changes). I kept synchronized_standby_slots parse logic similar to synchronous_standby_names to keep things simple. The default behavior is also not changed for synchronized_standby_slots.

...

Thinking about this further, using quorum settings for
synchronized_standby_slots can/will certainly result in at least one
sync standby lagging behind the logical replica, making it probably
impossible to continue with the existing logical replication setup
after a failover to the standby that lags behind. Here is what I am
mean:

But won't that be true even for synchronous_standby_names? I think in
the case of quorum, it is the responsibility of the failover solution
to select the most recent synced standby among all the standby's
specified in synchronous_standby_names. Similarly here before failing
over logical subscriber to one of physical standby, the failover tool
needs to ensure it is switching over to the synced replica. We have
given steps in the docs [1] that could be used to identify the replica
where the subscriber can switchover. Will that address your concern?

Here's my understanding of this:

I don't think we should be comparing "synchronous_standby_names" with
"synchronized_standby_slots", even though they appear similar in
purpose. All values listed in synchronous_standby_names represent
synchronous standbys exclusively, whereas synchronized_standby_slots
can hold values for both synchronous and asynchronous standbys. In
other words, every server referenced by synchronous_standby_names is
of the same type, but that may not be the case with
synchronized_standby_slots.

If a GUC can hold values of different types (sync vs. async), does it
really make sense to use a qualifier like ANY 1 (val1, val2) when val1
and val2 are different in nature? For example, suppose val1 is a
synchronous standby and val2 is an asynchronous standby, and we
configure ANY 1 (val1, val2). It's possible for val2 to get ahead of
val1 in terms of replication progress, which in turn could mean the
logical replica is also ahead of val1. So if we were to fail over to
val1 (since it's the only synchronous standby), we will not be able to
use the existing logical replication setup.

Please correct me if I have misunderstood anything here.

--
With Regards,
Ashutosh Sharma.

#6SATYANARAYANA NARLAPURAM
satyanarlapuram@gmail.com
In reply to: Amit Kapila (#4)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi Amit,

On Wed, Feb 25, 2026 at 10:20 PM Amit Kapila <amit.kapila16@gmail.com>
wrote:

...

Thinking about this further, using quorum settings for
synchronized_standby_slots can/will certainly result in at least one
sync standby lagging behind the logical replica, making it probably
impossible to continue with the existing logical replication setup
after a failover to the standby that lags behind. Here is what I am
mean:

But won't that be true even for synchronous_standby_names? I think in
the case of quorum, it is the responsibility of the failover solution
to select the most recent synced standby among all the standby's
specified in synchronous_standby_names. Similarly here before failing
over logical subscriber to one of physical standby, the failover tool
needs to ensure it is switching over to the synced replica. We have
given steps in the docs [1] that could be used to identify the replica
where the subscriber can switchover. Will that address your concern?

+1, the job of failover orchestration is to ensure the new primary is
caught up at least until the quorum LSN. Otherwise, it can be a durability
issue where users see missing committed transactions.

BTW, I have also suggested this idea in thread [2]. I don't recall all
the ideas/points discussed in that thread but it would be good to
check that thread for any alternative ideas and points raised, so that
we don't miss anything.

Thanks for sharing the links, the approach is similar. DEFAULT to
SAME_AS_SYNCREP_STANDBYS is an interesting option.
I like the idea of avoiding duplicate lists unless the user wants to
maintain a separate list.

Thanks,
Satya

#7SATYANARAYANA NARLAPURAM
satyanarlapuram@gmail.com
In reply to: Ashutosh Sharma (#5)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi Ashutosh,

On Wed, Feb 25, 2026 at 11:42 PM Ashutosh Sharma <ashu.coek88@gmail.com>
wrote:

I don't think we should be comparing "synchronous_standby_names" with
"synchronized_standby_slots", even though they appear similar in
purpose. All values listed in synchronous_standby_names represent
synchronous standbys exclusively, whereas synchronized_standby_slots
can hold values for both synchronous and asynchronous standbys. In
other words, every server referenced by synchronous_standby_names is
of the same type, but that may not be the case with
synchronized_standby_slots.

If a GUC can hold values of different types (sync vs. async), does it
really make sense to use a qualifier like ANY 1 (val1, val2) when val1
and val2 are different in nature? For example, suppose val1 is a
synchronous standby and val2 is an asynchronous standby, and we
configure ANY 1 (val1, val2). It's possible for val2 to get ahead of
val1 in terms of replication progress, which in turn could mean the
logical replica is also ahead of val1. So if we were to fail over to
val1 (since it's the only synchronous standby), we will not be able to
use the existing logical replication setup.

If the failover orchestrator cannot ensure standby1 to not get the quorum
committed WAL (from archive or standby2) then the setting ANY 1 (val1,
val2) is invalid.
This setup also has issues because in your scenario, standby2 is ahead of
the new primary (standby1) and standby2 requires now to rewind to be in
sync with the new primary. Additionally, it allowed readers to read data
that was lost at the end of the failover. We ideally need a mechanism to
not send WAL to async replicas before the sync replicas commit (honoring
syncrhnous_standby_names GUC) feature (similar to
synchronized_standby_slots). It could be a different thread on its own.

#8shveta malik
shveta.malik@gmail.com
In reply to: SATYANARAYANA NARLAPURAM (#7)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

On Thu, Feb 26, 2026 at 1:54 PM SATYANARAYANA NARLAPURAM
<satyanarlapuram@gmail.com> wrote:

Hi Ashutosh,

On Wed, Feb 25, 2026 at 11:42 PM Ashutosh Sharma <ashu.coek88@gmail.com> wrote:

I don't think we should be comparing "synchronous_standby_names" with
"synchronized_standby_slots", even though they appear similar in
purpose. All values listed in synchronous_standby_names represent
synchronous standbys exclusively, whereas synchronized_standby_slots
can hold values for both synchronous and asynchronous standbys. In
other words, every server referenced by synchronous_standby_names is
of the same type, but that may not be the case with
synchronized_standby_slots.

If a GUC can hold values of different types (sync vs. async), does it
really make sense to use a qualifier like ANY 1 (val1, val2) when val1
and val2 are different in nature? For example, suppose val1 is a
synchronous standby and val2 is an asynchronous standby, and we
configure ANY 1 (val1, val2). It's possible for val2 to get ahead of
val1 in terms of replication progress, which in turn could mean the
logical replica is also ahead of val1. So if we were to fail over to
val1 (since it's the only synchronous standby), we will not be able to
use the existing logical replication setup.

If the failover orchestrator cannot ensure standby1 to not get the quorum committed WAL (from archive or standby2) then the setting ANY 1 (val1, val2) is invalid.
This setup also has issues because in your scenario, standby2 is ahead of the new primary (standby1) and standby2 requires now to rewind to be in sync with the new primary. Additionally, it allowed readers to read data that was lost at the end of the failover. We ideally need a mechanism to not send WAL to async replicas before the sync replicas commit (honoring syncrhnous_standby_names GUC) feature (similar to synchronized_standby_slots). It could be a different thread on its own.

+1 on the overall idea of the patch.
I understand the concern raised above that one of the standbys in the
quorum (synchronized_standby_slots) might lag behind the logical
replica, and a user could potentially failover to such a standby. But
I also agree with Amit that configuring failover correctly is
ultimately the responsibility of failover-solution. And instructions
in doc should be followed before deciding if a standby is
failover-ready or not.

As suggested in [1]/messages/by-id/CAJpy0uCZ04ZQFHs-tV5LprkYtSSwtBtUJW4O=0S01yc+TRw7EQ@mail.gmail.com, IMO, it is a reasonably good idea for
'synchronized_standby_slots' to DEFAULT to the value of
'synchronous_standby_names'. That way, even if the user missed to
configure 'synchronized_standby_slots' explicitly, we would still have
reasonable protection in place. At the same time, if a user
intentionally chooses not to configure it, a NULL/NONE value should
remain a valid option.

[1]: /messages/by-id/CAJpy0uCZ04ZQFHs-tV5LprkYtSSwtBtUJW4O=0S01yc+TRw7EQ@mail.gmail.com

Thanks,
Shveta

#9Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#8)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi,

On Thu, Feb 26, 2026 at 2:15 PM shveta malik <shveta.malik@gmail.com> wrote:

On Thu, Feb 26, 2026 at 1:54 PM SATYANARAYANA NARLAPURAM
<satyanarlapuram@gmail.com> wrote:

Hi Ashutosh,

On Wed, Feb 25, 2026 at 11:42 PM Ashutosh Sharma <ashu.coek88@gmail.com> wrote:

I don't think we should be comparing "synchronous_standby_names" with
"synchronized_standby_slots", even though they appear similar in
purpose. All values listed in synchronous_standby_names represent
synchronous standbys exclusively, whereas synchronized_standby_slots
can hold values for both synchronous and asynchronous standbys. In
other words, every server referenced by synchronous_standby_names is
of the same type, but that may not be the case with
synchronized_standby_slots.

If a GUC can hold values of different types (sync vs. async), does it
really make sense to use a qualifier like ANY 1 (val1, val2) when val1
and val2 are different in nature? For example, suppose val1 is a
synchronous standby and val2 is an asynchronous standby, and we
configure ANY 1 (val1, val2). It's possible for val2 to get ahead of
val1 in terms of replication progress, which in turn could mean the
logical replica is also ahead of val1. So if we were to fail over to
val1 (since it's the only synchronous standby), we will not be able to
use the existing logical replication setup.

If the failover orchestrator cannot ensure standby1 to not get the quorum committed WAL (from archive or standby2) then the setting ANY 1 (val1, val2) is invalid.
This setup also has issues because in your scenario, standby2 is ahead of the new primary (standby1) and standby2 requires now to rewind to be in sync with the new primary. Additionally, it allowed readers to read data that was lost at the end of the failover. We ideally need a mechanism to not send WAL to async replicas before the sync replicas commit (honoring syncrhnous_standby_names GUC) feature (similar to synchronized_standby_slots). It could be a different thread on its own.

+1 on the overall idea of the patch.
I understand the concern raised above that one of the standbys in the
quorum (synchronized_standby_slots) might lag behind the logical
replica, and a user could potentially failover to such a standby. But
I also agree with Amit that configuring failover correctly is
ultimately the responsibility of failover-solution. And instructions
in doc should be followed before deciding if a standby is
failover-ready or not.

As suggested in [1], IMO, it is a reasonably good idea for
'synchronized_standby_slots' to DEFAULT to the value of
'synchronous_standby_names'. That way, even if the user missed to
configure 'synchronized_standby_slots' explicitly, we would still have
reasonable protection in place. At the same time, if a user
intentionally chooses not to configure it, a NULL/NONE value should
remain a valid option.

AFAIU, not all names listed in "synchronous_standby_names" are
necessarily synchronous standbys. Tools like pg_receivewal, for
example, can establish a replication connection to the primary and
appear in that list. Therefore, deriving "synchronized_standby_slots"
from "synchronous_standby_names", if not set by the user would cause
logical slots to be synchronized to whatever nodes those names
represent, including a host running pg_receivewal, which is certainly
not something the user would have intended to do. Therefore I feel
this might not just be the good choice.

--
With Regards,
Ashutosh Sharma.

#10Alexander Kukushkin
cyberdemn@gmail.com
In reply to: shveta malik (#8)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi,

On Thu, 26 Feb 2026 at 09:45, shveta malik <shveta.malik@gmail.com> wrote:

As suggested in [1], IMO, it is a reasonably good idea for
'synchronized_standby_slots' to DEFAULT to the value of
'synchronous_standby_names'. That way, even if the user missed to
configure 'synchronized_standby_slots' explicitly, we would still have
reasonable protection in place.

Hmm.
synchronous_standby_names contains application_names,
while synchronized_standby_slots contains names of physical replication
slots.
These are two different things, and in fact sync replication doesn't even
require to use replication slots.
What is worse, even when all standbys use physical replication slots there
is no guarantee that values in synchronous_standby_names will match
physical slot names.

Regards,
--
Alexander Kukushkin

#11SATYANARAYANA NARLAPURAM
satyanarlapuram@gmail.com
In reply to: Alexander Kukushkin (#10)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi Alexnader,

On Thu, Feb 26, 2026 at 1:29 AM Alexander Kukushkin <cyberdemn@gmail.com>
wrote:

Hi,

On Thu, 26 Feb 2026 at 09:45, shveta malik <shveta.malik@gmail.com> wrote:

As suggested in [1], IMO, it is a reasonably good idea for
'synchronized_standby_slots' to DEFAULT to the value of
'synchronous_standby_names'. That way, even if the user missed to
configure 'synchronized_standby_slots' explicitly, we would still have
reasonable protection in place.

Hmm.
synchronous_standby_names contains application_names,
while synchronized_standby_slots contains names of physical replication
slots.
These are two different things, and in fact sync replication doesn't even
require to use replication slots.
What is worse, even when all standbys use physical replication slots there
is no guarantee that values in synchronous_standby_names will match
physical slot names

That's right, thanks for reminding me. I am convinced that we can't use the
defaults of synchronous_standby_names for synchronized_standby_slots. What
do you think about the rest of the proposal?

Thanks,
Satya

#12SATYANARAYANA NARLAPURAM
satyanarlapuram@gmail.com
In reply to: Ashutosh Sharma (#9)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi Ashutosh,

On Thu, Feb 26, 2026 at 1:11 AM Ashutosh Sharma <ashu.coek88@gmail.com>
wrote:

Hi,

On Thu, Feb 26, 2026 at 2:15 PM shveta malik <shveta.malik@gmail.com>
wrote:

On Thu, Feb 26, 2026 at 1:54 PM SATYANARAYANA NARLAPURAM
<satyanarlapuram@gmail.com> wrote:

Hi Ashutosh,

On Wed, Feb 25, 2026 at 11:42 PM Ashutosh Sharma <

ashu.coek88@gmail.com> wrote:

I don't think we should be comparing "synchronous_standby_names" with
"synchronized_standby_slots", even though they appear similar in
purpose. All values listed in synchronous_standby_names represent
synchronous standbys exclusively, whereas synchronized_standby_slots
can hold values for both synchronous and asynchronous standbys. In
other words, every server referenced by synchronous_standby_names is
of the same type, but that may not be the case with
synchronized_standby_slots.

If a GUC can hold values of different types (sync vs. async), does it
really make sense to use a qualifier like ANY 1 (val1, val2) when val1
and val2 are different in nature? For example, suppose val1 is a
synchronous standby and val2 is an asynchronous standby, and we
configure ANY 1 (val1, val2). It's possible for val2 to get ahead of
val1 in terms of replication progress, which in turn could mean the
logical replica is also ahead of val1. So if we were to fail over to
val1 (since it's the only synchronous standby), we will not be able to
use the existing logical replication setup.

If the failover orchestrator cannot ensure standby1 to not get the

quorum committed WAL (from archive or standby2) then the setting ANY 1
(val1, val2) is invalid.

This setup also has issues because in your scenario, standby2 is ahead

of the new primary (standby1) and standby2 requires now to rewind to be in
sync with the new primary. Additionally, it allowed readers to read data
that was lost at the end of the failover. We ideally need a mechanism to
not send WAL to async replicas before the sync replicas commit (honoring
syncrhnous_standby_names GUC) feature (similar to
synchronized_standby_slots). It could be a different thread on its own.

+1 on the overall idea of the patch.
I understand the concern raised above that one of the standbys in the
quorum (synchronized_standby_slots) might lag behind the logical
replica, and a user could potentially failover to such a standby. But
I also agree with Amit that configuring failover correctly is
ultimately the responsibility of failover-solution. And instructions
in doc should be followed before deciding if a standby is
failover-ready or not.

As suggested in [1], IMO, it is a reasonably good idea for
'synchronized_standby_slots' to DEFAULT to the value of
'synchronous_standby_names'. That way, even if the user missed to
configure 'synchronized_standby_slots' explicitly, we would still have
reasonable protection in place. At the same time, if a user
intentionally chooses not to configure it, a NULL/NONE value should
remain a valid option.

AFAIU, not all names listed in "synchronous_standby_names" are
necessarily synchronous standbys. Tools like pg_receivewal, for
example, can establish a replication connection to the primary and
appear in that list. Therefore, deriving "synchronized_standby_slots"
from "synchronous_standby_names", if not set by the user would cause
logical slots to be synchronized to whatever nodes those names
represent, including a host running pg_receivewal, which is certainly
not something the user would have intended to do. Therefore I feel
this might not just be the good choice.

Agreed, not a good idea to have synchronized_standby_slots default to
synchronous_standby_names because application_names and slot names are
different as stated.

Thanks,
Satya

#13Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: SATYANARAYANA NARLAPURAM (#12)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi All,

Submitting a new version of the patch based on Satya's earlier work - [1]/messages/by-id/CAHg+QDfU7rOebrLDESPpHSgdiadKbpCOmBokcbmM6Gr+A5VobQ@mail.gmail.com.

Please take a look and let us know your thoughts.

[1]: /messages/by-id/CAHg+QDfU7rOebrLDESPpHSgdiadKbpCOmBokcbmM6Gr+A5VobQ@mail.gmail.com

--
With Regards,
Ashutosh Sharma.

Attachments:

v20260307-0001-Add-FIRST-N-and-ANY-N-syntax-support-to-synchronized.patchapplication/octet-stream; name=v20260307-0001-Add-FIRST-N-and-ANY-N-syntax-support-to-synchronized.patchDownload+693-108
#14shveta malik
shveta.malik@gmail.com
In reply to: SATYANARAYANA NARLAPURAM (#12)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

On Thu, Feb 26, 2026 at 4:16 PM SATYANARAYANA NARLAPURAM
<satyanarlapuram@gmail.com> wrote:

Hi Ashutosh,

On Thu, Feb 26, 2026 at 1:11 AM Ashutosh Sharma <ashu.coek88@gmail.com> wrote:

Hi,

On Thu, Feb 26, 2026 at 2:15 PM shveta malik <shveta.malik@gmail.com> wrote:

On Thu, Feb 26, 2026 at 1:54 PM SATYANARAYANA NARLAPURAM
<satyanarlapuram@gmail.com> wrote:

Hi Ashutosh,

On Wed, Feb 25, 2026 at 11:42 PM Ashutosh Sharma <ashu.coek88@gmail.com> wrote:

I don't think we should be comparing "synchronous_standby_names" with
"synchronized_standby_slots", even though they appear similar in
purpose. All values listed in synchronous_standby_names represent
synchronous standbys exclusively, whereas synchronized_standby_slots
can hold values for both synchronous and asynchronous standbys. In
other words, every server referenced by synchronous_standby_names is
of the same type, but that may not be the case with
synchronized_standby_slots.

If a GUC can hold values of different types (sync vs. async), does it
really make sense to use a qualifier like ANY 1 (val1, val2) when val1
and val2 are different in nature? For example, suppose val1 is a
synchronous standby and val2 is an asynchronous standby, and we
configure ANY 1 (val1, val2). It's possible for val2 to get ahead of
val1 in terms of replication progress, which in turn could mean the
logical replica is also ahead of val1. So if we were to fail over to
val1 (since it's the only synchronous standby), we will not be able to
use the existing logical replication setup.

If the failover orchestrator cannot ensure standby1 to not get the quorum committed WAL (from archive or standby2) then the setting ANY 1 (val1, val2) is invalid.
This setup also has issues because in your scenario, standby2 is ahead of the new primary (standby1) and standby2 requires now to rewind to be in sync with the new primary. Additionally, it allowed readers to read data that was lost at the end of the failover. We ideally need a mechanism to not send WAL to async replicas before the sync replicas commit (honoring syncrhnous_standby_names GUC) feature (similar to synchronized_standby_slots). It could be a different thread on its own.

+1 on the overall idea of the patch.
I understand the concern raised above that one of the standbys in the
quorum (synchronized_standby_slots) might lag behind the logical
replica, and a user could potentially failover to such a standby. But
I also agree with Amit that configuring failover correctly is
ultimately the responsibility of failover-solution. And instructions
in doc should be followed before deciding if a standby is
failover-ready or not.

As suggested in [1], IMO, it is a reasonably good idea for
'synchronized_standby_slots' to DEFAULT to the value of
'synchronous_standby_names'. That way, even if the user missed to
configure 'synchronized_standby_slots' explicitly, we would still have
reasonable protection in place. At the same time, if a user
intentionally chooses not to configure it, a NULL/NONE value should
remain a valid option.

AFAIU, not all names listed in "synchronous_standby_names" are
necessarily synchronous standbys. Tools like pg_receivewal, for
example, can establish a replication connection to the primary and
appear in that list. Therefore, deriving "synchronized_standby_slots"
from "synchronous_standby_names", if not set by the user would cause
logical slots to be synchronized to whatever nodes those names
represent, including a host running pg_receivewal, which is certainly
not something the user would have intended to do. Therefore I feel
this might not just be the good choice.

Agreed, not a good idea to have synchronized_standby_slots default to synchronous_standby_names because application_names and slot names are different as stated.

yes, agreed. Sorry I missed this point earlier.

Submitting a new version of the patch based on Satya's earlier work - [1].

Please take a look and let us know your thoughts.

Had a look at the patch. Few concerns:

1)
StandbySlotsHaveCaughtup:

+ * If a slot listed in synchronized_standby_slots is not found,
+ * report an error.

--

+ * If a slot is not physical, report error.

These comments are misleading as we may or may not report ERROR
depending upon elevel passed by caller.

2)
It seems to me (not tested yet) that even in priority based and quorum
based configuration, if we have found our N slots, still we will end
up emitting WARNING message for invalidated, missing slots etc such
as:

a)
repplication slot \"%s\" specified in parameter \"%s\" does not exist
Logical replication is waiting on the standby associated with replication slot.

b)
cannot specify logical replication slot \"%s\" in parameter
Logical replication is waiting for correction on replication slot.

c)
physical replication slot \"%s\" specified in parameter \"%s\" has
been invalidated
Logical replication is waiting on the standby associated with replication slot.

These messages may give the impression that logical replication is
actually waiting, even though it might already be progressing normally
because the required N slots have been found.

OTOH, if we suppress these messages, there could be cases where we
fail to find the required N valid slots and logical replication
genuinely ends up waiting, but the user would receive no indication of
the problem.

One thing for sure is, that we need to emit such messages when
'wait_for_all' is true, but for rest, we can not decide inline.

So there are 2 options:
a) either we change the DETAIL slightly with each such reporting to
say below or anything better:

DETAIL: logical replication may wait if the required number of standby
slots is not available.

b)
Or we collect the slot-names and emit the message at the end only 'if
(caught_up_slot_num < required)'. Something like:

WARNING: Some replication slots specified in parameter "%s" are not
valid: invalidated (slot1, slot2), logical (slot3), missing (slot4).
DETAIL: Logical replication is waiting because the required number of
standby slots is not available.

Thoughts?

3)
If elevel is ERROR, do we want to error-out on the first occurence of
invalid/missing slot? Shouldn't it look for first valid N slots in
case of priority, quorum and then decide for ERROR? Currently it seems
it will error out. So, if we go with solution 2b, this can also be
resolved with that.

~~

I have not tested the patch, so let me know if I have mis-understood the logic.

thanks
Shveta

#15Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#14)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi,

Thanks for the review.

On Wed, Mar 11, 2026 at 2:15 PM shveta malik <shveta.malik@gmail.com> wrote:

Had a look at the patch. Few concerns:

1)
StandbySlotsHaveCaughtup:

+ * If a slot listed in synchronized_standby_slots is not found,
+ * report an error.

--

+ * If a slot is not physical, report error.

These comments are misleading as we may or may not report ERROR
depending upon elevel passed by caller.

2)
It seems to me (not tested yet) that even in priority based and quorum
based configuration, if we have found our N slots, still we will end
up emitting WARNING message for invalidated, missing slots etc such
as:

a)
repplication slot \"%s\" specified in parameter \"%s\" does not exist
Logical replication is waiting on the standby associated with replication slot.

b)
cannot specify logical replication slot \"%s\" in parameter
Logical replication is waiting for correction on replication slot.

c)
physical replication slot \"%s\" specified in parameter \"%s\" has
been invalidated
Logical replication is waiting on the standby associated with replication slot.

These messages may give the impression that logical replication is
actually waiting, even though it might already be progressing normally
because the required N slots have been found.

Agreed. We will need to refactor the code around these messages so
that they are emitted only when necessary.

OTOH, if we suppress these messages, there could be cases where we
fail to find the required N valid slots and logical replication
genuinely ends up waiting, but the user would receive no indication of
the problem.

One thing for sure is, that we need to emit such messages when
'wait_for_all' is true, but for rest, we can not decide inline.

So there are 2 options:
a) either we change the DETAIL slightly with each such reporting to
say below or anything better:

DETAIL: logical replication may wait if the required number of standby
slots is not available.

b)
Or we collect the slot-names and emit the message at the end only 'if
(caught_up_slot_num < required)'. Something like:

WARNING: Some replication slots specified in parameter "%s" are not
valid: invalidated (slot1, slot2), logical (slot3), missing (slot4).
DETAIL: Logical replication is waiting because the required number of
standby slots is not available.

Thoughts?

For now, 2b seems like the better option to me as well - I will share
here if anything else (better than this) comes to mind while working
on it

--
With Regards,
Ashutosh Sharma.

#16Ajin Cherian
itsajin@gmail.com
In reply to: Ashutosh Sharma (#13)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

On Sun, Mar 8, 2026 at 4:16 AM Ashutosh Sharma <ashu.coek88@gmail.com> wrote:

Hi All,

Submitting a new version of the patch based on Satya's earlier work - [1].

Please take a look and let us know your thoughts.

[1] - /messages/by-id/CAHg+QDfU7rOebrLDESPpHSgdiadKbpCOmBokcbmM6Gr+A5VobQ@mail.gmail.com

Hi Ashutosh,

I was testing this patch and it seems, if the name of the slots starts
with first, say firstslot or firstsub, then the patch treats it as
FIRST 1 priority mode.

I tested with this:
synchronized_standby_slots = 'firstsub1, firstsub2'

regards,
Ajin Cherian
Fujitsu Australia

#17Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: Ajin Cherian (#16)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi Ajin,

On Thu, Mar 12, 2026 at 4:47 PM Ajin Cherian <itsajin@gmail.com> wrote:

On Sun, Mar 8, 2026 at 4:16 AM Ashutosh Sharma <ashu.coek88@gmail.com> wrote:

Hi All,

Submitting a new version of the patch based on Satya's earlier work - [1].

Please take a look and let us know your thoughts.

[1] - /messages/by-id/CAHg+QDfU7rOebrLDESPpHSgdiadKbpCOmBokcbmM6Gr+A5VobQ@mail.gmail.com

Hi Ashutosh,

I was testing this patch and it seems, if the name of the slots starts
with first, say firstslot or firstsub, then the patch treats it as
FIRST 1 priority mode.

Thanks for identifying and reporting this - confirmed, it is indeed an
issue. The attached patch addresses it and also adds a regression test
case for the same.

Additionally, it also fixes the issue related to log message reporting
for unavailable/invalid slots that Shveta raised yesterday.

Please take a look and feel free to share any further comments.

--
With Regards,
Ashutosh Sharma.

Attachments:

v20260312-0001-Add-FIRST-N-and-ANY-N-syntax-support-to-synchronized.patchapplication/octet-stream; name=v20260312-0001-Add-FIRST-N-and-ANY-N-syntax-support-to-synchronized.patchDownload+876-129
#18shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#17)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

On Thu, Mar 12, 2026 at 6:07 PM Ashutosh Sharma <ashu.coek88@gmail.com> wrote:

Hi Ajin,

On Thu, Mar 12, 2026 at 4:47 PM Ajin Cherian <itsajin@gmail.com> wrote:

On Sun, Mar 8, 2026 at 4:16 AM Ashutosh Sharma <ashu.coek88@gmail.com> wrote:

Hi All,

Submitting a new version of the patch based on Satya's earlier work - [1].

Please take a look and let us know your thoughts.

[1] - /messages/by-id/CAHg+QDfU7rOebrLDESPpHSgdiadKbpCOmBokcbmM6Gr+A5VobQ@mail.gmail.com

Hi Ashutosh,

I was testing this patch and it seems, if the name of the slots starts
with first, say firstslot or firstsub, then the patch treats it as
FIRST 1 priority mode.

Good catch.

Thanks for identifying and reporting this - confirmed, it is indeed an
issue. The attached patch addresses it and also adds a regression test
case for the same.

Additionally, it also fixes the issue related to log message reporting
for unavailable/invalid slots that Shveta raised yesterday.

Please take a look and feel free to share any further comments.

Thank You Ashutosh. A few comments:

1)
StandbySlotsHaveCaughtup():

+ /* If no specific slot state issues but requirement not met (slots
still lagging) */
+ if (num_slot_states == 0)
+ {
+ ereport(elevel,
+ errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("waiting for physical standbys corresponding to synchronized
standby slots, some slots have not caught up"));
+ }

Above means, when slots are lagging (not invalid), we will emit
WARNING or even error out in some cases (based on elevel). IIUC, this
behaviour is not the same as base code. Instead of ERROR, it used to
wait for lagging slots. Is this change intentional?

2)
Do you think we can move the reporting part (the below for-loop) to a
new function (may be report_unavailable_sync_standby_slots or anything
better) to keep the caught-up logic clean?
+ for (int i = 0; i < num_slot_states; i++)

3)

+ /*Record Slot State */
Space needed before Record.

4)
+ SS_SLOT_OK, /* slot is valid and can participate */
Do we need this value, we are not using it anywhere.

5)
check_synchronized_standby_slots():
+ /* Reject num_sync > nmembers — it can never be satisfied */
+ if (syncrep_parse_result->num_sync > syncrep_parse_result->nmembers)
+ {
+ GUC_check_errmsg("number of synchronized standby slots (%d) must not
exceed the number of listed slots (%d)",
+ syncrep_parse_result->num_sync,
+ syncrep_parse_result->nmembers);
+ return false;
+ }

Do we need this? Is it ever a possibility? Even if it happens, IIUC,
it will be our internal parser logic issue and not the user's GUC
configuration fault. So do we mean it to be user facing GUC error?

6)
If we plan to retain above, we shall move it before the previous 'if' block:

+ if (syncrep_parse_result->num_sync == 1 &&
+ syncrep_parse_result->syncrep_method == SYNC_REP_PRIORITY &&
+ syncrep_parse_result->nmembers > 1)

thanks
Shveta

#19Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#18)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

Hi,

Thanks for the review, please find comments inline:

On Fri, Mar 13, 2026 at 9:53 AM shveta malik <shveta.malik@gmail.com> wrote:

1)
StandbySlotsHaveCaughtup():

+ /* If no specific slot state issues but requirement not met (slots
still lagging) */
+ if (num_slot_states == 0)
+ {
+ ereport(elevel,
+ errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("waiting for physical standbys corresponding to synchronized
standby slots, some slots have not caught up"));
+ }

Above means, when slots are lagging (not invalid), we will emit
WARNING or even error out in some cases (based on elevel). IIUC, this
behaviour is not the same as base code. Instead of ERROR, it used to
wait for lagging slots. Is this change intentional?

Yes it was added intentionally, but the amount of information it was
emitting wasn't very much useful. It was just saying "some slots have
not caught up" which is already known by the fact that we are waiting.
It doesn't say which slots are lagging or by how much, so it was not
outputting any actionable information.

To make it more useful, this is how it has been changed now:

1) Add a SS_SLOT_LAGGING state to the enum to track slots that were
healthy but behind
2) Add a restart_lsn field to SyncStandbySlotsStateInfo to record how
far behind each lagging slot is
3) Record lagging slots in the scanning loop (currently they're just
skipped/broken out of without being saved)
4) Pass wait_for_lsn to ReportUnavailableSyncStandbySlots so it can
report the gap

With this change, we would see something like:

"replication slot "slot1" has not caught up, the slot's restart_lsn
0/1234 is behind the required 0/5678"

This looks more useful and actionable to me.

AFA elevel is concerned, it's mostly WARNING except when the server is
being stopped or when the cascaded standby is being promoted. So in
normal circumstances all these messages will always be reported as
WARNING, but still if you see any issues or you want the lagging slot
to be reported as WARNING always (even when the elevel is WARNING) do
let me know.

2)
Do you think we can move the reporting part (the below for-loop) to a
new function (may be report_unavailable_sync_standby_slots or anything
better) to keep the caught-up logic clean?
+ for (int i = 0; i < num_slot_states; i++)

Okay, moved the entire reporting logic to
ReportUnavailableSyncStandbySlots(). This function name pattern was
chosen considering the name of other functions in the file.

3)

+ /*Record Slot State */
Space needed before Record.

Added missing space.

4)
+ SS_SLOT_OK, /* slot is valid and can participate */
Do we need this value, we are not using it anywhere.

This was added just to make the enum look a little self documenting,
but it's true that it's not being used anywhere hence I removed it.

5)
check_synchronized_standby_slots():
+ /* Reject num_sync > nmembers — it can never be satisfied */
+ if (syncrep_parse_result->num_sync > syncrep_parse_result->nmembers)
+ {
+ GUC_check_errmsg("number of synchronized standby slots (%d) must not
exceed the number of listed slots (%d)",
+ syncrep_parse_result->num_sync,
+ syncrep_parse_result->nmembers);
+ return false;
+ }

Do we need this? Is it ever a possibility? Even if it happens, IIUC,
it will be our internal parser logic issue and not the user's GUC
configuration fault. So do we mean it to be user facing GUC error?

We need this to catch invalid settings like 'FIRST 5 (s1, s2, s3);'.
AFAICS this is actually a missing part in the check hook for
"synchronous_standby_names". It should have been present here as well.

6)
If we plan to retain above, we shall move it before the previous 'if' block:

+ if (syncrep_parse_result->num_sync == 1 &&
+ syncrep_parse_result->syncrep_method == SYNC_REP_PRIORITY &&
+ syncrep_parse_result->nmembers > 1)

I don't see any benefit in moving it upward, but it doesn't have any
functional harm as well, anyways I have just moved it up to the place
you suggested.

PFA patch with all the changes mentioned above and let me know if you
have any further comments.

--
With Regards,
Ashutosh Sharma.

Attachments:

v20260313-0001-Add-FIRST-N-and-ANY-N-syntax-support-to-synchronized.patchapplication/octet-stream; name=v20260313-0001-Add-FIRST-N-and-ANY-N-syntax-support-to-synchronized.patchDownload+894-128
#20shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#19)
Re: synchronized_standby_slots behavior inconsistent with quorum-based synchronous replication

On Fri, Mar 13, 2026 at 3:39 PM Ashutosh Sharma <ashu.coek88@gmail.com> wrote:

Hi,

Thanks for the review, please find comments inline:

On Fri, Mar 13, 2026 at 9:53 AM shveta malik <shveta.malik@gmail.com> wrote:

1)
StandbySlotsHaveCaughtup():

+ /* If no specific slot state issues but requirement not met (slots
still lagging) */
+ if (num_slot_states == 0)
+ {
+ ereport(elevel,
+ errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("waiting for physical standbys corresponding to synchronized
standby slots, some slots have not caught up"));
+ }

Above means, when slots are lagging (not invalid), we will emit
WARNING or even error out in some cases (based on elevel). IIUC, this
behaviour is not the same as base code. Instead of ERROR, it used to
wait for lagging slots. Is this change intentional?

Yes it was added intentionally, but the amount of information it was
emitting wasn't very much useful. It was just saying "some slots have
not caught up" which is already known by the fact that we are waiting.
It doesn't say which slots are lagging or by how much, so it was not
outputting any actionable information.

To make it more useful, this is how it has been changed now:

1) Add a SS_SLOT_LAGGING state to the enum to track slots that were
healthy but behind
2) Add a restart_lsn field to SyncStandbySlotsStateInfo to record how
far behind each lagging slot is
3) Record lagging slots in the scanning loop (currently they're just
skipped/broken out of without being saved)
4) Pass wait_for_lsn to ReportUnavailableSyncStandbySlots so it can
report the gap

With this change, we would see something like:

"replication slot "slot1" has not caught up, the slot's restart_lsn
0/1234 is behind the required 0/5678"

This looks more useful and actionable to me.

AFA elevel is concerned, it's mostly WARNING except when the server is
being stopped or when the cascaded standby is being promoted. So in
normal circumstances all these messages will always be reported as
WARNING, but still if you see any issues or you want the lagging slot
to be reported as WARNING always (even when the elevel is WARNING) do
let me know.

I modified the patch to emit WARNING instead of ERROR on lagging case.
I tested it for the case where standby is lagging, shutdown of primary
waits for standby to catch up:

--------------------
WARNING: replication slot "standby_1" specified in parameter
"synchronized_standby_slots" has not caught up
DETAIL: The slot's restart_lsn 0/26D1D250 is behind the required 0/26D1D2C0.
LOG: received fast shutdown request
LOG: aborting any active transactions
FATAL: terminating connection due to administrator command
LOG: background worker "logical replication launcher" (PID 144863)
exited with exit code 1
LOG: shutting down
WARNING: replication slot "standby_1" specified in parameter
"synchronized_standby_slots" has not caught up
DETAIL: The slot's restart_lsn 0/26D1D250 is behind the required 0/26D1D2C0.
WARNING: replication slot "standby_1" specified in parameter
"synchronized_standby_slots" has not caught up
DETAIL: The slot's restart_lsn 0/26D1D250 is behind the required 0/26D1D2C0.
LOG: released logical replication slot "sub1"
----------------------

This is how it is supposed to be as we want standby to catch-up before
the walsender exits on shutdown. Please see below code in
WalSndWaitForWal():

/*
* If postmaster asked us to stop and the standby slots have caught up
* to the flushed position, don't wait anymore.
*
* It's important to do this check after the recomputation of
* RecentFlushPtr, so we can send all remaining data before shutting
* down.
*/
if (got_STOPPING)
{
if (NeedToWaitForStandbys(RecentFlushPtr, &wait_event))
wait_for_standby_at_stop = true;
else
break;
}

But with the new change, walsender will ERROR out if standby is
lagging during shutdown. So we should avoid that. We can even skip
that complete section (case SS_SLOT_LAGGING in
ReportUnavailableSyncStandbySlots). But if we really want to have some
information for the user, we can make it DEBUG rather than Warning.
IMO, warning sounds alarming for the case where the user can not do
much. But let's see what others have to say on this.

2)
Do you think we can move the reporting part (the below for-loop) to a
new function (may be report_unavailable_sync_standby_slots or anything
better) to keep the caught-up logic clean?
+ for (int i = 0; i < num_slot_states; i++)

Okay, moved the entire reporting logic to
ReportUnavailableSyncStandbySlots(). This function name pattern was
chosen considering the name of other functions in the file.

Thanks, it has better readability now.

3)

+ /*Record Slot State */
Space needed before Record.

Added missing space.

4)
+ SS_SLOT_OK, /* slot is valid and can participate */
Do we need this value, we are not using it anywhere.

This was added just to make the enum look a little self documenting,
but it's true that it's not being used anywhere hence I removed it.

5)
check_synchronized_standby_slots():
+ /* Reject num_sync > nmembers — it can never be satisfied */
+ if (syncrep_parse_result->num_sync > syncrep_parse_result->nmembers)
+ {
+ GUC_check_errmsg("number of synchronized standby slots (%d) must not
exceed the number of listed slots (%d)",
+ syncrep_parse_result->num_sync,
+ syncrep_parse_result->nmembers);
+ return false;
+ }

Do we need this? Is it ever a possibility? Even if it happens, IIUC,
it will be our internal parser logic issue and not the user's GUC
configuration fault. So do we mean it to be user facing GUC error?

We need this to catch invalid settings like 'FIRST 5 (s1, s2, s3);'.
AFAICS this is actually a missing part in the check hook for
"synchronous_standby_names". It should have been present here as well.

Okay, I see this is for a wrong configuration.

6)
If we plan to retain above, we shall move it before the previous 'if' block:

+ if (syncrep_parse_result->num_sync == 1 &&
+ syncrep_parse_result->syncrep_method == SYNC_REP_PRIORITY &&
+ syncrep_parse_result->nmembers > 1)

I don't see any benefit in moving it upward, but it doesn't have any
functional harm as well, anyways I have just moved it up to the place
you suggested.

Please do as you feel fit. This comment was when I did not not have a
valid scenario in mind for the concerned case.

PFA patch with all the changes mentioned above and let me know if you
have any further comments.

Will review the rest of the changes.

thanks
Shveta

#21Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#20)
#22shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#21)
#23Amit Kapila
amit.kapila16@gmail.com
In reply to: Ashutosh Sharma (#21)
#24Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#22)
#25shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#24)
#26Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#25)
#27shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#26)
#28Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#27)
#29Zhijie Hou (Fujitsu)
houzj.fnst@fujitsu.com
In reply to: Ashutosh Sharma (#28)
#30shveta malik
shveta.malik@gmail.com
In reply to: Zhijie Hou (Fujitsu) (#29)
#31Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#30)
#32Zhijie Hou (Fujitsu)
houzj.fnst@fujitsu.com
In reply to: Ashutosh Sharma (#31)
#33Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: Zhijie Hou (Fujitsu) (#32)
#34shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#33)
#35Dilip Kumar
dilipbalaut@gmail.com
In reply to: Ashutosh Sharma (#28)
#36surya poondla
suryapoondla4@gmail.com
In reply to: SATYANARAYANA NARLAPURAM (#1)
#37Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: surya poondla (#36)
#38Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: surya poondla (#36)
#39Japin Li
japinli@hotmail.com
In reply to: Ashutosh Sharma (#38)
#40Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: Japin Li (#39)
#41shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#40)
#42Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#41)
#43Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#41)
#44surya poondla
suryapoondla4@gmail.com
In reply to: Ashutosh Sharma (#43)
#45shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#43)
#46Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#45)
#47shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#46)
#48shveta malik
shveta.malik@gmail.com
In reply to: shveta malik (#47)
#49Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#48)
#50shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#49)
#51shveta malik
shveta.malik@gmail.com
In reply to: shveta malik (#50)
#52Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#50)
#53Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: Ashutosh Sharma (#52)
#54shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#53)
#55Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#54)
#56Zhijie Hou (Fujitsu)
houzj.fnst@fujitsu.com
In reply to: Ashutosh Sharma (#55)
#57Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: Zhijie Hou (Fujitsu) (#56)
#58Ajin Cherian
itsajin@gmail.com
In reply to: Ashutosh Sharma (#57)
#59Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: Ajin Cherian (#58)
#60shveta malik
shveta.malik@gmail.com
In reply to: Ajin Cherian (#58)
#61shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#59)
#62Ajin Cherian
itsajin@gmail.com
In reply to: shveta malik (#60)
#63shveta malik
shveta.malik@gmail.com
In reply to: Ajin Cherian (#62)
#64Amit Kapila
amit.kapila16@gmail.com
In reply to: Ashutosh Sharma (#33)
#65SATYANARAYANA NARLAPURAM
satyanarlapuram@gmail.com
In reply to: Amit Kapila (#64)
#66Zhijie Hou (Fujitsu)
houzj.fnst@fujitsu.com
In reply to: Amit Kapila (#64)
#67Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: Amit Kapila (#64)
#68Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: Ashutosh Sharma (#67)
#69Amit Kapila
amit.kapila16@gmail.com
In reply to: Ashutosh Sharma (#68)
#70Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: Amit Kapila (#69)
#71shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#70)
#72Ashutosh Sharma
ashu.coek88@gmail.com
In reply to: shveta malik (#71)
#73shveta malik
shveta.malik@gmail.com
In reply to: Ashutosh Sharma (#72)