v1-0003-Pg-stat-replication.patch

application/x-patch

Filename: v1-0003-Pg-stat-replication.patch
Type: application/x-patch
Part: 2
Message: [PATCH] Add cascade synchronous replication

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-0003
Subject: Pg stat replication Add new states to pg_stat_replication. They were added for the synchronous node that sends invalid values. These are indicated by a question mark and are needed to speed up problem localization.
File+
src/backend/replication/walsender.c 15 3
src/include/access/xlogdefs.h 1 0
From f4f56dafc0c925b3d8909b985cc8245988f74b5d Mon Sep 17 00:00:00 2001
From: reVInotip <grigoriy.novikov220@gmail.com>
Date: Sat, 18 Oct 2025 13:00:17 +0700
Subject: [PATCH 3/4] Pg stat replication
 Add new states to pg_stat_replication. They were added for the synchronous
 node that sends invalid values. These are indicated by a question mark and
 are needed to speed up problem localization.

---
 src/backend/replication/walsender.c | 18 +++++++++++++++---
 src/include/access/xlogdefs.h       |  1 +
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 90b12edf58a..2c92ef6d530 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -4099,14 +4099,26 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 			 * be switched to "potential" ones at the next moment. So, it's
 			 * basically useless to report "sync" or "potential" as their sync
 			 * states. We report just "quorum" for them.
+			 *
+			 * A question mark at the end of the role name indicates that the sending
+			 * LSN cannot be calculated on this synchronous standby or on its standbys.
 			 */
 			if (priority == 0)
 				values[10] = CStringGetTextDatum("async");
 			else if (is_sync_standby)
-				values[10] = SyncRepConfig->syncrep_method == SYNC_REP_PRIORITY ?
-					CStringGetTextDatum("sync") : CStringGetTextDatum("quorum");
+			{
+				if (XLogRecPtrIsDefaultSending(flush))
+					values[10] = SyncRepConfig->syncrep_method == SYNC_REP_PRIORITY ?
+						CStringGetTextDatum("sync?") : CStringGetTextDatum("quorum?");
+				else
+					values[10] = SyncRepConfig->syncrep_method == SYNC_REP_PRIORITY ?
+						CStringGetTextDatum("sync") : CStringGetTextDatum("quorum");
+			}
 			else
-				values[10] = CStringGetTextDatum("potential");
+				if (XLogRecPtrIsDefaultSending(flush))
+					values[10] = CStringGetTextDatum("potential?");
+				else
+					values[10] = CStringGetTextDatum("potential");
 
 			if (replyTime == 0)
 				nulls[11] = true;
diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h
index c870c51d13d..ae5bfc6881e 100644
--- a/src/include/access/xlogdefs.h
+++ b/src/include/access/xlogdefs.h
@@ -34,6 +34,7 @@ typedef uint64 XLogRecPtr;
  * (for example, when the number of synchronous standbys is less than required).
  */
 #define DefaultSendingLSN   ((XLogRecPtr) 2)
+#define XLogRecPtrIsDefaultSending(r)   ((r) == DefaultSendingLSN)
 
 /*
  * First LSN to use for "fake" LSNs.