diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/system_views.sql | 7 | ||||
-rw-r--r-- | src/backend/postmaster/pgstat.c | 12 | ||||
-rw-r--r-- | src/backend/utils/adt/pgstatfuncs.c | 119 |
3 files changed, 130 insertions, 8 deletions
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 78465075755..1bf0f1657d5 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -3,7 +3,7 @@ * * 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 @@ -237,7 +237,10 @@ CREATE VIEW pg_stat_activity AS pg_stat_get_backend_userid(S.backendid) AS usesysid, U.usename AS usename, 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, (SELECT pg_stat_get_backend_idset() AS backendid) AS S, pg_shadow U diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index e21adab7caa..a2196373191 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -13,7 +13,7 @@ * * 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" @@ -1300,6 +1300,7 @@ pgstat_setheader(PgStat_MsgHdr *hdr, int mtype) hdr->m_procpid = MyProcPid; hdr->m_databaseid = MyDatabaseId; hdr->m_userid = GetSessionUserId(); + memcpy(&hdr->m_clientaddr, &MyProcPort->raddr, sizeof(hdr->m_clientaddr)); } @@ -2032,12 +2033,15 @@ pgstat_add_backend(PgStat_MsgHdr *msg) beentry->databaseid = msg->m_databaseid; beentry->procpid = msg->m_procpid; beentry->userid = msg->m_userid; + beentry->start_sec = + GetCurrentAbsoluteTimeUsec(&beentry->start_usec); beentry->activity_start_sec = 0; beentry->activity_start_usec = 0; + memcpy(&beentry->clientaddr, &msg->m_clientaddr, sizeof(beentry->clientaddr)); 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, (void *) &(msg->m_databaseid), @@ -2072,9 +2076,7 @@ pgstat_add_backend(PgStat_MsgHdr *msg) HASH_ELEM | HASH_FUNCTION); } - /* - * Count number of connects to the database - */ + /* Count the number of connects to the database */ dbentry->n_connects++; return 0; diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 953e079da5f..ae23dbf5d90 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -8,7 +8,7 @@ * * * 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 @@ #include "nodes/execnodes.h" #include "pgstat.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 */ extern Datum pg_stat_get_numscans(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_activity(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_xact_commit(PG_FUNCTION_ARGS); @@ -357,6 +363,117 @@ pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS) 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 pg_stat_get_db_numbackends(PG_FUNCTION_ARGS) |