0001-Fix-invalidation-when-slot-is-created-during-checkpo.patch

text/x-patch

Filename: 0001-Fix-invalidation-when-slot-is-created-during-checkpo.patch
Type: text/x-patch
Part: 1
Message: Re: Newly created replication slot may be invalidated by checkpoint

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch 0001
Subject: Fix invalidation when slot is created during checkpoint
File+
src/backend/access/transam/xlog.c 9 2
From daf346f515236246217101af0f6c6fec4e57c77e Mon Sep 17 00:00:00 2001
From: Vitaly Davydov <v.davydov@postgrespro.ru>
Date: Wed, 17 Sep 2025 13:29:54 +0300
Subject: [PATCH] Fix invalidation when slot is created during checkpoint

The commit 2090edc6f32f652a2c introduced an issue of slot invalidation
if the slot was creating during checkpoint. The issue happens in 17 and
earlier versions. The reason was in calculation of oldest slots' lsn at
the beginning of the checkpoint which is used in wal removal function.
If the slot reserved the wal during checkpoint, the new oldest value
may be lesser than the calculated value at the beginning of the
checkpoint. As the result, the new slot is invalidated unexpectedly.

To fix the issue, the oldest slots' lsn is calculated as the minimal
value of these two values: the current oldest slots' lsn and the oldest
slots' lsn at the beginning of the checkpoint.

Discussion: https://www.postgresql.org/message-id/flat/5e045179-236f-4f8f-84f1-0f2566ba784c.mengjuan.cmj%40alibaba-inc.com
---
 src/backend/access/transam/xlog.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 09fe5272022..8a2f5dda332 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7973,8 +7973,15 @@ KeepLogSeg(XLogRecPtr recptr, XLogRecPtr slotsMinReqLSN, XLogSegNo *logSegNo)
 	XLByteToSeg(recptr, currSegNo, wal_segment_size);
 	segno = currSegNo;
 
-	/* Calculate how many segments are kept by slots. */
-	keep = slotsMinReqLSN;
+	/*
+	 * Calculate how many segments are kept by slots. Keep the wal using
+	 * the minimal value from the current reserved LSN and the reserved LSN at
+	 * the moment of checkpoint start (before CheckPointReplicationSlots).
+	 */
+	keep = XLogGetReplicationSlotMinimumLSN();
+	if (!XLogRecPtrIsInvalid(slotsMinReqLSN))
+		keep = Min(keep, slotsMinReqLSN);
+
 	if (keep != InvalidXLogRecPtr && keep < recptr)
 	{
 		XLByteToSeg(keep, segno, wal_segment_size);
-- 
2.34.1