<entry><type>text</type></entry>
<entry>Replication slot name used by this WAL receiver</entry>
</row>
+ <row>
+ <entry><structfield>sender_host</structfield></entry>
+ <entry><type>text</type></entry>
+ <entry>
+ Host of the <productname>PostgreSQL</productname> instance
+ this WAL receiver is connected to. This can be a host name,
+ an IP address, or a directory path if the connection is via
+ Unix socket. (The path case can be distinguished because it
+ will always be an absolute path, beginning with <literal>/</literal>.)
+ </entry>
+ </row>
+ <row>
+ <entry><structfield>sender_port</structfield></entry>
+ <entry><type>integer</type></entry>
+ <entry>
+ Port number of the <productname>PostgreSQL</productname> instance
+ this WAL receiver is connected to.
+ </entry>
+ </row>
<row>
<entry><structfield>conninfo</structfield></entry>
<entry><type>text</type></entry>
s.latest_end_lsn,
s.latest_end_time,
s.slot_name,
+ s.sender_host,
+ s.sender_port,
s.conninfo
FROM pg_stat_get_wal_receiver() s
WHERE s.pid IS NOT NULL;
char **err);
static void libpqrcv_check_conninfo(const char *conninfo);
static char *libpqrcv_get_conninfo(WalReceiverConn *conn);
+static void libpqrcv_get_senderinfo(WalReceiverConn *conn,
+ char **sender_host, int *sender_port);
static char *libpqrcv_identify_system(WalReceiverConn *conn,
TimeLineID *primary_tli,
int *server_version);
libpqrcv_connect,
libpqrcv_check_conninfo,
libpqrcv_get_conninfo,
+ libpqrcv_get_senderinfo,
libpqrcv_identify_system,
libpqrcv_readtimelinehistoryfile,
libpqrcv_startstreaming,
return retval;
}
+/*
+ * Provides information of sender this WAL receiver is connected to.
+ */
+static void
+libpqrcv_get_senderinfo(WalReceiverConn *conn, char **sender_host,
+ int *sender_port)
+{
+ char *ret = NULL;
+
+ *sender_host = NULL;
+ *sender_port = 0;
+
+ Assert(conn->streamConn != NULL);
+
+ ret = PQhost(conn->streamConn);
+ if (ret && strlen(ret) != 0)
+ *sender_host = pstrdup(ret);
+
+ ret = PQport(conn->streamConn);
+ if (ret && strlen(ret) != 0)
+ *sender_port = atoi(ret);
+}
+
/*
* Check that primary's system identifier matches ours, and fetch the current
* timeline ID of the primary.
#include "access/xlog_internal.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_type.h"
+#include "common/ip.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "libpq/pqsignal.h"
TimestampTz now;
bool ping_sent;
char *err;
+ char *sender_host = NULL;
+ int sender_port = 0;
/*
* WalRcv should be set up already (if we are a backend, we inherit this
/*
* Save user-visible connection string. This clobbers the original
- * conninfo, for security.
+ * conninfo, for security. Also save host and port of the sender server
+ * this walreceiver is connected to.
*/
tmp_conninfo = walrcv_get_conninfo(wrconn);
+ walrcv_get_senderinfo(wrconn, &sender_host, &sender_port);
SpinLockAcquire(&walrcv->mutex);
memset(walrcv->conninfo, 0, MAXCONNINFO);
if (tmp_conninfo)
strlcpy((char *) walrcv->conninfo, tmp_conninfo, MAXCONNINFO);
+
+ memset(walrcv->sender_host, 0, NI_MAXHOST);
+ if (sender_host)
+ strlcpy((char *) walrcv->sender_host, sender_host, NI_MAXHOST);
+
+ walrcv->sender_port = sender_port;
walrcv->ready_to_display = true;
SpinLockRelease(&walrcv->mutex);
if (tmp_conninfo)
pfree(tmp_conninfo);
+ if (sender_host)
+ pfree(sender_host);
+
first_stream = true;
for (;;)
{
TimestampTz last_receipt_time;
XLogRecPtr latest_end_lsn;
TimestampTz latest_end_time;
+ char sender_host[NI_MAXHOST];
+ int sender_port = 0;
char slotname[NAMEDATALEN];
char conninfo[MAXCONNINFO];
latest_end_lsn = WalRcv->latestWalEnd;
latest_end_time = WalRcv->latestWalEndTime;
strlcpy(slotname, (char *) WalRcv->slotname, sizeof(slotname));
+ strlcpy(sender_host, (char *) WalRcv->sender_host, sizeof(sender_host));
+ sender_port = WalRcv->sender_port;
strlcpy(conninfo, (char *) WalRcv->conninfo, sizeof(conninfo));
SpinLockRelease(&WalRcv->mutex);
nulls[10] = true;
else
values[10] = CStringGetTextDatum(slotname);
- if (*conninfo == '\0')
+ if (*sender_host == '\0')
nulls[11] = true;
else
- values[11] = CStringGetTextDatum(conninfo);
+ values[11] = CStringGetTextDatum(sender_host);
+ if (sender_port == 0)
+ nulls[12] = true;
+ else
+ values[12] = Int32GetDatum(sender_port);
+ if (*conninfo == '\0')
+ nulls[13] = true;
+ else
+ values[13] = CStringGetTextDatum(conninfo);
}
/* Returns the record as Datum */
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201803291
+#define CATALOG_VERSION_NO 201803311
#endif
DESCR("statistics: information about progress of backends running maintenance command");
DATA(insert OID = 3099 ( pg_stat_get_wal_senders PGNSP PGUID 12 1 10 0 0 f f f f t s r 0 0 2249 "" "{23,25,3220,3220,3220,3220,1186,1186,1186,23,25}" "{o,o,o,o,o,o,o,o,o,o,o}" "{pid,state,sent_lsn,write_lsn,flush_lsn,replay_lsn,write_lag,flush_lag,replay_lag,sync_priority,sync_state}" _null_ _null_ pg_stat_get_wal_senders _null_ _null_ _null_ ));
DESCR("statistics: information about currently active replication");
-DATA(insert OID = 3317 ( pg_stat_get_wal_receiver PGNSP PGUID 12 1 0 0 0 f f f f f s r 0 0 2249 "" "{23,25,3220,23,3220,23,1184,1184,3220,1184,25,25}" "{o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,status,receive_start_lsn,receive_start_tli,received_lsn,received_tli,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time,slot_name,conninfo}" _null_ _null_ pg_stat_get_wal_receiver _null_ _null_ _null_ ));
+DATA(insert OID = 3317 ( pg_stat_get_wal_receiver PGNSP PGUID 12 1 0 0 0 f f f f f s r 0 0 2249 "" "{23,25,3220,23,3220,23,1184,1184,3220,1184,25,25,23,25}" "{o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,status,receive_start_lsn,receive_start_tli,received_lsn,received_tli,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time,slot_name,sender_host,sender_port,conninfo}" _null_ _null_ pg_stat_get_wal_receiver _null_ _null_ _null_ ));
DESCR("statistics: information about WAL receiver");
DATA(insert OID = 6118 ( pg_stat_get_subscription PGNSP PGUID 12 1 0 0 0 f f f f f s r 1 0 2249 "26" "{26,26,26,23,3220,1184,1184,3220,1184}" "{i,o,o,o,o,o,o,o,o}" "{subid,subid,relid,pid,received_lsn,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time}" _null_ _null_ pg_stat_get_subscription _null_ _null_ _null_ ));
DESCR("statistics: information about subscription");
*/
char conninfo[MAXCONNINFO];
+ /*
+ * Host name (this can be a host name, an IP address, or a directory
+ * path) and port number of the active replication connection.
+ */
+ char sender_host[NI_MAXHOST];
+ int sender_port;
+
/*
* replication slot name; is also used for walreceiver to connect with the
* primary
char **err);
typedef void (*walrcv_check_conninfo_fn) (const char *conninfo);
typedef char *(*walrcv_get_conninfo_fn) (WalReceiverConn *conn);
+typedef void (*walrcv_get_senderinfo_fn) (WalReceiverConn *conn,
+ char **sender_host,
+ int *sender_port);
typedef char *(*walrcv_identify_system_fn) (WalReceiverConn *conn,
TimeLineID *primary_tli,
int *server_version);
walrcv_connect_fn walrcv_connect;
walrcv_check_conninfo_fn walrcv_check_conninfo;
walrcv_get_conninfo_fn walrcv_get_conninfo;
+ walrcv_get_senderinfo_fn walrcv_get_senderinfo;
walrcv_identify_system_fn walrcv_identify_system;
walrcv_readtimelinehistoryfile_fn walrcv_readtimelinehistoryfile;
walrcv_startstreaming_fn walrcv_startstreaming;
WalReceiverFunctions->walrcv_check_conninfo(conninfo)
#define walrcv_get_conninfo(conn) \
WalReceiverFunctions->walrcv_get_conninfo(conn)
+#define walrcv_get_senderinfo(conn, sender_host, sender_port) \
+ WalReceiverFunctions->walrcv_get_senderinfo(conn, sender_host, sender_port)
#define walrcv_identify_system(conn, primary_tli, server_version) \
WalReceiverFunctions->walrcv_identify_system(conn, primary_tli, server_version)
#define walrcv_readtimelinehistoryfile(conn, tli, filename, content, size) \
s.latest_end_lsn,
s.latest_end_time,
s.slot_name,
+ s.sender_host,
+ s.sender_port,
s.conninfo
- FROM pg_stat_get_wal_receiver() s(pid, status, receive_start_lsn, receive_start_tli, received_lsn, received_tli, last_msg_send_time, last_msg_receipt_time, latest_end_lsn, latest_end_time, slot_name, conninfo)
+ FROM pg_stat_get_wal_receiver() s(pid, status, receive_start_lsn, receive_start_tli, received_lsn, received_tli, last_msg_send_time, last_msg_receipt_time, latest_end_lsn, latest_end_time, slot_name, sender_host, sender_port, conninfo)
WHERE (s.pid IS NOT NULL);
pg_stat_xact_all_tables| SELECT c.oid AS relid,
n.nspname AS schemaname,