On Thu, 23 Oct 2025 at 13:19, Shlok Kyal <[email protected]> wrote:
>
> On Thu, 23 Oct 2025 at 09:36, Amit Kapila <[email protected]> wrote:
> >
> > On Thu, Oct 9, 2025 at 10:53 AM Amit Kapila <[email protected]> wrote:
> > >
> > > On Wed, Oct 8, 2025 at 9:05 PM Fabrice Chapuis <[email protected]> 
> > > wrote:
> > > >
> > > > As Ashutosh suggests I will go more for the backpatching approach 
> > > > because the synchronized_standby_slots parameter impacts the last 2 
> > > > major versions and this problem is critical on production environments.
> > > >
> > >
> > > Fair enough. Let's wait for the related issue being discussed in email
> > > [1] to be fixed.
> > >
> >
> > As the other patch is committed
> > (f33e60a53a9ca89b5078df49416acae20affe1f5), can you update and prepare
> > backbranch patches for this fix as well?
> >
> Hi Amit,
>
> Please find the updated patch.
>
> v6-0001 : It applies on HEAD and REL_18_STABLE branches
> v6_REL_17-0001 : It applies on REL_17_STABLE branch.
>
> Since this GUC was introduced in PG_17, we do not need to back-patch
> to PG_16 or prior.
>
The CFbot was failing due to the merge conflict. It happened because
CFbot tried to apply v6_REL_17 on top of v6-0001 patch. Added
v6_REL_17 as a .txt file so this merge conflict do not happen.

Thanks,
Shlok Kyal
From 8d37e280aee3a2e99888b1ab96d1d3ffe779ba8d Mon Sep 17 00:00:00 2001
From: Shlok Kyal <[email protected]>
Date: Thu, 23 Oct 2025 11:09:47 +0530
Subject: [PATCH v6_REL_17] Remove the validation from the GUC check hook and
 add parsing check

The validation in check_synchronized_standby_slots cannot be run
in postmaster and hence can result inconsistent values in some
backends that inherit the value from postmaster and those
that are started newly. Also, this validation results in parallel
workers fail to with error. This causes all the commands run by
parallel workers to fail, which seems unnecesary. This validation
already happens in StandbySlotsHaveCaughtup() where this GUC is
used, so it can be removed from the GUC check. Also added a
parsing check for the slot names specified in this GUC.
---
 src/backend/replication/slot.c    | 58 ++++++++-----------------------
 src/test/regress/expected/guc.out | 26 ++++++++++++++
 src/test/regress/sql/guc.sql      | 16 +++++++++
 3 files changed, 57 insertions(+), 43 deletions(-)

diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 80b8abde3a2..e2a16a513a9 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -2468,53 +2468,31 @@ GetSlotInvalidationCause(const char 
*invalidation_reason)
 static bool
 validate_sync_standby_slots(char *rawname, List **elemlist)
 {
-       bool            ok;
-
        /* Verify syntax and parse string into a list of identifiers */
-       ok = SplitIdentifierString(rawname, ',', elemlist);
-
-       if (!ok)
+       if (!SplitIdentifierString(rawname, ',', elemlist))
        {
                GUC_check_errdetail("List syntax is invalid.");
+               return false;
        }
-       else if (MyProc)
+
+       foreach_ptr(char, name, *elemlist)
        {
-               /*
-                * Check that each specified slot exist and is physical.
-                *
-                * Because we need an LWLock, we cannot do this on processes 
without a
-                * PGPROC, so we skip it there; but see comments in
-                * StandbySlotsHaveCaughtup() as to why that's not a problem.
-                */
-               LWLockAcquire(ReplicationSlotControlLock, LW_SHARED);
+               int                     err_code;
+               char       *err_msg = NULL;
+               char       *err_hint = NULL;
 
-               foreach_ptr(char, name, *elemlist)
+               if (!ReplicationSlotValidateNameInternal(name, &err_code, 
&err_msg,
+                                                                               
                 &err_hint))
                {
-                       ReplicationSlot *slot;
-
-                       slot = SearchNamedReplicationSlot(name, false);
-
-                       if (!slot)
-                       {
-                               GUC_check_errdetail("replication slot \"%s\" 
does not exist",
-                                                                       name);
-                               ok = false;
-                               break;
-                       }
-
-                       if (!SlotIsPhysical(slot))
-                       {
-                               GUC_check_errdetail("\"%s\" is not a physical 
replication slot",
-                                                                       name);
-                               ok = false;
-                               break;
-                       }
+                       GUC_check_errcode(err_code);
+                       GUC_check_errdetail("%s", err_msg);
+                       if (err_hint != NULL)
+                               GUC_check_errhint("%s", err_hint);
+                       return false;
                }
-
-               LWLockRelease(ReplicationSlotControlLock);
        }
 
-       return ok;
+       return true;
 }
 
 /*
@@ -2672,12 +2650,6 @@ StandbySlotsHaveCaughtup(XLogRecPtr wait_for_lsn, int 
elevel)
                /*
                 * If a slot name provided in synchronized_standby_slots does 
not
                 * exist, report a message and exit the loop.
-                *
-                * Though validate_sync_standby_slots (the GUC check_hook) 
tries to
-                * avoid this, it can nonetheless happen because the user can 
specify
-                * a nonexistent slot name before server startup. That function 
cannot
-                * validate such a slot during startup, as ReplicationSlotCtl 
is not
-                * initialized by then.  Also, the user might have dropped one 
slot.
                 */
                if (!slot)
                {
diff --git a/src/test/regress/expected/guc.out 
b/src/test/regress/expected/guc.out
index 455b6d6c0ce..efb845f0339 100644
--- a/src/test/regress/expected/guc.out
+++ b/src/test/regress/expected/guc.out
@@ -888,3 +888,29 @@ SELECT name FROM tab_settings_flags
 (0 rows)
 
 DROP TABLE tab_settings_flags;
+-- Test for GUC synchronized standby slots
+-- Cannot set synchronized_standby_slots to a invalid slot name.
+ALTER SYSTEM SET synchronized_standby_slots='invalid*';
+ERROR:  invalid value for parameter "synchronized_standby_slots": "invalid*"
+DETAIL:  replication slot name "invalid*" contains invalid character
+HINT:  Replication slot names may only contain lower case letters, numbers, 
and the underscore character.
+-- Can set synchronized_standby_slots to a non-existent slot name.
+ALTER SYSTEM SET synchronized_standby_slots='missing';
+SELECT pg_reload_conf();
+ pg_reload_conf 
+----------------
+ t
+(1 row)
+
+-- Parallel worker does not throw error during startup.
+SET min_parallel_table_scan_size TO 0;
+SET parallel_setup_cost TO 0;
+SET parallel_tuple_cost TO 0;
+CREATE TABLE t1(a int);
+INSERT INTO t1 VALUES(1), (2), (3), (4);
+SELECT count(*) FROM t1;
+ count 
+-------
+     4
+(1 row)
+
diff --git a/src/test/regress/sql/guc.sql b/src/test/regress/sql/guc.sql
index dc79761955d..c0c6c9f98a2 100644
--- a/src/test/regress/sql/guc.sql
+++ b/src/test/regress/sql/guc.sql
@@ -353,3 +353,19 @@ SELECT name FROM tab_settings_flags
   WHERE no_reset AND NOT no_reset_all
   ORDER BY 1;
 DROP TABLE tab_settings_flags;
+
+-- Test for GUC synchronized standby slots
+-- Cannot set synchronized_standby_slots to a invalid slot name.
+ALTER SYSTEM SET synchronized_standby_slots='invalid*';
+
+-- Can set synchronized_standby_slots to a non-existent slot name.
+ALTER SYSTEM SET synchronized_standby_slots='missing';
+SELECT pg_reload_conf();
+
+-- Parallel worker does not throw error during startup.
+SET min_parallel_table_scan_size TO 0;
+SET parallel_setup_cost TO 0;
+SET parallel_tuple_cost TO 0;
+CREATE TABLE t1(a int);
+INSERT INTO t1 VALUES(1), (2), (3), (4);
+SELECT count(*) FROM t1;
-- 
2.34.1

Attachment: v6-0001-Remove-the-validation-from-the-GUC-check-hook-and.patch
Description: Binary data

Reply via email to