At Thu, 9 Nov 2023 09:53:07 +0530, Amit Kapila <amit.kapil...@gmail.com> wrote 
in 
> Michael, Horiguchi-San, and others, do you have any thoughts on what
> is the best way to proceed?

As I previously mentioned, I believe that if rejection is to be the
course of action, it would be best to proceed with it sooner rather
than later. On the other hand, I am concerned about the need for users
to perform extra steps depending on the source cluster
conrfiguration. Therefore, another possible approach could be to
simply ignore the given settings in the assignment hook rather than
rejecting by the check hook, and forcibuly apply -1.

What do you think about this third approach?

I haven't checked this with pg_upgrade, but a standalone postmaster
would emit the following messages.

> postgres -b -c max_slot_wal_keep_size=-1
> LOG:  "max_slot_wal_keep_size" is foced to set to -1 during binary upgrade 
> mode.

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
diff --git a/src/backend/access/transam/xlog.c 
b/src/backend/access/transam/xlog.c
index b541be8eec..319d4f5a81 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2063,6 +2063,31 @@ check_wal_segment_size(int *newval, void **extra, 
GucSource source)
        return true;
 }
 
+/*
+ * GUC check_hook for max_slot_wal_keep_size
+ *
+ * If WALs needed by logical replication slots are deleted, these slots become
+ * inoperable. During a binary upgrade, pg_upgrade sets this variable to -1 via
+ * the command line in an attempt to prevent such deletions, but users have
+ * ways to override it. To ensure the successful completion of the upgrade,
+ * it's essential to keep this variable unaltered.  See
+ * InvalidatePossiblyObsoleteSlot() and start_postmaster() in pg_upgrade for
+ * more details.
+ */
+bool
+check_max_slot_wal_keep_size(int *newval, void **extra, GucSource source)
+{
+       if (IsBinaryUpgrade && *newval != -1)
+       {
+               ereport(LOG,
+                               errmsg("\"%s\" is foced to set to -1 during 
binary upgrade mode.",
+                                          "max_slot_wal_keep_size"));
+               *newval = -1;
+       }
+
+       return true;
+}
+
 /*
  * At a checkpoint, how many WAL segments to recycle as preallocated future
  * XLOG segments? Returns the highest segment that should be preallocated.
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 99823df3c7..5c3d2b1082 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -1424,18 +1424,12 @@ 
InvalidatePossiblyObsoleteSlot(ReplicationSlotInvalidationCause cause,
                SpinLockRelease(&s->mutex);
 
                /*
-                * The logical replication slots shouldn't be invalidated as
-                * max_slot_wal_keep_size GUC is set to -1 during the upgrade.
-                *
-                * The following is just a sanity check.
+                * check_max_slot_wal_keep_size() ensures 
max_slot_wal_keep_size is set
+                * to -1, so, slot invalidation for logical slots shouldn't 
happen
+                * during an upgrade. At present, only logical slots really 
require
+                * this.
                 */
-               if (*invalidated && SlotIsLogical(s) && IsBinaryUpgrade)
-               {
-                       ereport(ERROR,
-                                       
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                       errmsg("replication slots must not be 
invalidated during the upgrade"),
-                                       errhint("\"max_slot_wal_keep_size\" 
must be set to -1 during the upgrade"));
-               }
+               Assert (!(*invalidated && SlotIsLogical(s) && IsBinaryUpgrade));
 
                if (active_pid != 0)
                {
diff --git a/src/backend/utils/misc/guc_tables.c 
b/src/backend/utils/misc/guc_tables.c
index 7605eff9b9..818ffdb2ae 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -2845,7 +2845,7 @@ struct config_int ConfigureNamesInt[] =
                },
                &max_slot_wal_keep_size_mb,
                -1, -1, MAX_KILOBYTES,
-               NULL, NULL, NULL
+               check_max_slot_wal_keep_size, NULL, NULL
        },
 
        {
diff --git a/src/include/utils/guc_hooks.h b/src/include/utils/guc_hooks.h
index 2a191830a8..3d74483f44 100644
--- a/src/include/utils/guc_hooks.h
+++ b/src/include/utils/guc_hooks.h
@@ -84,6 +84,8 @@ extern bool check_maintenance_io_concurrency(int *newval, 
void **extra,
 extern void assign_maintenance_io_concurrency(int newval, void *extra);
 extern bool check_max_connections(int *newval, void **extra, GucSource source);
 extern bool check_max_wal_senders(int *newval, void **extra, GucSource source);
+extern bool check_max_slot_wal_keep_size(int *newval, void **extra,
+                                                                               
 GucSource source);
 extern void assign_max_wal_size(int newval, void *extra);
 extern bool check_max_worker_processes(int *newval, void **extra,
                                                                           
GucSource source);

Reply via email to