v1-0001-Avoid-syscache-lookup-in-WAIT-FOR-LSN-tuple-descr.patch

application/octet-stream

Filename: v1-0001-Avoid-syscache-lookup-in-WAIT-FOR-LSN-tuple-descr.patch
Type: application/octet-stream
Part: 0
Message: Re: Implement waiting for wal lsn replay: reloaded

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 v1-0001
Subject: Avoid syscache lookup in WAIT FOR LSN tuple descriptor
File+
src/backend/commands/wait.c 22 4
From 50beec4de4e078020b03667453458cd440c26267 Mon Sep 17 00:00:00 2001
From: alterego655 <824662526@qq.com>
Date: Mon, 12 Jan 2026 14:36:27 +0800
Subject: [PATCH v1] Avoid syscache lookup in WAIT FOR LSN tuple descriptor

Use TupleDescInitBuiltinEntry instead of TupleDescInitEntry when
building the result tuple descriptor for WAIT FOR LSN. This avoids
a syscache access that could re-establish a catalog snapshot after
we've explicitly released all snapshots before the wait.
---
 src/backend/commands/wait.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/backend/commands/wait.c b/src/backend/commands/wait.c
index 97f1e778488..191c1877125 100644
--- a/src/backend/commands/wait.c
+++ b/src/backend/commands/wait.c
@@ -15,6 +15,7 @@
 
 #include <math.h>
 
+#include "access/tupdesc.h"
 #include "access/xlog.h"
 #include "access/xlogrecovery.h"
 #include "access/xlogwait.h"
@@ -320,7 +321,17 @@ ExecWaitStmt(ParseState *pstate, WaitStmt *stmt, DestReceiver *dest)
 			break;
 	}
 
-	/* need a tuple descriptor representing a single TEXT column */
+	/*
+	 * Output the result.
+	 *
+	 * We use TupleDescInitBuiltinEntry in WaitStmtResultDesc to avoid
+	 * syscache access when building the tuple descriptor. The standard output
+	 * path may briefly establish a catalog snapshot during output, but this
+	 * is acceptable since: 1. The snapshot window is very brief (just
+	 * emitting one row) 2. The critical section (the wait itself) is already
+	 * snapshot-free 3. Using the standard path respects receiver lifecycle
+	 * and semantics
+	 */
 	tupdesc = WaitStmtResultDesc(stmt);
 
 	/* prepare for projection of tuples */
@@ -337,9 +348,16 @@ WaitStmtResultDesc(WaitStmt *stmt)
 {
 	TupleDesc	tupdesc;
 
-	/* Need a tuple descriptor representing a single TEXT  column */
+	/*
+	 * Need a tuple descriptor representing a single TEXT column.
+	 *
+	 * We use TupleDescInitBuiltinEntry instead of TupleDescInitEntry to avoid
+	 * syscache access. This is important because WaitStmtResultDesc may be
+	 * called after snapshots have been released, and we must not re-establish
+	 * a catalog snapshot which could cause recovery conflicts on a standby.
+	 */
 	tupdesc = CreateTemplateTupleDesc(1);
-	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "status",
-					   TEXTOID, -1, 0);
+	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "status",
+							  TEXTOID, -1, 0);
 	return tupdesc;
 }
-- 
2.51.0