aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/pgstatfuncs.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2016-03-10 12:44:09 -0500
committerRobert Haas <rhaas@postgresql.org>2016-03-10 12:44:09 -0500
commit53be0b1add7064ca5db3cd884302dfc3268d884e (patch)
tree913271b90f5a41778fe5bdbe2ac200c785dd6778 /src/backend/utils/adt/pgstatfuncs.c
parenta3a8309d450f7c4d1b743e84ba54ef5f7877d7be (diff)
downloadpostgresql-53be0b1add7064ca5db3cd884302dfc3268d884e.tar.gz
postgresql-53be0b1add7064ca5db3cd884302dfc3268d884e.zip
Provide much better wait information in pg_stat_activity.
When a process is waiting for a heavyweight lock, we will now indicate the type of heavyweight lock for which it is waiting. Also, you can now see when a process is waiting for a lightweight lock - in which case we will indicate the individual lock name or the tranche, as appropriate - or for a buffer pin. Amit Kapila, Ildus Kurbangaliev, reviewed by me. Lots of helpful discussion and suggestions by many others, including Alexander Korotkov, Vladimir Borodin, and many others.
Diffstat (limited to 'src/backend/utils/adt/pgstatfuncs.c')
-rw-r--r--src/backend/utils/adt/pgstatfuncs.c126
1 files changed, 87 insertions, 39 deletions
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 2fb51fa6788..0f6f891f8ac 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -20,6 +20,8 @@
#include "libpq/ip.h"
#include "miscadmin.h"
#include "pgstat.h"
+#include "storage/proc.h"
+#include "storage/procarray.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/inet.h"
@@ -58,7 +60,8 @@ extern Datum pg_stat_get_backend_pid(PG_FUNCTION_ARGS);
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_waiting(PG_FUNCTION_ARGS);
+extern Datum pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS);
+extern Datum pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS);
extern Datum pg_stat_get_backend_start(PG_FUNCTION_ARGS);
@@ -633,7 +636,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
Datum
pg_stat_get_activity(PG_FUNCTION_ARGS)
{
-#define PG_STAT_GET_ACTIVITY_COLS 22
+#define PG_STAT_GET_ACTIVITY_COLS 23
int num_backends = pgstat_fetch_stat_numbackends();
int curr_backend;
int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
@@ -676,6 +679,9 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
bool nulls[PG_STAT_GET_ACTIVITY_COLS];
LocalPgBackendStatus *local_beentry;
PgBackendStatus *beentry;
+ PGPROC *proc;
+ const char *wait_event_type;
+ const char *wait_event;
MemSet(values, 0, sizeof(values));
MemSet(nulls, 0, sizeof(nulls));
@@ -720,28 +726,28 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
nulls[3] = true;
if (TransactionIdIsValid(local_beentry->backend_xid))
- values[14] = TransactionIdGetDatum(local_beentry->backend_xid);
+ values[15] = TransactionIdGetDatum(local_beentry->backend_xid);
else
- nulls[14] = true;
+ nulls[15] = true;
if (TransactionIdIsValid(local_beentry->backend_xmin))
- values[15] = TransactionIdGetDatum(local_beentry->backend_xmin);
+ values[16] = TransactionIdGetDatum(local_beentry->backend_xmin);
else
- nulls[15] = true;
+ nulls[16] = true;
if (beentry->st_ssl)
{
- values[16] = BoolGetDatum(true); /* ssl */
- values[17] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
- values[18] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
- values[19] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
- values[20] = BoolGetDatum(beentry->st_sslstatus->ssl_compression);
- values[21] = CStringGetTextDatum(beentry->st_sslstatus->ssl_clientdn);
+ values[17] = BoolGetDatum(true); /* ssl */
+ values[18] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
+ values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
+ values[20] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
+ values[21] = BoolGetDatum(beentry->st_sslstatus->ssl_compression);
+ values[22] = CStringGetTextDatum(beentry->st_sslstatus->ssl_clientdn);
}
else
{
- values[16] = BoolGetDatum(false); /* ssl */
- nulls[17] = nulls[18] = nulls[19] = nulls[20] = nulls[21] = true;
+ values[17] = BoolGetDatum(false); /* ssl */
+ nulls[18] = nulls[19] = nulls[20] = nulls[21] = nulls[22] = true;
}
/* Values only available to role member */
@@ -775,36 +781,48 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
}
values[5] = CStringGetTextDatum(beentry->st_activity);
- values[6] = BoolGetDatum(beentry->st_waiting);
- if (beentry->st_xact_start_timestamp != 0)
- values[7] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
+ proc = BackendPidGetProc(beentry->st_procpid);
+ wait_event_type = pgstat_get_wait_event_type(proc->wait_event_info);
+ if (wait_event_type)
+ values[6] = CStringGetTextDatum(wait_event_type);
+ else
+ nulls[6] = true;
+
+ wait_event = pgstat_get_wait_event(proc->wait_event_info);
+ if (wait_event)
+ values[7] = CStringGetTextDatum(wait_event);
else
nulls[7] = true;
- if (beentry->st_activity_start_timestamp != 0)
- values[8] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
+ if (beentry->st_xact_start_timestamp != 0)
+ values[8] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
else
nulls[8] = true;
- if (beentry->st_proc_start_timestamp != 0)
- values[9] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
+ if (beentry->st_activity_start_timestamp != 0)
+ values[9] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
else
nulls[9] = true;
- if (beentry->st_state_start_timestamp != 0)
- values[10] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
+ if (beentry->st_proc_start_timestamp != 0)
+ values[10] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
else
nulls[10] = true;
+ if (beentry->st_state_start_timestamp != 0)
+ values[11] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
+ else
+ nulls[11] = true;
+
/* A zeroed client addr means we don't know */
memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
sizeof(zero_clientaddr)) == 0)
{
- nulls[11] = true;
nulls[12] = true;
nulls[13] = true;
+ nulls[14] = true;
}
else
{
@@ -828,20 +846,20 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
if (ret == 0)
{
clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
- values[11] = DirectFunctionCall1(inet_in,
+ values[12] = DirectFunctionCall1(inet_in,
CStringGetDatum(remote_host));
if (beentry->st_clienthostname &&
beentry->st_clienthostname[0])
- values[12] = CStringGetTextDatum(beentry->st_clienthostname);
+ values[13] = CStringGetTextDatum(beentry->st_clienthostname);
else
- nulls[12] = true;
- values[13] = Int32GetDatum(atoi(remote_port));
+ nulls[13] = true;
+ values[14] = Int32GetDatum(atoi(remote_port));
}
else
{
- nulls[11] = true;
nulls[12] = true;
nulls[13] = true;
+ nulls[14] = true;
}
}
else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
@@ -852,16 +870,16 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
* connections we have no permissions to view, or with
* errors.
*/
- nulls[11] = true;
nulls[12] = true;
- values[13] = DatumGetInt32(-1);
+ nulls[13] = true;
+ values[14] = DatumGetInt32(-1);
}
else
{
/* Unknown address type, should never happen */
- nulls[11] = true;
nulls[12] = true;
nulls[13] = true;
+ nulls[14] = true;
}
}
}
@@ -878,6 +896,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
nulls[11] = true;
nulls[12] = true;
nulls[13] = true;
+ nulls[14] = true;
}
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
@@ -959,23 +978,52 @@ pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(cstring_to_text(activity));
}
-
Datum
-pg_stat_get_backend_waiting(PG_FUNCTION_ARGS)
+pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
{
int32 beid = PG_GETARG_INT32(0);
- bool result;
PgBackendStatus *beentry;
+ PGPROC *proc;
+ const char *wait_event_type;
if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
- PG_RETURN_NULL();
+ wait_event_type = "<backend information not available>";
+ else if (!has_privs_of_role(GetUserId(), beentry->st_userid))
+ wait_event_type = "<insufficient privilege>";
+ else
+ {
+ proc = BackendPidGetProc(beentry->st_procpid);
+ wait_event_type = pgstat_get_wait_event_type(proc->wait_event_info);
+ }
- if (!has_privs_of_role(GetUserId(), beentry->st_userid))
+ if (!wait_event_type)
PG_RETURN_NULL();
- result = beentry->st_waiting;
+ PG_RETURN_TEXT_P(cstring_to_text(wait_event_type));
+}
+
+Datum
+pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
+{
+ int32 beid = PG_GETARG_INT32(0);
+ PgBackendStatus *beentry;
+ PGPROC *proc;
+ const char *wait_event;
+
+ if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ wait_event = "<backend information not available>";
+ else if (!has_privs_of_role(GetUserId(), beentry->st_userid))
+ wait_event = "<insufficient privilege>";
+ else
+ {
+ proc = BackendPidGetProc(beentry->st_procpid);
+ wait_event = pgstat_get_wait_event(proc->wait_event_info);
+ }
+
+ if (!wait_event)
+ PG_RETURN_NULL();
- PG_RETURN_BOOL(result);
+ PG_RETURN_TEXT_P(cstring_to_text(wait_event));
}