@@ -187,6 +187,9 @@ update_local_synced_slot(RemoteSlot *remote_slot, Oid remote_dbid,
187187TransactionIdPrecedes (remote_slot -> catalog_xmin ,
188188slot -> data .catalog_xmin ))
189189{
190+ /* Update slot sync skip stats */
191+ pgstat_report_replslotsync (slot );
192+
190193/*
191194 * This can happen in following situations:
192195 *
@@ -277,6 +280,13 @@ update_local_synced_slot(RemoteSlot *remote_slot, Oid remote_dbid,
277280errdetail_internal ("Remote slot has LSN %X/%08X but local slot has LSN %X/%08X." ,
278281LSN_FORMAT_ARGS (remote_slot -> confirmed_lsn ),
279282LSN_FORMAT_ARGS (slot -> data .confirmed_flush )));
283+
284+ /*
285+ * If we can't reach a consistent snapshot, the slot won't be
286+ * persisted. See update_and_persist_local_synced_slot().
287+ */
288+ if (found_consistent_snapshot && !(* found_consistent_snapshot ))
289+ pgstat_report_replslotsync (slot );
280290}
281291
282292updated_xmin_or_lsn = true;
@@ -563,6 +573,7 @@ update_and_persist_local_synced_slot(RemoteSlot *remote_slot, Oid remote_dbid)
563573bool found_consistent_snapshot = false;
564574bool remote_slot_precedes = false;
565575
576+ /* Slotsync skip stats are handled in function update_local_synced_slot() */
566577(void )update_local_synced_slot (remote_slot ,remote_dbid ,
567578& found_consistent_snapshot ,
568579& remote_slot_precedes );
@@ -624,31 +635,9 @@ static bool
624635synchronize_one_slot (RemoteSlot * remote_slot ,Oid remote_dbid )
625636{
626637ReplicationSlot * slot ;
627- XLogRecPtr latestFlushPtr ;
638+ XLogRecPtr latestFlushPtr = GetStandbyFlushRecPtr ( NULL ) ;
628639bool slot_updated = false;
629640
630- /*
631- * Make sure that concerned WAL is received and flushed before syncing
632- * slot to target lsn received from the primary server.
633- */
634- latestFlushPtr = GetStandbyFlushRecPtr (NULL );
635- if (remote_slot -> confirmed_lsn > latestFlushPtr )
636- {
637- /*
638- * Can get here only if GUC 'synchronized_standby_slots' on the
639- * primary server was not configured correctly.
640- */
641- ereport (AmLogicalSlotSyncWorkerProcess () ?LOG :ERROR ,
642- errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
643- errmsg ("skipping slot synchronization because the received slot sync"
644- " LSN %X/%08X for slot \"%s\" is ahead of the standby position %X/%08X" ,
645- LSN_FORMAT_ARGS (remote_slot -> confirmed_lsn ),
646- remote_slot -> name ,
647- LSN_FORMAT_ARGS (latestFlushPtr )));
648-
649- return false;
650- }
651-
652641/* Search for the named slot */
653642if ((slot = SearchNamedReplicationSlot (remote_slot -> name , true)))
654643{
@@ -707,10 +696,38 @@ synchronize_one_slot(RemoteSlot *remote_slot, Oid remote_dbid)
707696/* Skip the sync of an invalidated slot */
708697if (slot -> data .invalidated != RS_INVAL_NONE )
709698{
699+ pgstat_report_replslotsync (slot );
700+
710701ReplicationSlotRelease ();
711702return slot_updated ;
712703}
713704
705+ /*
706+ * Make sure that concerned WAL is received and flushed before syncing
707+ * slot to target lsn received from the primary server.
708+ *
709+ * Report statistics only after the slot has been acquired, ensuring
710+ * it cannot be dropped during the reporting process.
711+ */
712+ if (remote_slot -> confirmed_lsn > latestFlushPtr )
713+ {
714+ pgstat_report_replslotsync (slot );
715+
716+ /*
717+ * Can get here only if GUC 'synchronized_standby_slots' on the
718+ * primary server was not configured correctly.
719+ */
720+ ereport (AmLogicalSlotSyncWorkerProcess () ?LOG :ERROR ,
721+ errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
722+ errmsg ("skipping slot synchronization because the received slot sync"
723+ " LSN %X/%08X for slot \"%s\" is ahead of the standby position %X/%08X" ,
724+ LSN_FORMAT_ARGS (remote_slot -> confirmed_lsn ),
725+ remote_slot -> name ,
726+ LSN_FORMAT_ARGS (latestFlushPtr )));
727+
728+ return slot_updated ;
729+ }
730+
714731/* Slot not ready yet, let's attempt to make it sync-ready now. */
715732if (slot -> data .persistency == RS_TEMPORARY )
716733{
@@ -784,6 +801,32 @@ synchronize_one_slot(RemoteSlot *remote_slot, Oid remote_dbid)
784801ReplicationSlotsComputeRequiredXmin (true);
785802LWLockRelease (ProcArrayLock );
786803
804+ /*
805+ * Make sure that concerned WAL is received and flushed before syncing
806+ * slot to target lsn received from the primary server.
807+ *
808+ * Report statistics only after the slot has been acquired, ensuring
809+ * it cannot be dropped during the reporting process.
810+ */
811+ if (remote_slot -> confirmed_lsn > latestFlushPtr )
812+ {
813+ pgstat_report_replslotsync (slot );
814+
815+ /*
816+ * Can get here only if GUC 'synchronized_standby_slots' on the
817+ * primary server was not configured correctly.
818+ */
819+ ereport (AmLogicalSlotSyncWorkerProcess () ?LOG :ERROR ,
820+ errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
821+ errmsg ("skipping slot synchronization because the received slot sync"
822+ " LSN %X/%08X for slot \"%s\" is ahead of the standby position %X/%08X" ,
823+ LSN_FORMAT_ARGS (remote_slot -> confirmed_lsn ),
824+ remote_slot -> name ,
825+ LSN_FORMAT_ARGS (latestFlushPtr )));
826+
827+ return false;
828+ }
829+
787830update_and_persist_local_synced_slot (remote_slot ,remote_dbid );
788831
789832slot_updated = true;