]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix inconsistent elevel in pg_sync_replication_slots() retry logic.
authorAmit Kapila <akapila@postgresql.org>
Fri, 6 Mar 2026 05:21:32 +0000 (10:51 +0530)
committerAmit Kapila <akapila@postgresql.org>
Fri, 6 Mar 2026 05:21:32 +0000 (10:51 +0530)
The commit 0d2d4a0ec3 allowed pg_sync_replication_slots() to retry sync
attempts, but missed a case, when WAL prior to a slot's
confirmed_flush_lsn is not yet flushed locally.

By changing the elevel from ERROR to LOG, we allow the sync loop to
continue. This provides the opportunity for the slot to be synchronized
once the standby catches up with the necessary WAL.

Author: Zhijie Hou <houzj.fnst@fujitsu.com>
Reviewed-by: shveta malik <shveta.malik@gmail.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Discussion: https://postgr.es/m/CAFPTHDZAA+gWDntpa5ucqKKba41=tXmoXqN3q4rpjO9cdxgQrw@mail.gmail.com

doc/src/sgml/func/func-admin.sgml
src/backend/replication/logical/slotsync.c

index 17319f9f969a3b909c98651d319df30552be720c..210b1118bdf74bbab7bbc1acf4fd789c243e0e03 100644 (file)
@@ -1495,7 +1495,9 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
         Synchronize the logical failover replication slots from the primary
         server to the standby server. This function can only be executed on the
         standby server. Temporary synced slots, if any, cannot be used for
-        logical decoding and must be dropped after promotion. See
+        logical decoding and must be dropped after promotion. This function
+        retries cyclically until all the failover slots that existed on
+        primary at the start of the function call are synchronized. See
         <xref linkend="logicaldecoding-replication-slots-synchronization"/> for details.
         Note that this function cannot be executed if
         <link linkend="guc-sync-replication-slots"><varname>
index 062a08ccb886646113b4f6373f28e370c706ec83..0c0399406f30a7e07f8908af9e2b32ec08940103 100644 (file)
  * RS_TEMPORARY. Once the decoding from corresponding LSNs can reach a
  * consistent point, they will be marked as RS_PERSISTENT.
  *
+ * If the WAL prior to the remote slot's confirmed_flush_lsn has not been
+ * flushed on the standby, the slot is marked as RS_TEMPORARY. Once the standby
+ * catches up and flushes that WAL, the slot will be marked as RS_PERSISTENT.
+ *
  * The slot sync worker waits for some time before the next synchronization,
  * with the duration varying based on whether any slots were updated during
  * the last cycle. Refer to the comments above wait_for_slot_activity() for
@@ -218,7 +222,7 @@ update_local_synced_slot(RemoteSlot *remote_slot, Oid remote_dbid)
                 * Can get here only if GUC 'synchronized_standby_slots' on the
                 * primary server was not configured correctly.
                 */
-               ereport(AmLogicalSlotSyncWorkerProcess() ? LOG : ERROR,
+               ereport(LOG,
                                errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
                                errmsg("skipping slot synchronization because the received slot sync"
                                           " LSN %X/%08X for slot \"%s\" is ahead of the standby position %X/%08X",