Commit 4744c1a0 authored by Neil Conway's avatar Neil Conway

Complete the following TODO items:

* Add session start time to pg_stat_activity
* Add the client IP address and port to pg_stat_activity

Original patch from Magnus Hagander, code review by Neil Conway. Catalog
version bumped. This patch sends the client IP address and port number in
every statistics message; that's not ideal, but will be fixed up shortly.
parent d8c21181
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/monitoring.sgml,v 1.27 2004/12/28 19:08:58 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/monitoring.sgml,v 1.28 2005/05/09 11:31:32 neilc Exp $
--> -->
<chapter id="monitoring"> <chapter id="monitoring">
...@@ -221,15 +221,16 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re ...@@ -221,15 +221,16 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
<row> <row>
<entry><structname>pg_stat_activity</></entry> <entry><structname>pg_stat_activity</></entry>
<entry>One row per server process, showing process <entry>One row per server process, showing process
<acronym>ID</>, database, user, current query, and the time at <acronym>ID</>, database, user, current query, the time at which
which the current query began execution. The columns that report the current query began execution, the time at which the backend
data on the current query are only available if the parameter was started and the client address and port number. The columns
<varname>stats_command_string</varname> has been turned on. that report data on the current query are only available if the
Furthermore, these columns read as null unless the user examining parameter <varname>stats_command_string</varname> has been
the view is a superuser or the same as the user owning the process turned on. Furthermore, these columns read as null unless the
being reported on. (Note that because of the user examining the view is a superuser or the same as the user
collector's reporting delay, current query will only be up-to-date for owning the process being reported on. (Note that because of the
long-running queries.)</entry> collector's reporting delay, the current query will only be
up-to-date for long-running queries.)</entry>
</row> </row>
<row> <row>
...@@ -509,7 +510,7 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re ...@@ -509,7 +510,7 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
<entry><type>set of integer</type></entry> <entry><type>set of integer</type></entry>
<entry> <entry>
Set of currently active backend process IDs (from 1 to the Set of currently active backend process IDs (from 1 to the
number of active backend processes). See usage example in the text. number of active backend processes). See usage example in the text
</entry> </entry>
</row> </row>
...@@ -568,6 +569,38 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re ...@@ -568,6 +569,38 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
</entry> </entry>
</row> </row>
<row>
<entry><literal><function>pg_stat_get_backend_start</function>(<type>integer</type>)</literal></entry>
<entry><type>timestamp with time zone</type></entry>
<entry>
The time at which the given backend process was started, or
null if the current user is not a superuser nor the same user
as that of the session being queried
</entry>
</row>
<row>
<entry><literal><function>pg_stat_get_backend_client_addr</function>(<type>integer</type>)</literal></entry>
<entry><type>inet</type></entry>
<entry>
The IP address of the client connected to the given
backend. Null if the connection is over a Unix domain
socket. Also null if the current user is not a superuser nor
the same user as that of the session being queried
</entry>
</row>
<row>
<entry><literal><function>pg_stat_get_backend_client_port</function>(<type>integer</type>)</literal></entry>
<entry><type>integer</type></entry>
<entry>
The IP port number of the client connected to the given
backend. -1 if the connection is over a Unix domain
socket. Null if the current user is not a superuser nor the
same user as that of the session being queried
</entry>
</row>
<row> <row>
<entry><literal><function>pg_stat_reset</function>()</literal></entry> <entry><literal><function>pg_stat_reset</function>()</literal></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 1996-2005, PostgreSQL Global Development Group * Copyright (c) 1996-2005, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.11 2005/01/01 20:44:14 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.12 2005/05/09 11:31:32 neilc Exp $
*/ */
CREATE VIEW pg_user AS CREATE VIEW pg_user AS
...@@ -237,7 +237,10 @@ CREATE VIEW pg_stat_activity AS ...@@ -237,7 +237,10 @@ CREATE VIEW pg_stat_activity AS
pg_stat_get_backend_userid(S.backendid) AS usesysid, pg_stat_get_backend_userid(S.backendid) AS usesysid,
U.usename AS usename, U.usename AS usename,
pg_stat_get_backend_activity(S.backendid) AS current_query, pg_stat_get_backend_activity(S.backendid) AS current_query,
pg_stat_get_backend_activity_start(S.backendid) AS query_start pg_stat_get_backend_activity_start(S.backendid) AS query_start,
pg_stat_get_backend_start(S.backendid) AS backend_start,
pg_stat_get_backend_client_addr(S.backendid) AS client_addr,
pg_stat_get_backend_client_port(S.backendid) AS client_port
FROM pg_database D, FROM pg_database D,
(SELECT pg_stat_get_backend_idset() AS backendid) AS S, (SELECT pg_stat_get_backend_idset() AS backendid) AS S,
pg_shadow U pg_shadow U
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* Copyright (c) 2001-2005, PostgreSQL Global Development Group * Copyright (c) 2001-2005, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.92 2005/04/14 20:32:42 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.93 2005/05/09 11:31:33 neilc Exp $
* ---------- * ----------
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -1300,6 +1300,7 @@ pgstat_setheader(PgStat_MsgHdr *hdr, int mtype) ...@@ -1300,6 +1300,7 @@ pgstat_setheader(PgStat_MsgHdr *hdr, int mtype)
hdr->m_procpid = MyProcPid; hdr->m_procpid = MyProcPid;
hdr->m_databaseid = MyDatabaseId; hdr->m_databaseid = MyDatabaseId;
hdr->m_userid = GetSessionUserId(); hdr->m_userid = GetSessionUserId();
memcpy(&hdr->m_clientaddr, &MyProcPort->raddr, sizeof(hdr->m_clientaddr));
} }
...@@ -2032,12 +2033,15 @@ pgstat_add_backend(PgStat_MsgHdr *msg) ...@@ -2032,12 +2033,15 @@ pgstat_add_backend(PgStat_MsgHdr *msg)
beentry->databaseid = msg->m_databaseid; beentry->databaseid = msg->m_databaseid;
beentry->procpid = msg->m_procpid; beentry->procpid = msg->m_procpid;
beentry->userid = msg->m_userid; beentry->userid = msg->m_userid;
beentry->start_sec =
GetCurrentAbsoluteTimeUsec(&beentry->start_usec);
beentry->activity_start_sec = 0; beentry->activity_start_sec = 0;
beentry->activity_start_usec = 0; beentry->activity_start_usec = 0;
memcpy(&beentry->clientaddr, &msg->m_clientaddr, sizeof(beentry->clientaddr));
MemSet(beentry->activity, 0, PGSTAT_ACTIVITY_SIZE); MemSet(beentry->activity, 0, PGSTAT_ACTIVITY_SIZE);
/* /*
* Lookup or create the database entry for this backends DB. * Lookup or create the database entry for this backend's DB.
*/ */
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash, dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
(void *) &(msg->m_databaseid), (void *) &(msg->m_databaseid),
...@@ -2072,9 +2076,7 @@ pgstat_add_backend(PgStat_MsgHdr *msg) ...@@ -2072,9 +2076,7 @@ pgstat_add_backend(PgStat_MsgHdr *msg)
HASH_ELEM | HASH_FUNCTION); HASH_ELEM | HASH_FUNCTION);
} }
/* /* Count the number of connects to the database */
* Count number of connects to the database
*/
dbentry->n_connects++; dbentry->n_connects++;
return 0; return 0;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.20 2004/12/31 22:01:22 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.21 2005/05/09 11:31:33 neilc Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
#include "pgstat.h" #include "pgstat.h"
#include "utils/hsearch.h" #include "utils/hsearch.h"
#include "utils/inet.h"
#include "utils/builtins.h"
#include "libpq/ip.h"
/* bogus ... these externs should be in a header file */ /* bogus ... these externs should be in a header file */
extern Datum pg_stat_get_numscans(PG_FUNCTION_ARGS); extern Datum pg_stat_get_numscans(PG_FUNCTION_ARGS);
...@@ -41,6 +44,9 @@ extern Datum pg_stat_get_backend_dbid(PG_FUNCTION_ARGS); ...@@ -41,6 +44,9 @@ extern Datum pg_stat_get_backend_dbid(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_backend_userid(PG_FUNCTION_ARGS); extern Datum pg_stat_get_backend_userid(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS); extern Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS); extern Datum pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_backend_start(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_backend_client_port(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_db_numbackends(PG_FUNCTION_ARGS); extern Datum pg_stat_get_db_numbackends(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS); extern Datum pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS);
...@@ -357,6 +363,117 @@ pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS) ...@@ -357,6 +363,117 @@ pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
PG_RETURN_TIMESTAMPTZ(result); PG_RETURN_TIMESTAMPTZ(result);
} }
Datum
pg_stat_get_backend_start(PG_FUNCTION_ARGS)
{
PgStat_StatBeEntry *beentry;
int32 beid;
AbsoluteTime sec;
int usec;
TimestampTz result;
beid = PG_GETARG_INT32(0);
if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
PG_RETURN_NULL();
if (!superuser() && beentry->userid != GetUserId())
PG_RETURN_NULL();
sec = beentry->start_sec;
usec = beentry->start_usec;
if (sec == 0 && usec == 0)
PG_RETURN_NULL();
result = AbsoluteTimeUsecToTimestampTz(sec, usec);
PG_RETURN_TIMESTAMPTZ(result);
}
Datum
pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
{
PgStat_StatBeEntry *beentry;
int32 beid;
char remote_host[NI_MAXHOST];
int ret;
beid = PG_GETARG_INT32(0);
if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
PG_RETURN_NULL();
if (!superuser() && beentry->userid != GetUserId())
PG_RETURN_NULL();
switch (beentry->clientaddr.addr.ss_family)
{
case AF_INET:
#ifdef HAVE_IPV6
case AF_INET6:
#endif
break;
default:
PG_RETURN_NULL();
}
remote_host[0] = '\0';
ret = getnameinfo_all(&beentry->clientaddr.addr, beentry->clientaddr.salen,
remote_host, sizeof(remote_host),
NULL, 0,
NI_NUMERICHOST | NI_NUMERICSERV);
if (ret)
PG_RETURN_NULL();
PG_RETURN_INET_P(DirectFunctionCall1(inet_in,
CStringGetDatum(remote_host)));
}
Datum
pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
{
PgStat_StatBeEntry *beentry;
int32 beid;
char remote_port[NI_MAXSERV];
int ret;
beid = PG_GETARG_INT32(0);
if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
PG_RETURN_NULL();
if (!superuser() && beentry->userid != GetUserId())
PG_RETURN_NULL();
switch (beentry->clientaddr.addr.ss_family)
{
case AF_INET:
#ifdef HAVE_IPV6
case AF_INET6:
#endif
break;
case AF_UNIX:
PG_RETURN_INT32(-1);
default:
PG_RETURN_NULL();
}
remote_port[0] = '\0';
ret = getnameinfo_all(&beentry->clientaddr.addr,
beentry->clientaddr.salen,
NULL, 0,
remote_port, sizeof(remote_port),
NI_NUMERICHOST | NI_NUMERICSERV);
if (ret)
PG_RETURN_NULL();
PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(remote_port)));
}
Datum Datum
pg_stat_get_db_numbackends(PG_FUNCTION_ARGS) pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.266 2005/04/30 20:31:37 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.267 2005/05/09 11:31:34 neilc Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200504301 #define CATALOG_VERSION_NO 200505091
#endif #endif
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.360 2005/04/30 20:31:38 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.361 2005/05/09 11:31:34 neilc Exp $
* *
* NOTES * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * The script catalog/genbki.sh reads this file and generates .bki
...@@ -2822,6 +2822,12 @@ DATA(insert OID = 1940 ( pg_stat_get_backend_activity PGNSP PGUID 12 f f t f s ...@@ -2822,6 +2822,12 @@ DATA(insert OID = 1940 ( pg_stat_get_backend_activity PGNSP PGUID 12 f f t f s
DESCR("Statistics: Current query of backend"); DESCR("Statistics: Current query of backend");
DATA(insert OID = 2094 ( pg_stat_get_backend_activity_start PGNSP PGUID 12 f f t f s 1 1184 "23" _null_ _null_ _null_ pg_stat_get_backend_activity_start - _null_)); DATA(insert OID = 2094 ( pg_stat_get_backend_activity_start PGNSP PGUID 12 f f t f s 1 1184 "23" _null_ _null_ _null_ pg_stat_get_backend_activity_start - _null_));
DESCR("Statistics: Start time for current query of backend"); DESCR("Statistics: Start time for current query of backend");
DATA(insert OID = 1391 ( pg_stat_get_backend_start PGNSP PGUID 12 f f t f s 1 1184 "23" _null_ _null_ _null_ pg_stat_get_backend_start - _null_));
DESCR("Statistics: Start time for current backend session");
DATA(insert OID = 1392 ( pg_stat_get_backend_client_addr PGNSP PGUID 12 f f t f s 1 869 "23" _null_ _null_ _null_ pg_stat_get_backend_client_addr - _null_));
DESCR("Statistics: Address of client connected to backend");
DATA(insert OID = 1393 ( pg_stat_get_backend_client_port PGNSP PGUID 12 f f t f s 1 23 "23" _null_ _null_ _null_ pg_stat_get_backend_client_port - _null_));
DESCR("Statistics: Port number of client connected to backend");
DATA(insert OID = 1941 ( pg_stat_get_db_numbackends PGNSP PGUID 12 f f t f s 1 23 "26" _null_ _null_ _null_ pg_stat_get_db_numbackends - _null_ )); DATA(insert OID = 1941 ( pg_stat_get_db_numbackends PGNSP PGUID 12 f f t f s 1 23 "26" _null_ _null_ _null_ pg_stat_get_db_numbackends - _null_ ));
DESCR("Statistics: Number of backends in database"); DESCR("Statistics: Number of backends in database");
DATA(insert OID = 1942 ( pg_stat_get_db_xact_commit PGNSP PGUID 12 f f t f s 1 20 "26" _null_ _null_ _null_ pg_stat_get_db_xact_commit - _null_ )); DATA(insert OID = 1942 ( pg_stat_get_db_xact_commit PGNSP PGUID 12 f f t f s 1 20 "26" _null_ _null_ _null_ pg_stat_get_db_xact_commit - _null_ ));
......
...@@ -5,17 +5,17 @@ ...@@ -5,17 +5,17 @@
* *
* Copyright (c) 2001-2005, PostgreSQL Global Development Group * Copyright (c) 2001-2005, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/include/pgstat.h,v 1.27 2005/01/01 05:43:08 momjian Exp $ * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.28 2005/05/09 11:31:33 neilc Exp $
* ---------- * ----------
*/ */
#ifndef PGSTAT_H #ifndef PGSTAT_H
#define PGSTAT_H #define PGSTAT_H
#include "libpq/pqcomm.h"
#include "utils/hsearch.h" #include "utils/hsearch.h"
#include "utils/nabstime.h" #include "utils/nabstime.h"
#include "utils/rel.h" #include "utils/rel.h"
/* ---------- /* ----------
* The types of backend/postmaster -> collector messages * The types of backend/postmaster -> collector messages
* ---------- * ----------
...@@ -54,6 +54,7 @@ typedef struct PgStat_MsgHdr ...@@ -54,6 +54,7 @@ typedef struct PgStat_MsgHdr
int m_procpid; int m_procpid;
Oid m_databaseid; Oid m_databaseid;
AclId m_userid; AclId m_userid;
SockAddr m_clientaddr;
} PgStat_MsgHdr; } PgStat_MsgHdr;
/* ---------- /* ----------
...@@ -231,8 +232,11 @@ typedef struct PgStat_StatBeEntry ...@@ -231,8 +232,11 @@ typedef struct PgStat_StatBeEntry
Oid databaseid; Oid databaseid;
Oid userid; Oid userid;
int procpid; int procpid;
AbsoluteTime start_sec;
int start_usec;
AbsoluteTime activity_start_sec; AbsoluteTime activity_start_sec;
int activity_start_usec; int activity_start_usec;
SockAddr clientaddr;
char activity[PGSTAT_ACTIVITY_SIZE]; char activity[PGSTAT_ACTIVITY_SIZE];
} PgStat_StatBeEntry; } PgStat_StatBeEntry;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment