1 /*-------------------------------------------------------------------------
4 * Functions for accessing the statistics collector data
6 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/utils/adt/pgstatfuncs.c
13 *-------------------------------------------------------------------------
18 #include "miscadmin.h"
20 #include "catalog/pg_type.h"
21 #include "utils/builtins.h"
22 #include "utils/inet.h"
25 /* bogus ... these externs should be in a header file */
26 extern Datum pg_stat_get_numscans(PG_FUNCTION_ARGS);
27 extern Datum pg_stat_get_tuples_returned(PG_FUNCTION_ARGS);
28 extern Datum pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS);
29 extern Datum pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS);
30 extern Datum pg_stat_get_tuples_updated(PG_FUNCTION_ARGS);
31 extern Datum pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS);
32 extern Datum pg_stat_get_tuples_hot_updated(PG_FUNCTION_ARGS);
33 extern Datum pg_stat_get_live_tuples(PG_FUNCTION_ARGS);
34 extern Datum pg_stat_get_dead_tuples(PG_FUNCTION_ARGS);
35 extern Datum pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS);
36 extern Datum pg_stat_get_blocks_hit(PG_FUNCTION_ARGS);
37 extern Datum pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS);
38 extern Datum pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS);
39 extern Datum pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS);
40 extern Datum pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS);
41 extern Datum pg_stat_get_vacuum_count(PG_FUNCTION_ARGS);
42 extern Datum pg_stat_get_autovacuum_count(PG_FUNCTION_ARGS);
43 extern Datum pg_stat_get_analyze_count(PG_FUNCTION_ARGS);
44 extern Datum pg_stat_get_autoanalyze_count(PG_FUNCTION_ARGS);
46 extern Datum pg_stat_get_function_calls(PG_FUNCTION_ARGS);
47 extern Datum pg_stat_get_function_time(PG_FUNCTION_ARGS);
48 extern Datum pg_stat_get_function_self_time(PG_FUNCTION_ARGS);
50 extern Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS);
51 extern Datum pg_stat_get_activity(PG_FUNCTION_ARGS);
52 extern Datum pg_backend_pid(PG_FUNCTION_ARGS);
53 extern Datum pg_stat_get_backend_pid(PG_FUNCTION_ARGS);
54 extern Datum pg_stat_get_backend_dbid(PG_FUNCTION_ARGS);
55 extern Datum pg_stat_get_backend_userid(PG_FUNCTION_ARGS);
56 extern Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS);
57 extern Datum pg_stat_get_backend_waiting(PG_FUNCTION_ARGS);
58 extern Datum pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS);
59 extern Datum pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS);
60 extern Datum pg_stat_get_backend_start(PG_FUNCTION_ARGS);
61 extern Datum pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS);
62 extern Datum pg_stat_get_backend_client_port(PG_FUNCTION_ARGS);
64 extern Datum pg_stat_get_db_numbackends(PG_FUNCTION_ARGS);
65 extern Datum pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS);
66 extern Datum pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS);
67 extern Datum pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS);
68 extern Datum pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS);
69 extern Datum pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS);
70 extern Datum pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS);
71 extern Datum pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS);
72 extern Datum pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS);
73 extern Datum pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS);
75 extern Datum pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS);
76 extern Datum pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS);
77 extern Datum pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS);
78 extern Datum pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS);
79 extern Datum pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS);
80 extern Datum pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS);
81 extern Datum pg_stat_get_buf_fsync_backend(PG_FUNCTION_ARGS);
82 extern Datum pg_stat_get_buf_alloc(PG_FUNCTION_ARGS);
84 extern Datum pg_stat_get_xact_numscans(PG_FUNCTION_ARGS);
85 extern Datum pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS);
86 extern Datum pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS);
87 extern Datum pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS);
88 extern Datum pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS);
89 extern Datum pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS);
90 extern Datum pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS);
91 extern Datum pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS);
92 extern Datum pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS);
94 extern Datum pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS);
95 extern Datum pg_stat_get_xact_function_time(PG_FUNCTION_ARGS);
96 extern Datum pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS);
98 extern Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS);
99 extern Datum pg_stat_reset(PG_FUNCTION_ARGS);
100 extern Datum pg_stat_reset_shared(PG_FUNCTION_ARGS);
101 extern Datum pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS);
102 extern Datum pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS);
104 /* Global bgwriter statistics, from bgwriter.c */
105 extern PgStat_MsgBgWriter bgwriterStats;
108 pg_stat_get_numscans(PG_FUNCTION_ARGS)
110 Oid relid = PG_GETARG_OID(0);
112 PgStat_StatTabEntry *tabentry;
114 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
117 result = (int64) (tabentry->numscans);
119 PG_RETURN_INT64(result);
124 pg_stat_get_tuples_returned(PG_FUNCTION_ARGS)
126 Oid relid = PG_GETARG_OID(0);
128 PgStat_StatTabEntry *tabentry;
130 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
133 result = (int64) (tabentry->tuples_returned);
135 PG_RETURN_INT64(result);
140 pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS)
142 Oid relid = PG_GETARG_OID(0);
144 PgStat_StatTabEntry *tabentry;
146 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
149 result = (int64) (tabentry->tuples_fetched);
151 PG_RETURN_INT64(result);
156 pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS)
158 Oid relid = PG_GETARG_OID(0);
160 PgStat_StatTabEntry *tabentry;
162 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
165 result = (int64) (tabentry->tuples_inserted);
167 PG_RETURN_INT64(result);
172 pg_stat_get_tuples_updated(PG_FUNCTION_ARGS)
174 Oid relid = PG_GETARG_OID(0);
176 PgStat_StatTabEntry *tabentry;
178 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
181 result = (int64) (tabentry->tuples_updated);
183 PG_RETURN_INT64(result);
188 pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS)
190 Oid relid = PG_GETARG_OID(0);
192 PgStat_StatTabEntry *tabentry;
194 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
197 result = (int64) (tabentry->tuples_deleted);
199 PG_RETURN_INT64(result);
204 pg_stat_get_tuples_hot_updated(PG_FUNCTION_ARGS)
206 Oid relid = PG_GETARG_OID(0);
208 PgStat_StatTabEntry *tabentry;
210 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
213 result = (int64) (tabentry->tuples_hot_updated);
215 PG_RETURN_INT64(result);
220 pg_stat_get_live_tuples(PG_FUNCTION_ARGS)
222 Oid relid = PG_GETARG_OID(0);
224 PgStat_StatTabEntry *tabentry;
226 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
229 result = (int64) (tabentry->n_live_tuples);
231 PG_RETURN_INT64(result);
236 pg_stat_get_dead_tuples(PG_FUNCTION_ARGS)
238 Oid relid = PG_GETARG_OID(0);
240 PgStat_StatTabEntry *tabentry;
242 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
245 result = (int64) (tabentry->n_dead_tuples);
247 PG_RETURN_INT64(result);
252 pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS)
254 Oid relid = PG_GETARG_OID(0);
256 PgStat_StatTabEntry *tabentry;
258 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
261 result = (int64) (tabentry->blocks_fetched);
263 PG_RETURN_INT64(result);
268 pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
270 Oid relid = PG_GETARG_OID(0);
272 PgStat_StatTabEntry *tabentry;
274 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
277 result = (int64) (tabentry->blocks_hit);
279 PG_RETURN_INT64(result);
283 pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS)
285 Oid relid = PG_GETARG_OID(0);
287 PgStat_StatTabEntry *tabentry;
289 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
292 result = tabentry->vacuum_timestamp;
297 PG_RETURN_TIMESTAMPTZ(result);
301 pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS)
303 Oid relid = PG_GETARG_OID(0);
305 PgStat_StatTabEntry *tabentry;
307 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
310 result = tabentry->autovac_vacuum_timestamp;
315 PG_RETURN_TIMESTAMPTZ(result);
319 pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS)
321 Oid relid = PG_GETARG_OID(0);
323 PgStat_StatTabEntry *tabentry;
325 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
328 result = tabentry->analyze_timestamp;
333 PG_RETURN_TIMESTAMPTZ(result);
337 pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS)
339 Oid relid = PG_GETARG_OID(0);
341 PgStat_StatTabEntry *tabentry;
343 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
346 result = tabentry->autovac_analyze_timestamp;
351 PG_RETURN_TIMESTAMPTZ(result);
355 pg_stat_get_vacuum_count(PG_FUNCTION_ARGS)
357 Oid relid = PG_GETARG_OID(0);
359 PgStat_StatTabEntry *tabentry;
361 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
364 result = (int64) (tabentry->vacuum_count);
366 PG_RETURN_INT64(result);
370 pg_stat_get_autovacuum_count(PG_FUNCTION_ARGS)
372 Oid relid = PG_GETARG_OID(0);
374 PgStat_StatTabEntry *tabentry;
376 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
379 result = (int64) (tabentry->autovac_vacuum_count);
381 PG_RETURN_INT64(result);
385 pg_stat_get_analyze_count(PG_FUNCTION_ARGS)
387 Oid relid = PG_GETARG_OID(0);
389 PgStat_StatTabEntry *tabentry;
391 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
394 result = (int64) (tabentry->analyze_count);
396 PG_RETURN_INT64(result);
400 pg_stat_get_autoanalyze_count(PG_FUNCTION_ARGS)
402 Oid relid = PG_GETARG_OID(0);
404 PgStat_StatTabEntry *tabentry;
406 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
409 result = (int64) (tabentry->autovac_analyze_count);
411 PG_RETURN_INT64(result);
415 pg_stat_get_function_calls(PG_FUNCTION_ARGS)
417 Oid funcid = PG_GETARG_OID(0);
418 PgStat_StatFuncEntry *funcentry;
420 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
422 PG_RETURN_INT64(funcentry->f_numcalls);
426 pg_stat_get_function_time(PG_FUNCTION_ARGS)
428 Oid funcid = PG_GETARG_OID(0);
429 PgStat_StatFuncEntry *funcentry;
431 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
433 PG_RETURN_INT64(funcentry->f_time);
437 pg_stat_get_function_self_time(PG_FUNCTION_ARGS)
439 Oid funcid = PG_GETARG_OID(0);
440 PgStat_StatFuncEntry *funcentry;
442 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
444 PG_RETURN_INT64(funcentry->f_time_self);
448 pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
450 FuncCallContext *funcctx;
454 /* stuff done only on the first call of the function */
455 if (SRF_IS_FIRSTCALL())
457 /* create a function context for cross-call persistence */
458 funcctx = SRF_FIRSTCALL_INIT();
460 fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
462 funcctx->user_fctx = fctx;
465 fctx[1] = pgstat_fetch_stat_numbackends();
468 /* stuff done on every call of the function */
469 funcctx = SRF_PERCALL_SETUP();
470 fctx = funcctx->user_fctx;
475 if (result <= fctx[1])
477 /* do when there is more left to send */
478 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
482 /* do when there is no more left */
483 SRF_RETURN_DONE(funcctx);
488 pg_stat_get_activity(PG_FUNCTION_ARGS)
490 FuncCallContext *funcctx;
492 if (SRF_IS_FIRSTCALL())
494 MemoryContext oldcontext;
497 funcctx = SRF_FIRSTCALL_INIT();
499 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
501 tupdesc = CreateTemplateTupleDesc(11, false);
502 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "datid", OIDOID, -1, 0);
503 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "procpid", INT4OID, -1, 0);
504 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "usesysid", OIDOID, -1, 0);
505 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "application_name", TEXTOID, -1, 0);
506 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "current_query", TEXTOID, -1, 0);
507 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "waiting", BOOLOID, -1, 0);
508 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "act_start", TIMESTAMPTZOID, -1, 0);
509 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "query_start", TIMESTAMPTZOID, -1, 0);
510 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "backend_start", TIMESTAMPTZOID, -1, 0);
511 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "client_addr", INETOID, -1, 0);
512 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "client_port", INT4OID, -1, 0);
514 funcctx->tuple_desc = BlessTupleDesc(tupdesc);
516 funcctx->user_fctx = palloc0(sizeof(int));
519 /* Get all backends */
520 funcctx->max_calls = pgstat_fetch_stat_numbackends();
525 * Get one backend - locate by pid.
527 * We lookup the backend early, so we can return zero rows if it
528 * doesn't exist, instead of returning a single row full of NULLs.
530 int pid = PG_GETARG_INT32(0);
532 int n = pgstat_fetch_stat_numbackends();
534 for (i = 1; i <= n; i++)
536 PgBackendStatus *be = pgstat_fetch_stat_beentry(i);
540 if (be->st_procpid == pid)
542 *(int *) (funcctx->user_fctx) = i;
548 if (*(int *) (funcctx->user_fctx) == 0)
549 /* Pid not found, return zero rows */
550 funcctx->max_calls = 0;
552 funcctx->max_calls = 1;
555 MemoryContextSwitchTo(oldcontext);
558 /* stuff done on every call of the function */
559 funcctx = SRF_PERCALL_SETUP();
561 if (funcctx->call_cntr < funcctx->max_calls)
567 PgBackendStatus *beentry;
568 SockAddr zero_clientaddr;
570 MemSet(values, 0, sizeof(values));
571 MemSet(nulls, 0, sizeof(nulls));
573 if (*(int *) (funcctx->user_fctx) > 0)
575 /* Get specific pid slot */
576 beentry = pgstat_fetch_stat_beentry(*(int *) (funcctx->user_fctx));
580 /* Get the next one in the list */
581 beentry = pgstat_fetch_stat_beentry(funcctx->call_cntr + 1); /* 1-based index */
587 for (i = 0; i < sizeof(nulls) / sizeof(nulls[0]); i++)
591 values[4] = CStringGetTextDatum("<backend information not available>");
593 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
594 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
597 /* Values available to all callers */
598 values[0] = ObjectIdGetDatum(beentry->st_databaseid);
599 values[1] = Int32GetDatum(beentry->st_procpid);
600 values[2] = ObjectIdGetDatum(beentry->st_userid);
601 if (beentry->st_appname)
602 values[3] = CStringGetTextDatum(beentry->st_appname);
606 /* Values only available to same user or superuser */
607 if (superuser() || beentry->st_userid == GetUserId())
609 if (*(beentry->st_activity) == '\0')
611 values[4] = CStringGetTextDatum("<command string not enabled>");
615 values[4] = CStringGetTextDatum(beentry->st_activity);
618 values[5] = BoolGetDatum(beentry->st_waiting);
620 if (beentry->st_xact_start_timestamp != 0)
621 values[6] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
625 if (beentry->st_activity_start_timestamp != 0)
626 values[7] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
630 if (beentry->st_proc_start_timestamp != 0)
631 values[8] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
635 /* A zeroed client addr means we don't know */
636 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
637 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
638 sizeof(zero_clientaddr) == 0))
645 if (beentry->st_clientaddr.addr.ss_family == AF_INET
647 || beentry->st_clientaddr.addr.ss_family == AF_INET6
651 char remote_host[NI_MAXHOST];
652 char remote_port[NI_MAXSERV];
655 remote_host[0] = '\0';
656 remote_port[0] = '\0';
657 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
658 beentry->st_clientaddr.salen,
659 remote_host, sizeof(remote_host),
660 remote_port, sizeof(remote_port),
661 NI_NUMERICHOST | NI_NUMERICSERV);
669 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
670 values[9] = DirectFunctionCall1(inet_in,
671 CStringGetDatum(remote_host));
672 values[10] = Int32GetDatum(atoi(remote_port));
675 else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
678 * Unix sockets always reports NULL for host and -1 for
679 * port, so it's possible to tell the difference to
680 * connections we have no permissions to view, or with
684 values[10] = DatumGetInt32(-1);
688 /* Unknown address type, should never happen */
696 /* No permissions to view data about this session */
697 values[4] = CStringGetTextDatum("<insufficient privilege>");
706 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
708 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
713 SRF_RETURN_DONE(funcctx);
719 pg_backend_pid(PG_FUNCTION_ARGS)
721 PG_RETURN_INT32(MyProcPid);
726 pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
728 int32 beid = PG_GETARG_INT32(0);
729 PgBackendStatus *beentry;
731 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
734 PG_RETURN_INT32(beentry->st_procpid);
739 pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
741 int32 beid = PG_GETARG_INT32(0);
742 PgBackendStatus *beentry;
744 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
747 PG_RETURN_OID(beentry->st_databaseid);
752 pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
754 int32 beid = PG_GETARG_INT32(0);
755 PgBackendStatus *beentry;
757 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
760 PG_RETURN_OID(beentry->st_userid);
765 pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
767 int32 beid = PG_GETARG_INT32(0);
768 PgBackendStatus *beentry;
769 const char *activity;
771 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
772 activity = "<backend information not available>";
773 else if (!superuser() && beentry->st_userid != GetUserId())
774 activity = "<insufficient privilege>";
775 else if (*(beentry->st_activity) == '\0')
776 activity = "<command string not enabled>";
778 activity = beentry->st_activity;
780 PG_RETURN_TEXT_P(cstring_to_text(activity));
785 pg_stat_get_backend_waiting(PG_FUNCTION_ARGS)
787 int32 beid = PG_GETARG_INT32(0);
789 PgBackendStatus *beentry;
791 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
794 if (!superuser() && beentry->st_userid != GetUserId())
797 result = beentry->st_waiting;
799 PG_RETURN_BOOL(result);
804 pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
806 int32 beid = PG_GETARG_INT32(0);
808 PgBackendStatus *beentry;
810 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
813 if (!superuser() && beentry->st_userid != GetUserId())
816 result = beentry->st_activity_start_timestamp;
819 * No time recorded for start of current query -- this is the case if the
820 * user hasn't enabled query-level stats collection.
825 PG_RETURN_TIMESTAMPTZ(result);
830 pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
832 int32 beid = PG_GETARG_INT32(0);
834 PgBackendStatus *beentry;
836 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
839 if (!superuser() && beentry->st_userid != GetUserId())
842 result = beentry->st_xact_start_timestamp;
844 if (result == 0) /* not in a transaction */
847 PG_RETURN_TIMESTAMPTZ(result);
852 pg_stat_get_backend_start(PG_FUNCTION_ARGS)
854 int32 beid = PG_GETARG_INT32(0);
856 PgBackendStatus *beentry;
858 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
861 if (!superuser() && beentry->st_userid != GetUserId())
864 result = beentry->st_proc_start_timestamp;
866 if (result == 0) /* probably can't happen? */
869 PG_RETURN_TIMESTAMPTZ(result);
874 pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
876 int32 beid = PG_GETARG_INT32(0);
877 PgBackendStatus *beentry;
878 SockAddr zero_clientaddr;
879 char remote_host[NI_MAXHOST];
882 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
885 if (!superuser() && beentry->st_userid != GetUserId())
888 /* A zeroed client addr means we don't know */
889 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
890 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
891 sizeof(zero_clientaddr) == 0))
894 switch (beentry->st_clientaddr.addr.ss_family)
905 remote_host[0] = '\0';
906 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
907 beentry->st_clientaddr.salen,
908 remote_host, sizeof(remote_host),
910 NI_NUMERICHOST | NI_NUMERICSERV);
914 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
916 PG_RETURN_INET_P(DirectFunctionCall1(inet_in,
917 CStringGetDatum(remote_host)));
921 pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
923 int32 beid = PG_GETARG_INT32(0);
924 PgBackendStatus *beentry;
925 SockAddr zero_clientaddr;
926 char remote_port[NI_MAXSERV];
929 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
932 if (!superuser() && beentry->st_userid != GetUserId())
935 /* A zeroed client addr means we don't know */
936 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
937 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
938 sizeof(zero_clientaddr) == 0))
941 switch (beentry->st_clientaddr.addr.ss_family)
954 remote_port[0] = '\0';
955 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
956 beentry->st_clientaddr.salen,
958 remote_port, sizeof(remote_port),
959 NI_NUMERICHOST | NI_NUMERICSERV);
963 PG_RETURN_DATUM(DirectFunctionCall1(int4in,
964 CStringGetDatum(remote_port)));
969 pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
971 Oid dbid = PG_GETARG_OID(0);
973 int tot_backends = pgstat_fetch_stat_numbackends();
977 for (beid = 1; beid <= tot_backends; beid++)
979 PgBackendStatus *beentry = pgstat_fetch_stat_beentry(beid);
981 if (beentry && beentry->st_databaseid == dbid)
985 PG_RETURN_INT32(result);
990 pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS)
992 Oid dbid = PG_GETARG_OID(0);
994 PgStat_StatDBEntry *dbentry;
996 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
999 result = (int64) (dbentry->n_xact_commit);
1001 PG_RETURN_INT64(result);
1006 pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS)
1008 Oid dbid = PG_GETARG_OID(0);
1010 PgStat_StatDBEntry *dbentry;
1012 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1015 result = (int64) (dbentry->n_xact_rollback);
1017 PG_RETURN_INT64(result);
1022 pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS)
1024 Oid dbid = PG_GETARG_OID(0);
1026 PgStat_StatDBEntry *dbentry;
1028 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1031 result = (int64) (dbentry->n_blocks_fetched);
1033 PG_RETURN_INT64(result);
1038 pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS)
1040 Oid dbid = PG_GETARG_OID(0);
1042 PgStat_StatDBEntry *dbentry;
1044 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1047 result = (int64) (dbentry->n_blocks_hit);
1049 PG_RETURN_INT64(result);
1054 pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS)
1056 Oid dbid = PG_GETARG_OID(0);
1058 PgStat_StatDBEntry *dbentry;
1060 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1063 result = (int64) (dbentry->n_tuples_returned);
1065 PG_RETURN_INT64(result);
1070 pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS)
1072 Oid dbid = PG_GETARG_OID(0);
1074 PgStat_StatDBEntry *dbentry;
1076 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1079 result = (int64) (dbentry->n_tuples_fetched);
1081 PG_RETURN_INT64(result);
1086 pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS)
1088 Oid dbid = PG_GETARG_OID(0);
1090 PgStat_StatDBEntry *dbentry;
1092 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1095 result = (int64) (dbentry->n_tuples_inserted);
1097 PG_RETURN_INT64(result);
1102 pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS)
1104 Oid dbid = PG_GETARG_OID(0);
1106 PgStat_StatDBEntry *dbentry;
1108 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1111 result = (int64) (dbentry->n_tuples_updated);
1113 PG_RETURN_INT64(result);
1118 pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS)
1120 Oid dbid = PG_GETARG_OID(0);
1122 PgStat_StatDBEntry *dbentry;
1124 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1127 result = (int64) (dbentry->n_tuples_deleted);
1129 PG_RETURN_INT64(result);
1133 pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS)
1135 PG_RETURN_INT64(pgstat_fetch_global()->timed_checkpoints);
1139 pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS)
1141 PG_RETURN_INT64(pgstat_fetch_global()->requested_checkpoints);
1145 pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS)
1147 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_checkpoints);
1151 pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
1153 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_clean);
1157 pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS)
1159 PG_RETURN_INT64(pgstat_fetch_global()->maxwritten_clean);
1163 pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS)
1165 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_backend);
1169 pg_stat_get_buf_fsync_backend(PG_FUNCTION_ARGS)
1171 PG_RETURN_INT64(pgstat_fetch_global()->buf_fsync_backend);
1175 pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
1177 PG_RETURN_INT64(pgstat_fetch_global()->buf_alloc);
1181 pg_stat_get_xact_numscans(PG_FUNCTION_ARGS)
1183 Oid relid = PG_GETARG_OID(0);
1185 PgStat_TableStatus *tabentry;
1187 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1190 result = (int64) (tabentry->t_counts.t_numscans);
1192 PG_RETURN_INT64(result);
1196 pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS)
1198 Oid relid = PG_GETARG_OID(0);
1200 PgStat_TableStatus *tabentry;
1202 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1205 result = (int64) (tabentry->t_counts.t_tuples_returned);
1207 PG_RETURN_INT64(result);
1211 pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS)
1213 Oid relid = PG_GETARG_OID(0);
1215 PgStat_TableStatus *tabentry;
1217 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1220 result = (int64) (tabentry->t_counts.t_tuples_fetched);
1222 PG_RETURN_INT64(result);
1226 pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS)
1228 Oid relid = PG_GETARG_OID(0);
1230 PgStat_TableStatus *tabentry;
1231 PgStat_TableXactStatus *trans;
1233 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1237 result = tabentry->t_counts.t_tuples_inserted;
1238 /* live subtransactions' counts aren't in t_tuples_inserted yet */
1239 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1240 result += trans->tuples_inserted;
1243 PG_RETURN_INT64(result);
1247 pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS)
1249 Oid relid = PG_GETARG_OID(0);
1251 PgStat_TableStatus *tabentry;
1252 PgStat_TableXactStatus *trans;
1254 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1258 result = tabentry->t_counts.t_tuples_updated;
1259 /* live subtransactions' counts aren't in t_tuples_updated yet */
1260 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1261 result += trans->tuples_updated;
1264 PG_RETURN_INT64(result);
1268 pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS)
1270 Oid relid = PG_GETARG_OID(0);
1272 PgStat_TableStatus *tabentry;
1273 PgStat_TableXactStatus *trans;
1275 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1279 result = tabentry->t_counts.t_tuples_deleted;
1280 /* live subtransactions' counts aren't in t_tuples_deleted yet */
1281 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1282 result += trans->tuples_deleted;
1285 PG_RETURN_INT64(result);
1289 pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS)
1291 Oid relid = PG_GETARG_OID(0);
1293 PgStat_TableStatus *tabentry;
1295 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1298 result = (int64) (tabentry->t_counts.t_tuples_hot_updated);
1300 PG_RETURN_INT64(result);
1304 pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS)
1306 Oid relid = PG_GETARG_OID(0);
1308 PgStat_TableStatus *tabentry;
1310 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1313 result = (int64) (tabentry->t_counts.t_blocks_fetched);
1315 PG_RETURN_INT64(result);
1319 pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS)
1321 Oid relid = PG_GETARG_OID(0);
1323 PgStat_TableStatus *tabentry;
1325 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1328 result = (int64) (tabentry->t_counts.t_blocks_hit);
1330 PG_RETURN_INT64(result);
1334 pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)
1336 Oid funcid = PG_GETARG_OID(0);
1337 PgStat_BackendFunctionEntry *funcentry;
1339 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1341 PG_RETURN_INT64(funcentry->f_counts.f_numcalls);
1345 pg_stat_get_xact_function_time(PG_FUNCTION_ARGS)
1347 Oid funcid = PG_GETARG_OID(0);
1348 PgStat_BackendFunctionEntry *funcentry;
1350 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1352 PG_RETURN_INT64(INSTR_TIME_GET_MICROSEC(funcentry->f_counts.f_time));
1356 pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS)
1358 Oid funcid = PG_GETARG_OID(0);
1359 PgStat_BackendFunctionEntry *funcentry;
1361 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1363 PG_RETURN_INT64(INSTR_TIME_GET_MICROSEC(funcentry->f_counts.f_time_self));
1367 /* Discard the active statistics snapshot */
1369 pg_stat_clear_snapshot(PG_FUNCTION_ARGS)
1371 pgstat_clear_snapshot();
1377 /* Reset all counters for the current database */
1379 pg_stat_reset(PG_FUNCTION_ARGS)
1381 pgstat_reset_counters();
1386 /* Reset some shared cluster-wide counters */
1388 pg_stat_reset_shared(PG_FUNCTION_ARGS)
1390 char *target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1392 pgstat_reset_shared_counters(target);
1397 /* Reset a a single counter in the current database */
1399 pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS)
1401 Oid taboid = PG_GETARG_OID(0);
1403 pgstat_reset_single_counter(taboid, RESET_TABLE);
1409 pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS)
1411 Oid funcoid = PG_GETARG_OID(0);
1413 pgstat_reset_single_counter(funcoid, RESET_FUNCTION);