wait_replication_slot_xmin_v2.patch

application/octet-stream

Filename: wait_replication_slot_xmin_v2.patch
Type: application/octet-stream
Part: 0
Message: Re: BUG #18213: Standby's repeatable read isolation level transaction encountered a "nonrepeatable read" problem

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: unified
Series: patch v2
File+
src/backend/commands/indexcmds.c 23 0
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 0b3b8e98b8..e9c94f6550 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -424,6 +424,7 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress)
 	int			n_old_snapshots;
 	int			i;
 	VirtualTransactionId *old_snapshots;
+	TransactionId replication_slot_xmin = InvalidTransactionId;
 
 	old_snapshots = GetCurrentVirtualXIDs(limitXmin, true, false,
 										  PROC_IS_AUTOVACUUM | PROC_IN_VACUUM
@@ -483,6 +484,28 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress)
 		if (progress)
 			pgstat_progress_update_param(PROGRESS_WAITFOR_DONE, i + 1);
 	}
+
+	do
+	{
+		if (!TransactionIdIsNormal(limitXmin))
+			break;
+
+		/*
+		 * Wait for the oldest replication slot xmin to exceed limitXmin to prevent
+		 * standby being unable to access old version data through the newly built
+		 * index.
+		 * It is necessary to wait only if replication_slot_xmin is "normal".
+		 * Since replication catalog xmin doesn't take into account snapshots for
+		 * backend connections, it doesn't need to be considered
+		 */
+		CHECK_FOR_INTERRUPTS();
+		ProcArrayGetReplicationSlotXmin(&replication_slot_xmin, NULL);
+		if (!TransactionIdIsNormal(replication_slot_xmin))
+			break;
+		if (!NormalTransactionIdPrecedes(replication_slot_xmin, limitXmin))
+			break;
+		pg_usleep(1000000);
+	} while (true);
 }