summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorAmit Kapila <akapila@postgresql.org>2025-07-11 10:46:43 +0530
committerAmit Kapila <akapila@postgresql.org>2025-07-11 10:46:43 +0530
commit72e6c08fea7cf59f5166e138aab927ad87570aa4 (patch)
tree661b2b2e2fae73f6361e34a138208ff72be8b100 /src/backend
parent4cff01c4a3472ecd2a53f957f13ab20a2970db4c (diff)
Fix the handling of two GUCs during upgrade.
Previously, the check_hook functions for max_slot_wal_keep_size and idle_replication_slot_timeout would incorrectly raise an ERROR for values set in postgresql.conf during upgrade, even though those values were not actively used in the upgrade process. To prevent logical slot invalidation during upgrade, we used to set special values for these GUCs. Now, instead of relying on those values, we directly prevent WAL removal and logical slot invalidation caused by max_slot_wal_keep_size and idle_replication_slot_timeout. Note: PostgreSQL 17 does not include the idle_replication_slot_timeout GUC, so related changes were not backported. BUG #18979 Reported-by: jorsol <jorsol@gmail.com> Author: Dilip Kumar <dilipbalaut@gmail.com> Reviewed by: vignesh C <vignesh21@gmail.com> Reviewed by: Alvaro Herrera <alvherre@alvh.no-ip.org> Backpatch-through: 17, where it was introduced Discussion: https://postgr.es/m/219561.1751826409@sss.pgh.pa.us Discussion: https://postgr.es/m/18979-a1b7fdbb7cd181c6@postgresql.org
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/transam/xlog.c33
-rw-r--r--src/backend/replication/slot.c32
-rw-r--r--src/backend/utils/misc/guc_tables.c4
3 files changed, 14 insertions, 55 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index a8cc6402d62..304b60933c9 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2347,25 +2347,6 @@ check_wal_segment_size(int *newval, void **extra, GucSource source)
}
/*
- * GUC check_hook for max_slot_wal_keep_size
- *
- * We don't allow the value of max_slot_wal_keep_size other than -1 during the
- * binary upgrade. See 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)
- {
- GUC_check_errdetail("\"%s\" must be set to -1 during binary upgrade mode.",
- "max_slot_wal_keep_size");
- return false;
- }
-
- return true;
-}
-
-/*
* At a checkpoint, how many WAL segments to recycle as preallocated future
* XLOG segments? Returns the highest segment that should be preallocated.
*/
@@ -8150,17 +8131,19 @@ KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
XLByteToSeg(recptr, currSegNo, wal_segment_size);
segno = currSegNo;
- /*
- * Calculate how many segments are kept by slots first, adjusting for
- * max_slot_wal_keep_size.
- */
+ /* Calculate how many segments are kept by slots. */
keep = XLogGetReplicationSlotMinimumLSN();
if (keep != InvalidXLogRecPtr && keep < recptr)
{
XLByteToSeg(keep, segno, wal_segment_size);
- /* Cap by max_slot_wal_keep_size ... */
- if (max_slot_wal_keep_size_mb >= 0)
+ /*
+ * Account for max_slot_wal_keep_size to avoid keeping more than
+ * configured. However, don't do that during a binary upgrade: if
+ * slots were to be invalidated because of this, it would not be
+ * possible to preserve logical ones during the upgrade.
+ */
+ if (max_slot_wal_keep_size_mb >= 0 && !IsBinaryUpgrade)
{
uint64 slot_keep_segs;
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 281092279ac..e44ad576bc7 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -1888,15 +1888,6 @@ InvalidatePossiblyObsoleteSlot(uint32 possible_causes,
SpinLockRelease(&s->mutex);
/*
- * The logical replication slots shouldn't be invalidated as GUC
- * max_slot_wal_keep_size is set to -1 and
- * idle_replication_slot_timeout is set to 0 during the binary
- * upgrade. See check_old_cluster_for_valid_slots() where we ensure
- * that no slot was invalidated before the upgrade.
- */
- Assert(!(*invalidated && SlotIsLogical(s) && IsBinaryUpgrade));
-
- /*
* Calculate the idle time duration of the slot if slot is marked
* invalidated with RS_INVAL_IDLE_TIMEOUT.
*/
@@ -2042,6 +2033,10 @@ restart:
if (!s->in_use)
continue;
+ /* Prevent invalidation of logical slots during binary upgrade */
+ if (SlotIsLogical(s) && IsBinaryUpgrade)
+ continue;
+
if (InvalidatePossiblyObsoleteSlot(possible_causes, s, oldestLSN, dboid,
snapshotConflictHorizon,
&invalidated))
@@ -3054,22 +3049,3 @@ WaitForStandbyConfirmation(XLogRecPtr wait_for_lsn)
ConditionVariableCancelSleep();
}
-
-/*
- * GUC check_hook for idle_replication_slot_timeout
- *
- * The value of idle_replication_slot_timeout must be set to 0 during
- * a binary upgrade. See start_postmaster() in pg_upgrade for more details.
- */
-bool
-check_idle_replication_slot_timeout(int *newval, void **extra, GucSource source)
-{
- if (IsBinaryUpgrade && *newval != 0)
- {
- GUC_check_errdetail("\"%s\" must be set to 0 during binary upgrade mode.",
- "idle_replication_slot_timeout");
- return false;
- }
-
- return true;
-}
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index a925be86944..d14b1678e7f 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -3081,7 +3081,7 @@ struct config_int ConfigureNamesInt[] =
},
&max_slot_wal_keep_size_mb,
-1, -1, MAX_KILOBYTES,
- check_max_slot_wal_keep_size, NULL, NULL
+ NULL, NULL, NULL
},
{
@@ -3104,7 +3104,7 @@ struct config_int ConfigureNamesInt[] =
},
&idle_replication_slot_timeout_secs,
0, 0, INT_MAX,
- check_idle_replication_slot_timeout, NULL, NULL
+ NULL, NULL, NULL
},
{