public inbox for pgsql-hackers@postgresql.org  
help / color / mirror / Atom feed
From: Chao Li <li.evan.chao@gmail.com>
To: PostgreSQL-development <pgsql-hackers@postgresql.org>
Cc: Michael Paquier <michael.paquier@gmail.com>
Cc: Xuneng Zhou <xunengzhou@gmail.com>
Subject: Fix pg_stat_wal_receiver to show CONNECTING status
Date: Tue, 19 May 2026 13:55:14 +0800
Message-ID: <EF91FF76-1E2B-4F3B-9162-290B4DC517FF@gmail.com> (raw)

Hi,

I just tested "Add WALRCV_CONNECTING state to the WAL receiver” and found an issue.

Commit a36164e74 added the feature, and the commit message says:
```
...
the WAL receiver is ready to stream changes. This change is useful for
monitoring purposes, especially in environments with a high latency
where a connection could take some time to be established, giving some
room between the [re]start phase and the streaming activity.
```

However, I failed to see the CONNECTING status. To simulate a high-latency primary connection, I shut down the real primary server and created a fake socket server:
```
chaol@ChaodeMacBook-Air ~ % perl -MIO::Socket::INET -e '
  $s = IO::Socket::INET->new(
    LocalAddr => "127.0.0.1",
    LocalPort => 5432,
    Listen => 1,
    ReuseAddr => 1
  ) or die $!;
  $c = $s->accept;
  sleep 600;
'
```

Then pg_stat_wal_receiver only shows an empty result:
```
evantest=# SELECT * FROM pg_stat_wal_receiver;
 pid | status | receive_start_lsn | receive_start_tli | written_lsn | flushed_lsn | received_tli | last_msg_send_time | last_msg_receipt_time | latest_end_lsn | latest_end_time | slot_name | sender_host | sender_port | conninfo
-----+--------+-------------------+-------------------+-------------+-------------+--------------+--------------------+-----------------------+----------------+-----------------+-----------+-------------+-------------+----------
(0 rows)
```

I also tried restarting the standby server, and the result was the same.

The problem is that pg_stat_wal_receiver is gated by WalRcv->ready_to_display, and when the status is CONNECTING, WalRcv->ready_to_display is false.

Given that the original commit message explicitly mentions “monitoring purposes”, I think hiding this status during the connecting phase is a bug. I tried to fix it by showing only the PID and CONNECTING status when WalRcv->ready_to_display is false, like this:
```
evantest=# SELECT * FROM pg_stat_wal_receiver;
 pid  |   status   | receive_start_lsn | receive_start_tli | written_lsn | flushed_lsn | received_tli | last_msg_send_time | last_msg_receipt_time | latest_end_lsn | latest_end_time | slot_name | sender_host | sender_port | conninfo
------+------------+-------------------+-------------------+-------------+-------------+--------------+--------------------+-----------------------+----------------+-----------------+-----------+-------------+-------------+----------
 3256 | connecting |                   |                   |             |             |              |                    |                       |                |                 |           |             |             |
(1 row)
```

See the attached patch for details.
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/



Attachments:

  [application/octet-stream] v1-0001-Fix-pg_stat_wal_receiver-to-show-CONNECTING-statu.patch (2.8K, 2-v1-0001-Fix-pg_stat_wal_receiver-to-show-CONNECTING-statu.patch)
  download | inline diff:
From 817d3c881dd6d3912635c89d7aa24407576a85d8 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <lic@highgo.com>
Date: Tue, 19 May 2026 13:32:15 +0800
Subject: [PATCH v1] Fix pg_stat_wal_receiver to show CONNECTING status

Commit a36164e7465 added a CONNECTING status for the WAL receiver, but
pg_stat_wal_receiver still returned no row while ready_to_display was
false.  That made the new status invisible during the connection setup
phase.

Allow pg_stat_wal_receiver to show the WAL receiver PID and status once
they have been advertised, even before connection details are ready to
display.  Keep the remaining fields NULL until conninfo has been
obfuscated.

Author: Chao Li <lic@highgo.com>
---
 src/backend/replication/walreceiver.c | 36 +++++++++++++++++----------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 07eac07b9ce..78d948adc49 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -1474,21 +1474,10 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS)
 	strlcpy(conninfo, WalRcv->conninfo, sizeof(conninfo));
 	SpinLockRelease(&WalRcv->mutex);
 
-	/*
-	 * No WAL receiver (or not ready yet), just return a tuple with NULL
-	 * values
-	 */
-	if (pid == 0 || !ready_to_display)
+	/* No WAL receiver, just return a tuple with NULL values */
+	if (pid == 0)
 		PG_RETURN_NULL();
 
-	/*
-	 * Read "writtenUpto" without holding a spinlock.  Note that it may not be
-	 * consistent with the other shared variables of the WAL receiver
-	 * protected by a spinlock, but this should not be used for data integrity
-	 * checks.
-	 */
-	written_lsn = pg_atomic_read_u64(&WalRcv->writtenUpto);
-
 	/* determine result type */
 	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 		elog(ERROR, "return type must be a row type");
@@ -1512,6 +1501,27 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS)
 	{
 		values[1] = CStringGetTextDatum(WalRcvGetStateString(state));
 
+		/*
+		 * The WAL receiver advertises its PID and state before connection
+		 * details are safe to display.  Show the state, but keep all other
+		 * details hidden until conninfo has been obfuscated.
+		 */
+		if (!ready_to_display)
+		{
+			memset(&nulls[2], true, sizeof(bool) * (tupdesc->natts - 2));
+
+			PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values,
+															  nulls)));
+		}
+
+		/*
+		 * Read "writtenUpto" without holding a spinlock.  Note that it may
+		 * not be consistent with the other shared variables of the WAL
+		 * receiver protected by a spinlock, but this should not be used for
+		 * data integrity checks.
+		 */
+		written_lsn = pg_atomic_read_u64(&WalRcv->writtenUpto);
+
 		if (!XLogRecPtrIsValid(receive_start_lsn))
 			nulls[2] = true;
 		else
-- 
2.50.1 (Apple Git-155)



reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: li.evan.chao@gmail.com, michael.paquier@gmail.com, xunengzhou@gmail.com
  Subject: Re: Fix pg_stat_wal_receiver to show CONNECTING status
  In-Reply-To: <EF91FF76-1E2B-4F3B-9162-290B4DC517FF@gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox