On Tue, May 18, 2021 at 11:20:49AM +0900, Michael Paquier wrote:
> So that would mean the addition of one new catalog view, called
> pg_stat_connection, with the following fields:
> - PID
> - all three client_*
> - authn ID
> I can live with this split.  Thoughts from others?

Just to make the discussion move on, attached is an updated version
doing that.
--
Michael
From 749422386ed7fd24219c3bce6a5ecfb693602d89 Mon Sep 17 00:00:00 2001
From: Michael Paquier <mich...@paquier.xyz>
Date: Fri, 21 May 2021 13:27:05 +0900
Subject: [PATCH v2] Add authenticated data to pg_stat_activity

---
 src/include/catalog/pg_proc.dat               |   6 +-
 src/include/utils/backend_status.h            |  16 ++-
 src/backend/catalog/system_views.sql          |  12 +-
 src/backend/utils/activity/backend_status.c   |  60 +++++----
 src/backend/utils/adt/pgstatfuncs.c           |  21 +++-
 src/backend/utils/misc/guc.c                  |  11 ++
 src/backend/utils/misc/postgresql.conf.sample |   1 +
 src/test/ldap/t/001_auth.pl                   |   4 +-
 src/test/regress/expected/rules.out           |  17 +--
 src/test/ssl/t/001_ssltests.pl                |   7 +-
 doc/src/sgml/config.sgml                      |  18 +++
 doc/src/sgml/monitoring.sgml                  | 119 +++++++++++++-----
 12 files changed, 212 insertions(+), 80 deletions(-)

diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index acbcae4607..6c35496554 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5280,9 +5280,9 @@
   proname => 'pg_stat_get_activity', prorows => '100', proisstrict => 'f',
   proretset => 't', provolatile => 's', proparallel => 'r',
   prorettype => 'record', proargtypes => 'int4',
-  proallargtypes => '{int4,oid,int4,oid,text,text,text,text,text,timestamptz,timestamptz,timestamptz,timestamptz,inet,text,int4,xid,xid,text,bool,text,text,int4,text,numeric,text,bool,text,bool,int4,int8}',
-  proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
-  proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,ssl_client_dn,ssl_client_serial,ssl_issuer_dn,gss_auth,gss_princ,gss_enc,leader_pid,query_id}',
+  proallargtypes => '{int4,oid,int4,oid,text,text,text,text,text,timestamptz,timestamptz,timestamptz,timestamptz,inet,text,int4,xid,xid,text,bool,text,text,int4,text,numeric,text,bool,text,bool,int4,int8,text}',
+  proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
+  proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,ssl_client_dn,ssl_client_serial,ssl_issuer_dn,gss_auth,gss_princ,gss_enc,leader_pid,query_id,authenticated_id}',
   prosrc => 'pg_stat_get_activity' },
 { oid => '3318',
   descr => 'statistics: information about progress of backends running maintenance command',
diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h
index 8042b817df..5762d201b0 100644
--- a/src/include/utils/backend_status.h
+++ b/src/include/utils/backend_status.h
@@ -145,13 +145,16 @@ typedef struct PgBackendStatus
 	char	   *st_appname;
 
 	/*
-	 * Current command string; MUST be null-terminated. Note that this string
-	 * possibly is truncated in the middle of a multi-byte character. As
-	 * activity strings are stored more frequently than read, that allows to
-	 * move the cost of correct truncation to the display side. Use
-	 * pgstat_clip_activity() to truncate correctly.
+	 * Current command string and authenticated ID string; MUST be
+	 * null-terminated.  Note that those strings possibly are truncated in
+	 * the middle of a multi-byte character.  As activity strings are
+	 * stored more frequently than read, that allows to move the cost of
+	 * correct truncation to the display side.  Authenticated ID strings
+	 * are stored once at backend startup but the cost is minimal.
+	 * Use pgstat_clip_string() to truncate both of them correctly.
 	 */
 	char	   *st_activity_raw;
+	char	   *st_authn_id;
 
 	/*
 	 * Command progress reporting.  Any command which wishes can advertise
@@ -267,6 +270,7 @@ typedef struct LocalPgBackendStatus
  */
 extern PGDLLIMPORT bool pgstat_track_activities;
 extern PGDLLIMPORT int pgstat_track_activity_query_size;
+extern PGDLLIMPORT int pgstat_track_connection_authn_size;
 
 
 /* ----------
@@ -315,7 +319,7 @@ extern uint64 pgstat_get_my_query_id(void);
 extern int	pgstat_fetch_stat_numbackends(void);
 extern PgBackendStatus *pgstat_fetch_stat_beentry(int beid);
 extern LocalPgBackendStatus *pgstat_fetch_stat_local_beentry(int beid);
-extern char *pgstat_clip_activity(const char *raw_activity);
+extern char *pgstat_clip_string(const char *raw_activity, int max_size);
 
 
 #endif							/* BACKEND_STATUS_H */
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 5c84d758bb..648cf6e138 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -821,9 +821,6 @@ CREATE VIEW pg_stat_activity AS
             S.usesysid,
             U.rolname AS usename,
             S.application_name,
-            S.client_addr,
-            S.client_hostname,
-            S.client_port,
             S.backend_start,
             S.xact_start,
             S.query_start,
@@ -840,6 +837,15 @@ CREATE VIEW pg_stat_activity AS
         LEFT JOIN pg_database AS D ON (S.datid = D.oid)
         LEFT JOIN pg_authid AS U ON (S.usesysid = U.oid);
 
+CREATE VIEW pg_stat_connection AS
+    SELECT
+            S.pid,
+            S.authenticated_id,
+            S.client_addr,
+            S.client_hostname,
+            S.client_port
+    FROM pg_stat_get_activity(NULL) AS S;
+
 CREATE VIEW pg_stat_replication AS
     SELECT
             S.pid,
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index 2901f9f5a9..09252ae0e2 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -44,6 +44,7 @@
  */
 bool		pgstat_track_activities = false;
 int			pgstat_track_activity_query_size = 1024;
+int			pgstat_track_connection_authn_size = 128;
 
 
 /* exposed so that progress.c can access it */
@@ -95,7 +96,9 @@ BackendStatusShmemSize(void)
 					mul_size(NAMEDATALEN, NumBackendStatSlots));
 	/* BackendActivityBuffer: */
 	size = add_size(size,
-					mul_size(pgstat_track_activity_query_size, NumBackendStatSlots));
+					mul_size(pgstat_track_activity_query_size +
+							 pgstat_track_connection_authn_size,
+							 NumBackendStatSlots));
 #ifdef USE_SSL
 	/* BackendSslStatusBuffer: */
 	size = add_size(size,
@@ -171,7 +174,8 @@ CreateSharedBackendStatus(void)
 	}
 
 	/* Create or attach to the shared activity buffer */
-	BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size,
+	BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size +
+										 pgstat_track_connection_authn_size,
 										 NumBackendStatSlots);
 	BackendActivityBuffer = (char *)
 		ShmemInitStruct("Backend Activity Buffer",
@@ -182,12 +186,14 @@ CreateSharedBackendStatus(void)
 	{
 		MemSet(BackendActivityBuffer, 0, BackendActivityBufferSize);
 
-		/* Initialize st_activity pointers. */
+		/* Initialize st_activity and st_authn_id pointers. */
 		buffer = BackendActivityBuffer;
 		for (i = 0; i < NumBackendStatSlots; i++)
 		{
 			BackendStatusArray[i].st_activity_raw = buffer;
 			buffer += pgstat_track_activity_query_size;
+			BackendStatusArray[i].st_authn_id = buffer;
+			buffer += pgstat_track_connection_authn_size;
 		}
 	}
 
@@ -432,10 +438,22 @@ pgstat_bestart(void)
 	else
 		lbeentry.st_clienthostname[0] = '\0';
 	lbeentry.st_activity_raw[0] = '\0';
+	if (MyProcPort && MyProcPort->authn_id)
+	{
+		/* Compute the length of the field to store */
+		int		len = Min(strlen(MyProcPort->authn_id),
+						  pgstat_track_connection_authn_size - 1);
+
+		memcpy(lbeentry.st_authn_id, MyProcPort->authn_id, len);
+		lbeentry.st_authn_id[len] = '\0';
+	}
+	else
+		lbeentry.st_authn_id[0] = '\0';
 	/* Also make sure the last byte in each string area is always 0 */
 	lbeentry.st_appname[NAMEDATALEN - 1] = '\0';
 	lbeentry.st_clienthostname[NAMEDATALEN - 1] = '\0';
 	lbeentry.st_activity_raw[pgstat_track_activity_query_size - 1] = '\0';
+	lbeentry.st_authn_id[pgstat_track_connection_authn_size - 1] = '\0';
 
 #ifdef USE_SSL
 	memcpy(lbeentry.st_sslstatus, &lsslstatus, sizeof(PgBackendSSLStatus));
@@ -936,7 +954,8 @@ pgstat_get_backend_current_activity(int pid, bool checkUser)
 			else
 			{
 				/* this'll leak a bit of memory, but that seems acceptable */
-				return pgstat_clip_activity(beentry->st_activity_raw);
+				return pgstat_clip_string(beentry->st_activity_raw,
+										  pgstat_track_activity_query_size);
 			}
 		}
 
@@ -1103,7 +1122,7 @@ pgstat_fetch_stat_numbackends(void)
 }
 
 /*
- * Convert a potentially unsafely truncated activity string (see
+ * Convert a potentially unsafely truncated activity or authn ID string (see
  * PgBackendStatus.st_activity_raw's documentation) into a correctly truncated
  * one.
  *
@@ -1111,37 +1130,36 @@ pgstat_fetch_stat_numbackends(void)
  * freed.
  */
 char *
-pgstat_clip_activity(const char *raw_activity)
+pgstat_clip_string(const char *raw_string, int max_size)
 {
-	char	   *activity;
+	char	   *string;
 	int			rawlen;
 	int			cliplen;
 
 	/*
 	 * Some callers, like pgstat_get_backend_current_activity(), do not
-	 * guarantee that the buffer isn't concurrently modified. We try to take
+	 * guarantee that the buffer isn't concurrently modified.  We try to take
 	 * care that the buffer is always terminated by a NUL byte regardless, but
-	 * let's still be paranoid about the string's length. In those cases the
-	 * underlying buffer is guaranteed to be pgstat_track_activity_query_size
-	 * large.
+	 * let's still be paranoid about the string's length.  In those cases the
+	 * underlying buffer is guaranteed to be max_size large.
 	 */
-	activity = pnstrdup(raw_activity, pgstat_track_activity_query_size - 1);
+	string = pnstrdup(raw_string, max_size - 1);
 
 	/* now double-guaranteed to be NUL terminated */
-	rawlen = strlen(activity);
+	rawlen = strlen(string);
 
 	/*
 	 * All supported server-encodings make it possible to determine the length
 	 * of a multi-byte character from its first byte (this is not the case for
-	 * client encodings, see GB18030). As st_activity is always stored using
-	 * server encoding, this allows us to perform multi-byte aware truncation,
-	 * even if the string earlier was truncated in the middle of a multi-byte
-	 * character.
+	 * client encodings, see GB18030).  As st_activity and st_authn_id are
+	 * always stored using server encoding, this allows us to perform
+	 * multi-byte aware truncation, even if the string earlier was truncated
+	 * in the middle of a multi-byte character.
 	 */
-	cliplen = pg_mbcliplen(activity, rawlen,
-						   pgstat_track_activity_query_size - 1);
+	cliplen = pg_mbcliplen(string, rawlen,
+						   max_size - 1);
 
-	activity[cliplen] = '\0';
+	string[cliplen] = '\0';
 
-	return activity;
+	return string;
 }
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 14056f5347..16a92ff089 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -570,7 +570,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
 Datum
 pg_stat_get_activity(PG_FUNCTION_ARGS)
 {
-#define PG_STAT_GET_ACTIVITY_COLS	30
+#define PG_STAT_GET_ACTIVITY_COLS	31
 	int			num_backends = pgstat_fetch_stat_numbackends();
 	int			curr_backend;
 	int			pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
@@ -704,10 +704,23 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 					break;
 			}
 
-			clipped_activity = pgstat_clip_activity(beentry->st_activity_raw);
+			clipped_activity = pgstat_clip_string(beentry->st_activity_raw,
+												  pgstat_track_activity_query_size);
 			values[5] = CStringGetTextDatum(clipped_activity);
 			pfree(clipped_activity);
 
+			if (beentry->st_authn_id)
+			{
+				char	   *clipped_authn_id;
+
+				clipped_authn_id = pgstat_clip_string(beentry->st_authn_id,
+													  pgstat_track_connection_authn_size);
+				values[30] = CStringGetTextDatum(clipped_authn_id);
+				pfree(clipped_authn_id);
+			}
+			else
+				nulls[30] = true;
+
 			/* leader_pid */
 			nulls[28] = true;
 
@@ -947,6 +960,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 			nulls[27] = true;
 			nulls[28] = true;
 			nulls[29] = true;
+			nulls[30] = true;
 		}
 
 		tuplestore_putvalues(tupstore, tupdesc, values, nulls);
@@ -1027,7 +1041,8 @@ pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
 	else
 		activity = beentry->st_activity_raw;
 
-	clipped_activity = pgstat_clip_activity(activity);
+	clipped_activity = pgstat_clip_string(activity,
+										  pgstat_track_activity_query_size);
 	ret = cstring_to_text(activity);
 	pfree(clipped_activity);
 
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index ee731044b6..024d6539a6 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -3472,6 +3472,17 @@ static struct config_int ConfigureNamesInt[] =
 		NULL, NULL, NULL
 	},
 
+	{
+		{"track_connection_authn_size", PGC_POSTMASTER, RESOURCES_MEM,
+			gettext_noop("Sets the size reserved for pg_stat_connection.authenticated_id, in bytes."),
+			NULL,
+			GUC_UNIT_BYTE
+		},
+		&pgstat_track_connection_authn_size,
+		128, 100, 1048576,
+		NULL, NULL, NULL
+	},
+
 	{
 		{"gin_pending_list_limit", PGC_USERSET, CLIENT_CONN_STATEMENT,
 			gettext_noop("Sets the maximum size of the pending list for GIN index."),
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 6e36e4c2ef..d79d7e773c 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -595,6 +595,7 @@
 
 #track_activities = on
 #track_activity_query_size = 1024	# (change requires restart)
+#track_connection_authn_size = 128	# (change requires restart)
 #track_counts = on
 #track_io_timing = off
 #track_wal_io_timing = off
diff --git a/src/test/ldap/t/001_auth.pl b/src/test/ldap/t/001_auth.pl
index 0ae14e4c85..87930b25b5 100644
--- a/src/test/ldap/t/001_auth.pl
+++ b/src/test/ldap/t/001_auth.pl
@@ -9,7 +9,7 @@ use Test::More;
 
 if ($ENV{with_ldap} eq 'yes')
 {
-	plan tests => 28;
+	plan tests => 29;
 }
 else
 {
@@ -202,6 +202,8 @@ $ENV{"PGPASSWORD"} = 'secret1';
 test_access(
 	$node, 'test1', 0,
 	'simple bind authentication succeeds',
+	sql => 'SELECT authenticated_id FROM pg_stat_connection WHERE pid = pg_backend_pid()',
+	expected_stdout => qr/uid=test1,dc=example,dc=net/,
 	log_like => [
 		qr/connection authenticated: identity="uid=test1,dc=example,dc=net" method=ldap/
 	],);
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e5ab11275d..9eff8604a2 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1750,9 +1750,6 @@ pg_stat_activity| SELECT s.datid,
     s.usesysid,
     u.rolname AS usename,
     s.application_name,
-    s.client_addr,
-    s.client_hostname,
-    s.client_port,
     s.backend_start,
     s.xact_start,
     s.query_start,
@@ -1765,7 +1762,7 @@ pg_stat_activity| SELECT s.datid,
     s.query_id,
     s.query,
     s.backend_type
-   FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, leader_pid, query_id)
+   FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, leader_pid, query_id, authenticated_id)
      LEFT JOIN pg_database d ON ((s.datid = d.oid)))
      LEFT JOIN pg_authid u ON ((s.usesysid = u.oid)));
 pg_stat_all_indexes| SELECT c.oid AS relid,
@@ -1828,6 +1825,12 @@ pg_stat_bgwriter| SELECT pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints
     pg_stat_get_buf_fsync_backend() AS buffers_backend_fsync,
     pg_stat_get_buf_alloc() AS buffers_alloc,
     pg_stat_get_bgwriter_stat_reset_time() AS stats_reset;
+pg_stat_connection| SELECT s.pid,
+    s.authenticated_id,
+    s.client_addr,
+    s.client_hostname,
+    s.client_port
+   FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, leader_pid, query_id, authenticated_id);
 pg_stat_database| SELECT d.oid AS datid,
     d.datname,
         CASE
@@ -1877,7 +1880,7 @@ pg_stat_gssapi| SELECT s.pid,
     s.gss_auth AS gss_authenticated,
     s.gss_princ AS principal,
     s.gss_enc AS encrypted
-   FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, leader_pid, query_id)
+   FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, leader_pid, query_id, authenticated_id)
   WHERE (s.client_port IS NOT NULL);
 pg_stat_progress_analyze| SELECT s.pid,
     s.datid,
@@ -2047,7 +2050,7 @@ pg_stat_replication| SELECT s.pid,
     w.sync_priority,
     w.sync_state,
     w.reply_time
-   FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, leader_pid, query_id)
+   FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, leader_pid, query_id, authenticated_id)
      JOIN pg_stat_get_wal_senders() w(pid, state, sent_lsn, write_lsn, flush_lsn, replay_lsn, write_lag, flush_lag, replay_lag, sync_priority, sync_state, reply_time) ON ((s.pid = w.pid)))
      LEFT JOIN pg_authid u ON ((s.usesysid = u.oid)));
 pg_stat_replication_slots| SELECT s.slot_name,
@@ -2081,7 +2084,7 @@ pg_stat_ssl| SELECT s.pid,
     s.ssl_client_dn AS client_dn,
     s.ssl_client_serial AS client_serial,
     s.ssl_issuer_dn AS issuer_dn
-   FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, leader_pid, query_id)
+   FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, leader_pid, query_id, authenticated_id)
   WHERE (s.client_port IS NOT NULL);
 pg_stat_subscription| SELECT su.oid AS subid,
     su.subname,
diff --git a/src/test/ssl/t/001_ssltests.pl b/src/test/ssl/t/001_ssltests.pl
index 44daefb002..03cd45ff71 100644
--- a/src/test/ssl/t/001_ssltests.pl
+++ b/src/test/ssl/t/001_ssltests.pl
@@ -20,7 +20,7 @@ if ($ENV{with_ssl} ne 'openssl')
 }
 else
 {
-	plan tests => 110;
+	plan tests => 111;
 }
 
 #### Some configuration
@@ -449,10 +449,13 @@ $node->connect_ok(
 # same thing but using explicit CN
 $dn_connstr = "$common_connstr dbname=certdb_cn";
 
+# The full DN should still be used as the authenticated identity, within the
+# backend logs and pg_stat_connection.
 $node->connect_ok(
 	"$dn_connstr user=ssltestuser sslcert=ssl/client-dn.crt sslkey=ssl/client-dn_tmp.key",
 	"certificate authorization succeeds with CN mapping",
-	# the full DN should still be used as the authenticated identity
+	sql => 'SELECT authenticated_id FROM pg_stat_connection WHERE pid = pg_backend_pid()',
+	expected_stdout => qr/CN=ssltestuser-dn,OU=Testing,OU=Engineering,O=PGDG/,
 	log_like => [
 		qr/connection authenticated: identity="CN=ssltestuser-dn,OU=Testing,OU=Engineering,O=PGDG" method=cert/
 	],);
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 7e32b0686c..2d0c9bae65 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -7513,6 +7513,24 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-track-connection-authn-size" xreflabel="track_connection_authn_size">
+      <term><varname>track_connection_authn_size</varname> (<type>integer</type>)
+      <indexterm>
+       <primary><varname>track_connection_authn_size</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+       Specifies the amount of memory reserved to store the text of the
+       authenticated identity for each active session, for the
+       <structname>pg_stat_activity</structname>.<structfield>authenticated_id</structfield> field.
+       If this value is specified without units, it is taken as bytes.
+       The default value is 128 bytes.
+       This parameter can only be set at server start.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-track-counts" xreflabel="track_counts">
       <term><varname>track_counts</varname> (<type>boolean</type>)
       <indexterm>
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index dcbb10fb6f..1d21d92d3c 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -749,40 +749,6 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
       </para></entry>
      </row>
 
-     <row>
-      <entry role="catalog_table_entry"><para role="column_definition">
-       <structfield>client_addr</structfield> <type>inet</type>
-      </para>
-      <para>
-       IP address of the client connected to this backend.
-       If this field is null, it indicates either that the client is
-       connected via a Unix socket on the server machine or that this is an
-       internal process such as autovacuum.
-      </para></entry>
-     </row>
-
-     <row>
-      <entry role="catalog_table_entry"><para role="column_definition">
-       <structfield>client_hostname</structfield> <type>text</type>
-      </para>
-      <para>
-       Host name of the connected client, as reported by a
-       reverse DNS lookup of <structfield>client_addr</structfield>. This field will
-       only be non-null for IP connections, and only when <xref linkend="guc-log-hostname"/> is enabled.
-      </para></entry>
-     </row>
-
-     <row>
-      <entry role="catalog_table_entry"><para role="column_definition">
-       <structfield>client_port</structfield> <type>integer</type>
-      </para>
-      <para>
-       TCP port number that the client is using for communication
-       with this backend, or <literal>-1</literal> if a Unix socket is used.
-       If this field is null, it indicates that this is an internal server process.
-      </para></entry>
-     </row>
-
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>backend_start</structfield> <type>timestamp with time zone</type>
@@ -2261,6 +2227,91 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
 
  </sect2>
 
+ <sect2 id="monitoring-pg-stat-connection-view">
+  <title><structname>pg_stat_connection</structname></title>
+
+  <indexterm>
+   <primary>pg_stat_connection</primary>
+  </indexterm>
+
+  <para>
+   The <structname>pg_stat_connection</structname> view will have one row
+   per server process, showing information related to
+   the current connection of that process.
+  </para>
+
+  <table id="pg-stat-connection-view" xreflabel="pg_stat_connection">
+   <title><structname>pg_stat_connection</structname> View</title>
+   <tgroup cols="1">
+    <thead>
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       Column Type
+      </para>
+      <para>
+       Description
+      </para></entry>
+     </row>
+    </thead>
+
+    <tbody>
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>pid</structfield> <type>integer</type>
+      </para>
+      <para>
+       Process ID of this backend
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>authenticated_id</structfield> <type>text</type>
+      </para>
+      <para>
+       Name of the authenticated ID used for this backend login at
+       authentication
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>client_addr</structfield> <type>inet</type>
+      </para>
+      <para>
+       IP address of the client connected to this backend.
+       If this field is null, it indicates either that the client is
+       connected via a Unix socket on the server machine or that this is an
+       internal process such as autovacuum.
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>client_hostname</structfield> <type>text</type>
+      </para>
+      <para>
+       Host name of the connected client, as reported by a
+       reverse DNS lookup of <structfield>client_addr</structfield>. This field will
+       only be non-null for IP connections, and only when <xref linkend="guc-log-hostname"/> is enabled.
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>client_port</structfield> <type>integer</type>
+      </para>
+      <para>
+       TCP port number that the client is using for communication
+       with this backend, or <literal>-1</literal> if a Unix socket is used.
+       If this field is null, it indicates that this is an internal server process.
+      </para></entry>
+     </row>
+    </tbody>
+   </tgroup>
+  </table>
+ </sect2>
+
  <sect2 id="monitoring-pg-stat-replication-view">
   <title><structname>pg_stat_replication</structname></title>
 
-- 
2.31.1

Attachment: signature.asc
Description: PGP signature

Reply via email to