1 /*-------------------------------------------------------------------------
4 * Functions for accessing the statistics collector data
6 * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/utils/adt/pgstatfuncs.c
13 *-------------------------------------------------------------------------
17 #include "catalog/pg_type.h"
20 #include "miscadmin.h"
22 #include "utils/builtins.h"
23 #include "utils/inet.h"
24 #include "utils/timestamp.h"
26 /* bogus ... these externs should be in a header file */
27 extern Datum pg_stat_get_numscans(PG_FUNCTION_ARGS);
28 extern Datum pg_stat_get_tuples_returned(PG_FUNCTION_ARGS);
29 extern Datum pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS);
30 extern Datum pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS);
31 extern Datum pg_stat_get_tuples_updated(PG_FUNCTION_ARGS);
32 extern Datum pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS);
33 extern Datum pg_stat_get_tuples_hot_updated(PG_FUNCTION_ARGS);
34 extern Datum pg_stat_get_live_tuples(PG_FUNCTION_ARGS);
35 extern Datum pg_stat_get_dead_tuples(PG_FUNCTION_ARGS);
36 extern Datum pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS);
37 extern Datum pg_stat_get_blocks_hit(PG_FUNCTION_ARGS);
38 extern Datum pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS);
39 extern Datum pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS);
40 extern Datum pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS);
41 extern Datum pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS);
42 extern Datum pg_stat_get_vacuum_count(PG_FUNCTION_ARGS);
43 extern Datum pg_stat_get_autovacuum_count(PG_FUNCTION_ARGS);
44 extern Datum pg_stat_get_analyze_count(PG_FUNCTION_ARGS);
45 extern Datum pg_stat_get_autoanalyze_count(PG_FUNCTION_ARGS);
47 extern Datum pg_stat_get_function_calls(PG_FUNCTION_ARGS);
48 extern Datum pg_stat_get_function_time(PG_FUNCTION_ARGS);
49 extern Datum pg_stat_get_function_self_time(PG_FUNCTION_ARGS);
51 extern Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS);
52 extern Datum pg_stat_get_activity(PG_FUNCTION_ARGS);
53 extern Datum pg_backend_pid(PG_FUNCTION_ARGS);
54 extern Datum pg_stat_get_backend_pid(PG_FUNCTION_ARGS);
55 extern Datum pg_stat_get_backend_dbid(PG_FUNCTION_ARGS);
56 extern Datum pg_stat_get_backend_userid(PG_FUNCTION_ARGS);
57 extern Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS);
58 extern Datum pg_stat_get_backend_waiting(PG_FUNCTION_ARGS);
59 extern Datum pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS);
60 extern Datum pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS);
61 extern Datum pg_stat_get_backend_start(PG_FUNCTION_ARGS);
62 extern Datum pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS);
63 extern Datum pg_stat_get_backend_client_port(PG_FUNCTION_ARGS);
65 extern Datum pg_stat_get_db_numbackends(PG_FUNCTION_ARGS);
66 extern Datum pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS);
67 extern Datum pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS);
68 extern Datum pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS);
69 extern Datum pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS);
70 extern Datum pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS);
71 extern Datum pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS);
72 extern Datum pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS);
73 extern Datum pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS);
74 extern Datum pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS);
75 extern Datum pg_stat_get_db_conflict_tablespace(PG_FUNCTION_ARGS);
76 extern Datum pg_stat_get_db_conflict_lock(PG_FUNCTION_ARGS);
77 extern Datum pg_stat_get_db_conflict_snapshot(PG_FUNCTION_ARGS);
78 extern Datum pg_stat_get_db_conflict_bufferpin(PG_FUNCTION_ARGS);
79 extern Datum pg_stat_get_db_conflict_startup_deadlock(PG_FUNCTION_ARGS);
80 extern Datum pg_stat_get_db_conflict_all(PG_FUNCTION_ARGS);
81 extern Datum pg_stat_get_db_deadlocks(PG_FUNCTION_ARGS);
82 extern Datum pg_stat_get_db_stat_reset_time(PG_FUNCTION_ARGS);
83 extern Datum pg_stat_get_db_temp_files(PG_FUNCTION_ARGS);
84 extern Datum pg_stat_get_db_temp_bytes(PG_FUNCTION_ARGS);
85 extern Datum pg_stat_get_db_block_time_read(PG_FUNCTION_ARGS);
86 extern Datum pg_stat_get_db_block_time_write(PG_FUNCTION_ARGS);
88 extern Datum pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS);
89 extern Datum pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS);
90 extern Datum pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS);
91 extern Datum pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS);
92 extern Datum pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS);
93 extern Datum pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS);
94 extern Datum pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS);
95 extern Datum pg_stat_get_buf_fsync_backend(PG_FUNCTION_ARGS);
96 extern Datum pg_stat_get_buf_alloc(PG_FUNCTION_ARGS);
98 extern Datum pg_stat_get_xact_numscans(PG_FUNCTION_ARGS);
99 extern Datum pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS);
100 extern Datum pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS);
101 extern Datum pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS);
102 extern Datum pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS);
103 extern Datum pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS);
104 extern Datum pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS);
105 extern Datum pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS);
106 extern Datum pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS);
108 extern Datum pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS);
109 extern Datum pg_stat_get_xact_function_time(PG_FUNCTION_ARGS);
110 extern Datum pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS);
112 extern Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS);
113 extern Datum pg_stat_reset(PG_FUNCTION_ARGS);
114 extern Datum pg_stat_reset_shared(PG_FUNCTION_ARGS);
115 extern Datum pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS);
116 extern Datum pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS);
118 /* Global bgwriter statistics, from bgwriter.c */
119 extern PgStat_MsgBgWriter bgwriterStats;
122 pg_stat_get_numscans(PG_FUNCTION_ARGS)
124 Oid relid = PG_GETARG_OID(0);
126 PgStat_StatTabEntry *tabentry;
128 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
131 result = (int64) (tabentry->numscans);
133 PG_RETURN_INT64(result);
138 pg_stat_get_tuples_returned(PG_FUNCTION_ARGS)
140 Oid relid = PG_GETARG_OID(0);
142 PgStat_StatTabEntry *tabentry;
144 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
147 result = (int64) (tabentry->tuples_returned);
149 PG_RETURN_INT64(result);
154 pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS)
156 Oid relid = PG_GETARG_OID(0);
158 PgStat_StatTabEntry *tabentry;
160 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
163 result = (int64) (tabentry->tuples_fetched);
165 PG_RETURN_INT64(result);
170 pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS)
172 Oid relid = PG_GETARG_OID(0);
174 PgStat_StatTabEntry *tabentry;
176 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
179 result = (int64) (tabentry->tuples_inserted);
181 PG_RETURN_INT64(result);
186 pg_stat_get_tuples_updated(PG_FUNCTION_ARGS)
188 Oid relid = PG_GETARG_OID(0);
190 PgStat_StatTabEntry *tabentry;
192 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
195 result = (int64) (tabentry->tuples_updated);
197 PG_RETURN_INT64(result);
202 pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS)
204 Oid relid = PG_GETARG_OID(0);
206 PgStat_StatTabEntry *tabentry;
208 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
211 result = (int64) (tabentry->tuples_deleted);
213 PG_RETURN_INT64(result);
218 pg_stat_get_tuples_hot_updated(PG_FUNCTION_ARGS)
220 Oid relid = PG_GETARG_OID(0);
222 PgStat_StatTabEntry *tabentry;
224 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
227 result = (int64) (tabentry->tuples_hot_updated);
229 PG_RETURN_INT64(result);
234 pg_stat_get_live_tuples(PG_FUNCTION_ARGS)
236 Oid relid = PG_GETARG_OID(0);
238 PgStat_StatTabEntry *tabentry;
240 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
243 result = (int64) (tabentry->n_live_tuples);
245 PG_RETURN_INT64(result);
250 pg_stat_get_dead_tuples(PG_FUNCTION_ARGS)
252 Oid relid = PG_GETARG_OID(0);
254 PgStat_StatTabEntry *tabentry;
256 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
259 result = (int64) (tabentry->n_dead_tuples);
261 PG_RETURN_INT64(result);
266 pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS)
268 Oid relid = PG_GETARG_OID(0);
270 PgStat_StatTabEntry *tabentry;
272 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
275 result = (int64) (tabentry->blocks_fetched);
277 PG_RETURN_INT64(result);
282 pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
284 Oid relid = PG_GETARG_OID(0);
286 PgStat_StatTabEntry *tabentry;
288 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
291 result = (int64) (tabentry->blocks_hit);
293 PG_RETURN_INT64(result);
297 pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS)
299 Oid relid = PG_GETARG_OID(0);
301 PgStat_StatTabEntry *tabentry;
303 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
306 result = tabentry->vacuum_timestamp;
311 PG_RETURN_TIMESTAMPTZ(result);
315 pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS)
317 Oid relid = PG_GETARG_OID(0);
319 PgStat_StatTabEntry *tabentry;
321 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
324 result = tabentry->autovac_vacuum_timestamp;
329 PG_RETURN_TIMESTAMPTZ(result);
333 pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS)
335 Oid relid = PG_GETARG_OID(0);
337 PgStat_StatTabEntry *tabentry;
339 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
342 result = tabentry->analyze_timestamp;
347 PG_RETURN_TIMESTAMPTZ(result);
351 pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS)
353 Oid relid = PG_GETARG_OID(0);
355 PgStat_StatTabEntry *tabentry;
357 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
360 result = tabentry->autovac_analyze_timestamp;
365 PG_RETURN_TIMESTAMPTZ(result);
369 pg_stat_get_vacuum_count(PG_FUNCTION_ARGS)
371 Oid relid = PG_GETARG_OID(0);
373 PgStat_StatTabEntry *tabentry;
375 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
378 result = (int64) (tabentry->vacuum_count);
380 PG_RETURN_INT64(result);
384 pg_stat_get_autovacuum_count(PG_FUNCTION_ARGS)
386 Oid relid = PG_GETARG_OID(0);
388 PgStat_StatTabEntry *tabentry;
390 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
393 result = (int64) (tabentry->autovac_vacuum_count);
395 PG_RETURN_INT64(result);
399 pg_stat_get_analyze_count(PG_FUNCTION_ARGS)
401 Oid relid = PG_GETARG_OID(0);
403 PgStat_StatTabEntry *tabentry;
405 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
408 result = (int64) (tabentry->analyze_count);
410 PG_RETURN_INT64(result);
414 pg_stat_get_autoanalyze_count(PG_FUNCTION_ARGS)
416 Oid relid = PG_GETARG_OID(0);
418 PgStat_StatTabEntry *tabentry;
420 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
423 result = (int64) (tabentry->autovac_analyze_count);
425 PG_RETURN_INT64(result);
429 pg_stat_get_function_calls(PG_FUNCTION_ARGS)
431 Oid funcid = PG_GETARG_OID(0);
432 PgStat_StatFuncEntry *funcentry;
434 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
436 PG_RETURN_INT64(funcentry->f_numcalls);
440 pg_stat_get_function_time(PG_FUNCTION_ARGS)
442 Oid funcid = PG_GETARG_OID(0);
443 PgStat_StatFuncEntry *funcentry;
445 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
447 PG_RETURN_INT64(funcentry->f_time);
451 pg_stat_get_function_self_time(PG_FUNCTION_ARGS)
453 Oid funcid = PG_GETARG_OID(0);
454 PgStat_StatFuncEntry *funcentry;
456 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
458 PG_RETURN_INT64(funcentry->f_time_self);
462 pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
464 FuncCallContext *funcctx;
468 /* stuff done only on the first call of the function */
469 if (SRF_IS_FIRSTCALL())
471 /* create a function context for cross-call persistence */
472 funcctx = SRF_FIRSTCALL_INIT();
474 fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
476 funcctx->user_fctx = fctx;
479 fctx[1] = pgstat_fetch_stat_numbackends();
482 /* stuff done on every call of the function */
483 funcctx = SRF_PERCALL_SETUP();
484 fctx = funcctx->user_fctx;
489 if (result <= fctx[1])
491 /* do when there is more left to send */
492 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
496 /* do when there is no more left */
497 SRF_RETURN_DONE(funcctx);
502 pg_stat_get_activity(PG_FUNCTION_ARGS)
504 FuncCallContext *funcctx;
506 if (SRF_IS_FIRSTCALL())
508 MemoryContext oldcontext;
511 funcctx = SRF_FIRSTCALL_INIT();
513 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
515 tupdesc = CreateTemplateTupleDesc(14, false);
516 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "datid",
518 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "pid",
520 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "usesysid",
522 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "application_name",
524 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "state",
526 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "query",
528 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "waiting",
530 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "act_start",
531 TIMESTAMPTZOID, -1, 0);
532 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "query_start",
533 TIMESTAMPTZOID, -1, 0);
534 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "backend_start",
535 TIMESTAMPTZOID, -1, 0);
536 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "state_change",
537 TIMESTAMPTZOID, -1, 0);
538 TupleDescInitEntry(tupdesc, (AttrNumber) 12, "client_addr",
540 TupleDescInitEntry(tupdesc, (AttrNumber) 13, "client_hostname",
542 TupleDescInitEntry(tupdesc, (AttrNumber) 14, "client_port",
545 funcctx->tuple_desc = BlessTupleDesc(tupdesc);
547 funcctx->user_fctx = palloc0(sizeof(int));
550 /* Get all backends */
551 funcctx->max_calls = pgstat_fetch_stat_numbackends();
556 * Get one backend - locate by pid.
558 * We lookup the backend early, so we can return zero rows if it
559 * doesn't exist, instead of returning a single row full of NULLs.
561 int pid = PG_GETARG_INT32(0);
563 int n = pgstat_fetch_stat_numbackends();
565 for (i = 1; i <= n; i++)
567 PgBackendStatus *be = pgstat_fetch_stat_beentry(i);
571 if (be->st_procpid == pid)
573 *(int *) (funcctx->user_fctx) = i;
579 if (*(int *) (funcctx->user_fctx) == 0)
580 /* Pid not found, return zero rows */
581 funcctx->max_calls = 0;
583 funcctx->max_calls = 1;
586 MemoryContextSwitchTo(oldcontext);
589 /* stuff done on every call of the function */
590 funcctx = SRF_PERCALL_SETUP();
592 if (funcctx->call_cntr < funcctx->max_calls)
598 PgBackendStatus *beentry;
599 SockAddr zero_clientaddr;
601 MemSet(values, 0, sizeof(values));
602 MemSet(nulls, 0, sizeof(nulls));
604 if (*(int *) (funcctx->user_fctx) > 0)
606 /* Get specific pid slot */
607 beentry = pgstat_fetch_stat_beentry(*(int *) (funcctx->user_fctx));
611 /* Get the next one in the list */
612 beentry = pgstat_fetch_stat_beentry(funcctx->call_cntr + 1); /* 1-based index */
618 for (i = 0; i < sizeof(nulls) / sizeof(nulls[0]); i++)
622 values[5] = CStringGetTextDatum("<backend information not available>");
624 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
625 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
628 /* Values available to all callers */
629 values[0] = ObjectIdGetDatum(beentry->st_databaseid);
630 values[1] = Int32GetDatum(beentry->st_procpid);
631 values[2] = ObjectIdGetDatum(beentry->st_userid);
632 if (beentry->st_appname)
633 values[3] = CStringGetTextDatum(beentry->st_appname);
637 /* Values only available to same user or superuser */
638 if (superuser() || beentry->st_userid == GetUserId())
640 switch (beentry->st_state)
643 values[4] = CStringGetTextDatum("idle");
646 values[4] = CStringGetTextDatum("active");
648 case STATE_IDLEINTRANSACTION:
649 values[4] = CStringGetTextDatum("idle in transaction");
652 values[4] = CStringGetTextDatum("fastpath function call");
654 case STATE_IDLEINTRANSACTION_ABORTED:
655 values[4] = CStringGetTextDatum("idle in transaction (aborted)");
658 values[4] = CStringGetTextDatum("disabled");
660 case STATE_UNDEFINED:
664 if (beentry->st_state == STATE_UNDEFINED ||
665 beentry->st_state == STATE_DISABLED)
667 values[5] = CStringGetTextDatum("");
671 values[5] = CStringGetTextDatum(beentry->st_activity);
673 values[6] = BoolGetDatum(beentry->st_waiting);
675 if (beentry->st_xact_start_timestamp != 0)
676 values[7] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
680 if (beentry->st_activity_start_timestamp != 0)
681 values[8] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
685 if (beentry->st_proc_start_timestamp != 0)
686 values[9] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
690 if (beentry->st_state_start_timestamp != 0)
691 values[10] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
695 /* A zeroed client addr means we don't know */
696 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
697 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
698 sizeof(zero_clientaddr) == 0))
706 if (beentry->st_clientaddr.addr.ss_family == AF_INET
708 || beentry->st_clientaddr.addr.ss_family == AF_INET6
712 char remote_host[NI_MAXHOST];
713 char remote_port[NI_MAXSERV];
716 remote_host[0] = '\0';
717 remote_port[0] = '\0';
718 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
719 beentry->st_clientaddr.salen,
720 remote_host, sizeof(remote_host),
721 remote_port, sizeof(remote_port),
722 NI_NUMERICHOST | NI_NUMERICSERV);
725 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
726 values[11] = DirectFunctionCall1(inet_in,
727 CStringGetDatum(remote_host));
728 if (beentry->st_clienthostname)
729 values[12] = CStringGetTextDatum(beentry->st_clienthostname);
732 values[13] = Int32GetDatum(atoi(remote_port));
741 else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
744 * Unix sockets always reports NULL for host and -1 for
745 * port, so it's possible to tell the difference to
746 * connections we have no permissions to view, or with
751 values[13] = DatumGetInt32(-1);
755 /* Unknown address type, should never happen */
764 /* No permissions to view data about this session */
765 values[5] = CStringGetTextDatum("<insufficient privilege>");
777 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
779 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
784 SRF_RETURN_DONE(funcctx);
790 pg_backend_pid(PG_FUNCTION_ARGS)
792 PG_RETURN_INT32(MyProcPid);
797 pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
799 int32 beid = PG_GETARG_INT32(0);
800 PgBackendStatus *beentry;
802 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
805 PG_RETURN_INT32(beentry->st_procpid);
810 pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
812 int32 beid = PG_GETARG_INT32(0);
813 PgBackendStatus *beentry;
815 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
818 PG_RETURN_OID(beentry->st_databaseid);
823 pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
825 int32 beid = PG_GETARG_INT32(0);
826 PgBackendStatus *beentry;
828 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
831 PG_RETURN_OID(beentry->st_userid);
836 pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
838 int32 beid = PG_GETARG_INT32(0);
839 PgBackendStatus *beentry;
840 const char *activity;
842 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
843 activity = "<backend information not available>";
844 else if (!superuser() && beentry->st_userid != GetUserId())
845 activity = "<insufficient privilege>";
846 else if (*(beentry->st_activity) == '\0')
847 activity = "<command string not enabled>";
849 activity = beentry->st_activity;
851 PG_RETURN_TEXT_P(cstring_to_text(activity));
856 pg_stat_get_backend_waiting(PG_FUNCTION_ARGS)
858 int32 beid = PG_GETARG_INT32(0);
860 PgBackendStatus *beentry;
862 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
865 if (!superuser() && beentry->st_userid != GetUserId())
868 result = beentry->st_waiting;
870 PG_RETURN_BOOL(result);
875 pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
877 int32 beid = PG_GETARG_INT32(0);
879 PgBackendStatus *beentry;
881 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
884 if (!superuser() && beentry->st_userid != GetUserId())
887 result = beentry->st_activity_start_timestamp;
890 * No time recorded for start of current query -- this is the case if the
891 * user hasn't enabled query-level stats collection.
896 PG_RETURN_TIMESTAMPTZ(result);
901 pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
903 int32 beid = PG_GETARG_INT32(0);
905 PgBackendStatus *beentry;
907 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
910 if (!superuser() && beentry->st_userid != GetUserId())
913 result = beentry->st_xact_start_timestamp;
915 if (result == 0) /* not in a transaction */
918 PG_RETURN_TIMESTAMPTZ(result);
923 pg_stat_get_backend_start(PG_FUNCTION_ARGS)
925 int32 beid = PG_GETARG_INT32(0);
927 PgBackendStatus *beentry;
929 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
932 if (!superuser() && beentry->st_userid != GetUserId())
935 result = beentry->st_proc_start_timestamp;
937 if (result == 0) /* probably can't happen? */
940 PG_RETURN_TIMESTAMPTZ(result);
945 pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
947 int32 beid = PG_GETARG_INT32(0);
948 PgBackendStatus *beentry;
949 SockAddr zero_clientaddr;
950 char remote_host[NI_MAXHOST];
953 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
956 if (!superuser() && beentry->st_userid != GetUserId())
959 /* A zeroed client addr means we don't know */
960 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
961 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
962 sizeof(zero_clientaddr) == 0))
965 switch (beentry->st_clientaddr.addr.ss_family)
976 remote_host[0] = '\0';
977 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
978 beentry->st_clientaddr.salen,
979 remote_host, sizeof(remote_host),
981 NI_NUMERICHOST | NI_NUMERICSERV);
985 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
987 PG_RETURN_INET_P(DirectFunctionCall1(inet_in,
988 CStringGetDatum(remote_host)));
992 pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
994 int32 beid = PG_GETARG_INT32(0);
995 PgBackendStatus *beentry;
996 SockAddr zero_clientaddr;
997 char remote_port[NI_MAXSERV];
1000 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
1003 if (!superuser() && beentry->st_userid != GetUserId())
1006 /* A zeroed client addr means we don't know */
1007 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
1008 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
1009 sizeof(zero_clientaddr) == 0))
1012 switch (beentry->st_clientaddr.addr.ss_family)
1020 PG_RETURN_INT32(-1);
1025 remote_port[0] = '\0';
1026 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
1027 beentry->st_clientaddr.salen,
1029 remote_port, sizeof(remote_port),
1030 NI_NUMERICHOST | NI_NUMERICSERV);
1034 PG_RETURN_DATUM(DirectFunctionCall1(int4in,
1035 CStringGetDatum(remote_port)));
1040 pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
1042 Oid dbid = PG_GETARG_OID(0);
1044 int tot_backends = pgstat_fetch_stat_numbackends();
1048 for (beid = 1; beid <= tot_backends; beid++)
1050 PgBackendStatus *beentry = pgstat_fetch_stat_beentry(beid);
1052 if (beentry && beentry->st_databaseid == dbid)
1056 PG_RETURN_INT32(result);
1061 pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS)
1063 Oid dbid = PG_GETARG_OID(0);
1065 PgStat_StatDBEntry *dbentry;
1067 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1070 result = (int64) (dbentry->n_xact_commit);
1072 PG_RETURN_INT64(result);
1077 pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS)
1079 Oid dbid = PG_GETARG_OID(0);
1081 PgStat_StatDBEntry *dbentry;
1083 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1086 result = (int64) (dbentry->n_xact_rollback);
1088 PG_RETURN_INT64(result);
1093 pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS)
1095 Oid dbid = PG_GETARG_OID(0);
1097 PgStat_StatDBEntry *dbentry;
1099 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1102 result = (int64) (dbentry->n_blocks_fetched);
1104 PG_RETURN_INT64(result);
1109 pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS)
1111 Oid dbid = PG_GETARG_OID(0);
1113 PgStat_StatDBEntry *dbentry;
1115 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1118 result = (int64) (dbentry->n_blocks_hit);
1120 PG_RETURN_INT64(result);
1125 pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS)
1127 Oid dbid = PG_GETARG_OID(0);
1129 PgStat_StatDBEntry *dbentry;
1131 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1134 result = (int64) (dbentry->n_tuples_returned);
1136 PG_RETURN_INT64(result);
1141 pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS)
1143 Oid dbid = PG_GETARG_OID(0);
1145 PgStat_StatDBEntry *dbentry;
1147 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1150 result = (int64) (dbentry->n_tuples_fetched);
1152 PG_RETURN_INT64(result);
1157 pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS)
1159 Oid dbid = PG_GETARG_OID(0);
1161 PgStat_StatDBEntry *dbentry;
1163 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1166 result = (int64) (dbentry->n_tuples_inserted);
1168 PG_RETURN_INT64(result);
1173 pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS)
1175 Oid dbid = PG_GETARG_OID(0);
1177 PgStat_StatDBEntry *dbentry;
1179 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1182 result = (int64) (dbentry->n_tuples_updated);
1184 PG_RETURN_INT64(result);
1189 pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS)
1191 Oid dbid = PG_GETARG_OID(0);
1193 PgStat_StatDBEntry *dbentry;
1195 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1198 result = (int64) (dbentry->n_tuples_deleted);
1200 PG_RETURN_INT64(result);
1204 pg_stat_get_db_stat_reset_time(PG_FUNCTION_ARGS)
1206 Oid dbid = PG_GETARG_OID(0);
1208 PgStat_StatDBEntry *dbentry;
1210 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1213 result = dbentry->stat_reset_timestamp;
1218 PG_RETURN_TIMESTAMPTZ(result);
1222 pg_stat_get_db_temp_files(PG_FUNCTION_ARGS)
1224 Oid dbid = PG_GETARG_OID(0);
1226 PgStat_StatDBEntry *dbentry;
1228 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1231 result = dbentry->n_temp_files;
1233 PG_RETURN_INT64(result);
1238 pg_stat_get_db_temp_bytes(PG_FUNCTION_ARGS)
1240 Oid dbid = PG_GETARG_OID(0);
1242 PgStat_StatDBEntry *dbentry;
1244 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1247 result = dbentry->n_temp_bytes;
1249 PG_RETURN_INT64(result);
1253 pg_stat_get_db_conflict_tablespace(PG_FUNCTION_ARGS)
1255 Oid dbid = PG_GETARG_OID(0);
1257 PgStat_StatDBEntry *dbentry;
1259 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1262 result = (int64) (dbentry->n_conflict_tablespace);
1264 PG_RETURN_INT64(result);
1268 pg_stat_get_db_conflict_lock(PG_FUNCTION_ARGS)
1270 Oid dbid = PG_GETARG_OID(0);
1272 PgStat_StatDBEntry *dbentry;
1274 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1277 result = (int64) (dbentry->n_conflict_lock);
1279 PG_RETURN_INT64(result);
1283 pg_stat_get_db_conflict_snapshot(PG_FUNCTION_ARGS)
1285 Oid dbid = PG_GETARG_OID(0);
1287 PgStat_StatDBEntry *dbentry;
1289 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1292 result = (int64) (dbentry->n_conflict_snapshot);
1294 PG_RETURN_INT64(result);
1298 pg_stat_get_db_conflict_bufferpin(PG_FUNCTION_ARGS)
1300 Oid dbid = PG_GETARG_OID(0);
1302 PgStat_StatDBEntry *dbentry;
1304 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1307 result = (int64) (dbentry->n_conflict_bufferpin);
1309 PG_RETURN_INT64(result);
1313 pg_stat_get_db_conflict_startup_deadlock(PG_FUNCTION_ARGS)
1315 Oid dbid = PG_GETARG_OID(0);
1317 PgStat_StatDBEntry *dbentry;
1319 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1322 result = (int64) (dbentry->n_conflict_startup_deadlock);
1324 PG_RETURN_INT64(result);
1328 pg_stat_get_db_conflict_all(PG_FUNCTION_ARGS)
1330 Oid dbid = PG_GETARG_OID(0);
1332 PgStat_StatDBEntry *dbentry;
1334 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1338 dbentry->n_conflict_tablespace +
1339 dbentry->n_conflict_lock +
1340 dbentry->n_conflict_snapshot +
1341 dbentry->n_conflict_bufferpin +
1342 dbentry->n_conflict_startup_deadlock);
1344 PG_RETURN_INT64(result);
1348 pg_stat_get_db_deadlocks(PG_FUNCTION_ARGS)
1350 Oid dbid = PG_GETARG_OID(0);
1352 PgStat_StatDBEntry *dbentry;
1354 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1357 result = (int64) (dbentry->n_deadlocks);
1359 PG_RETURN_INT64(result);
1363 pg_stat_get_db_block_time_read(PG_FUNCTION_ARGS)
1365 Oid dbid = PG_GETARG_OID(0);
1367 PgStat_StatDBEntry *dbentry;
1369 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1372 result = (int64) (dbentry->n_block_time_read);
1374 PG_RETURN_INT64(result);
1378 pg_stat_get_db_block_time_write(PG_FUNCTION_ARGS)
1380 Oid dbid = PG_GETARG_OID(0);
1382 PgStat_StatDBEntry *dbentry;
1384 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1387 result = (int64) (dbentry->n_block_time_write);
1389 PG_RETURN_INT64(result);
1393 pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS)
1395 PG_RETURN_INT64(pgstat_fetch_global()->timed_checkpoints);
1399 pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS)
1401 PG_RETURN_INT64(pgstat_fetch_global()->requested_checkpoints);
1405 pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS)
1407 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_checkpoints);
1411 pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
1413 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_clean);
1417 pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS)
1419 PG_RETURN_INT64(pgstat_fetch_global()->maxwritten_clean);
1423 pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS)
1425 PG_RETURN_TIMESTAMPTZ(pgstat_fetch_global()->stat_reset_timestamp);
1429 pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS)
1431 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_backend);
1435 pg_stat_get_buf_fsync_backend(PG_FUNCTION_ARGS)
1437 PG_RETURN_INT64(pgstat_fetch_global()->buf_fsync_backend);
1441 pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
1443 PG_RETURN_INT64(pgstat_fetch_global()->buf_alloc);
1447 pg_stat_get_xact_numscans(PG_FUNCTION_ARGS)
1449 Oid relid = PG_GETARG_OID(0);
1451 PgStat_TableStatus *tabentry;
1453 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1456 result = (int64) (tabentry->t_counts.t_numscans);
1458 PG_RETURN_INT64(result);
1462 pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS)
1464 Oid relid = PG_GETARG_OID(0);
1466 PgStat_TableStatus *tabentry;
1468 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1471 result = (int64) (tabentry->t_counts.t_tuples_returned);
1473 PG_RETURN_INT64(result);
1477 pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS)
1479 Oid relid = PG_GETARG_OID(0);
1481 PgStat_TableStatus *tabentry;
1483 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1486 result = (int64) (tabentry->t_counts.t_tuples_fetched);
1488 PG_RETURN_INT64(result);
1492 pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS)
1494 Oid relid = PG_GETARG_OID(0);
1496 PgStat_TableStatus *tabentry;
1497 PgStat_TableXactStatus *trans;
1499 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1503 result = tabentry->t_counts.t_tuples_inserted;
1504 /* live subtransactions' counts aren't in t_tuples_inserted yet */
1505 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1506 result += trans->tuples_inserted;
1509 PG_RETURN_INT64(result);
1513 pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS)
1515 Oid relid = PG_GETARG_OID(0);
1517 PgStat_TableStatus *tabentry;
1518 PgStat_TableXactStatus *trans;
1520 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1524 result = tabentry->t_counts.t_tuples_updated;
1525 /* live subtransactions' counts aren't in t_tuples_updated yet */
1526 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1527 result += trans->tuples_updated;
1530 PG_RETURN_INT64(result);
1534 pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS)
1536 Oid relid = PG_GETARG_OID(0);
1538 PgStat_TableStatus *tabentry;
1539 PgStat_TableXactStatus *trans;
1541 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1545 result = tabentry->t_counts.t_tuples_deleted;
1546 /* live subtransactions' counts aren't in t_tuples_deleted yet */
1547 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1548 result += trans->tuples_deleted;
1551 PG_RETURN_INT64(result);
1555 pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS)
1557 Oid relid = PG_GETARG_OID(0);
1559 PgStat_TableStatus *tabentry;
1561 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1564 result = (int64) (tabentry->t_counts.t_tuples_hot_updated);
1566 PG_RETURN_INT64(result);
1570 pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS)
1572 Oid relid = PG_GETARG_OID(0);
1574 PgStat_TableStatus *tabentry;
1576 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1579 result = (int64) (tabentry->t_counts.t_blocks_fetched);
1581 PG_RETURN_INT64(result);
1585 pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS)
1587 Oid relid = PG_GETARG_OID(0);
1589 PgStat_TableStatus *tabentry;
1591 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1594 result = (int64) (tabentry->t_counts.t_blocks_hit);
1596 PG_RETURN_INT64(result);
1600 pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)
1602 Oid funcid = PG_GETARG_OID(0);
1603 PgStat_BackendFunctionEntry *funcentry;
1605 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1607 PG_RETURN_INT64(funcentry->f_counts.f_numcalls);
1611 pg_stat_get_xact_function_time(PG_FUNCTION_ARGS)
1613 Oid funcid = PG_GETARG_OID(0);
1614 PgStat_BackendFunctionEntry *funcentry;
1616 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1618 PG_RETURN_INT64(INSTR_TIME_GET_MICROSEC(funcentry->f_counts.f_time));
1622 pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS)
1624 Oid funcid = PG_GETARG_OID(0);
1625 PgStat_BackendFunctionEntry *funcentry;
1627 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1629 PG_RETURN_INT64(INSTR_TIME_GET_MICROSEC(funcentry->f_counts.f_time_self));
1633 /* Discard the active statistics snapshot */
1635 pg_stat_clear_snapshot(PG_FUNCTION_ARGS)
1637 pgstat_clear_snapshot();
1643 /* Reset all counters for the current database */
1645 pg_stat_reset(PG_FUNCTION_ARGS)
1647 pgstat_reset_counters();
1652 /* Reset some shared cluster-wide counters */
1654 pg_stat_reset_shared(PG_FUNCTION_ARGS)
1656 char *target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1658 pgstat_reset_shared_counters(target);
1663 /* Reset a a single counter in the current database */
1665 pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS)
1667 Oid taboid = PG_GETARG_OID(0);
1669 pgstat_reset_single_counter(taboid, RESET_TABLE);
1675 pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS)
1677 Oid funcoid = PG_GETARG_OID(0);
1679 pgstat_reset_single_counter(funcoid, RESET_FUNCTION);