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 * $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.62 2010/08/21 10:59:17 mha Exp $
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_alloc(PG_FUNCTION_ARGS);
83 extern Datum pg_stat_get_xact_numscans(PG_FUNCTION_ARGS);
84 extern Datum pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS);
85 extern Datum pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS);
86 extern Datum pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS);
87 extern Datum pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS);
88 extern Datum pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS);
89 extern Datum pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS);
90 extern Datum pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS);
91 extern Datum pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS);
93 extern Datum pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS);
94 extern Datum pg_stat_get_xact_function_time(PG_FUNCTION_ARGS);
95 extern Datum pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS);
97 extern Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS);
98 extern Datum pg_stat_reset(PG_FUNCTION_ARGS);
99 extern Datum pg_stat_reset_shared(PG_FUNCTION_ARGS);
100 extern Datum pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS);
101 extern Datum pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS);
103 /* Global bgwriter statistics, from bgwriter.c */
104 extern PgStat_MsgBgWriter bgwriterStats;
107 pg_stat_get_numscans(PG_FUNCTION_ARGS)
109 Oid relid = PG_GETARG_OID(0);
111 PgStat_StatTabEntry *tabentry;
113 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
116 result = (int64) (tabentry->numscans);
118 PG_RETURN_INT64(result);
123 pg_stat_get_tuples_returned(PG_FUNCTION_ARGS)
125 Oid relid = PG_GETARG_OID(0);
127 PgStat_StatTabEntry *tabentry;
129 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
132 result = (int64) (tabentry->tuples_returned);
134 PG_RETURN_INT64(result);
139 pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS)
141 Oid relid = PG_GETARG_OID(0);
143 PgStat_StatTabEntry *tabentry;
145 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
148 result = (int64) (tabentry->tuples_fetched);
150 PG_RETURN_INT64(result);
155 pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS)
157 Oid relid = PG_GETARG_OID(0);
159 PgStat_StatTabEntry *tabentry;
161 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
164 result = (int64) (tabentry->tuples_inserted);
166 PG_RETURN_INT64(result);
171 pg_stat_get_tuples_updated(PG_FUNCTION_ARGS)
173 Oid relid = PG_GETARG_OID(0);
175 PgStat_StatTabEntry *tabentry;
177 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
180 result = (int64) (tabentry->tuples_updated);
182 PG_RETURN_INT64(result);
187 pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS)
189 Oid relid = PG_GETARG_OID(0);
191 PgStat_StatTabEntry *tabentry;
193 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
196 result = (int64) (tabentry->tuples_deleted);
198 PG_RETURN_INT64(result);
203 pg_stat_get_tuples_hot_updated(PG_FUNCTION_ARGS)
205 Oid relid = PG_GETARG_OID(0);
207 PgStat_StatTabEntry *tabentry;
209 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
212 result = (int64) (tabentry->tuples_hot_updated);
214 PG_RETURN_INT64(result);
219 pg_stat_get_live_tuples(PG_FUNCTION_ARGS)
221 Oid relid = PG_GETARG_OID(0);
223 PgStat_StatTabEntry *tabentry;
225 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
228 result = (int64) (tabentry->n_live_tuples);
230 PG_RETURN_INT64(result);
235 pg_stat_get_dead_tuples(PG_FUNCTION_ARGS)
237 Oid relid = PG_GETARG_OID(0);
239 PgStat_StatTabEntry *tabentry;
241 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
244 result = (int64) (tabentry->n_dead_tuples);
246 PG_RETURN_INT64(result);
251 pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS)
253 Oid relid = PG_GETARG_OID(0);
255 PgStat_StatTabEntry *tabentry;
257 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
260 result = (int64) (tabentry->blocks_fetched);
262 PG_RETURN_INT64(result);
267 pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
269 Oid relid = PG_GETARG_OID(0);
271 PgStat_StatTabEntry *tabentry;
273 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
276 result = (int64) (tabentry->blocks_hit);
278 PG_RETURN_INT64(result);
282 pg_stat_get_last_vacuum_time(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 = tabentry->vacuum_timestamp;
296 PG_RETURN_TIMESTAMPTZ(result);
300 pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS)
302 Oid relid = PG_GETARG_OID(0);
304 PgStat_StatTabEntry *tabentry;
306 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
309 result = tabentry->autovac_vacuum_timestamp;
314 PG_RETURN_TIMESTAMPTZ(result);
318 pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS)
320 Oid relid = PG_GETARG_OID(0);
322 PgStat_StatTabEntry *tabentry;
324 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
327 result = tabentry->analyze_timestamp;
332 PG_RETURN_TIMESTAMPTZ(result);
336 pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS)
338 Oid relid = PG_GETARG_OID(0);
340 PgStat_StatTabEntry *tabentry;
342 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
345 result = tabentry->autovac_analyze_timestamp;
350 PG_RETURN_TIMESTAMPTZ(result);
354 pg_stat_get_vacuum_count(PG_FUNCTION_ARGS)
356 Oid relid = PG_GETARG_OID(0);
358 PgStat_StatTabEntry *tabentry;
360 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
363 result = (int64) (tabentry->vacuum_count);
365 PG_RETURN_INT64(result);
369 pg_stat_get_autovacuum_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->autovac_vacuum_count);
380 PG_RETURN_INT64(result);
384 pg_stat_get_analyze_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->analyze_count);
395 PG_RETURN_INT64(result);
399 pg_stat_get_autoanalyze_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->autovac_analyze_count);
410 PG_RETURN_INT64(result);
414 pg_stat_get_function_calls(PG_FUNCTION_ARGS)
416 Oid funcid = PG_GETARG_OID(0);
417 PgStat_StatFuncEntry *funcentry;
419 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
421 PG_RETURN_INT64(funcentry->f_numcalls);
425 pg_stat_get_function_time(PG_FUNCTION_ARGS)
427 Oid funcid = PG_GETARG_OID(0);
428 PgStat_StatFuncEntry *funcentry;
430 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
432 PG_RETURN_INT64(funcentry->f_time);
436 pg_stat_get_function_self_time(PG_FUNCTION_ARGS)
438 Oid funcid = PG_GETARG_OID(0);
439 PgStat_StatFuncEntry *funcentry;
441 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
443 PG_RETURN_INT64(funcentry->f_time_self);
447 pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
449 FuncCallContext *funcctx;
453 /* stuff done only on the first call of the function */
454 if (SRF_IS_FIRSTCALL())
456 /* create a function context for cross-call persistence */
457 funcctx = SRF_FIRSTCALL_INIT();
459 fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
461 funcctx->user_fctx = fctx;
464 fctx[1] = pgstat_fetch_stat_numbackends();
467 /* stuff done on every call of the function */
468 funcctx = SRF_PERCALL_SETUP();
469 fctx = funcctx->user_fctx;
474 if (result <= fctx[1])
476 /* do when there is more left to send */
477 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
481 /* do when there is no more left */
482 SRF_RETURN_DONE(funcctx);
487 pg_stat_get_activity(PG_FUNCTION_ARGS)
489 FuncCallContext *funcctx;
491 if (SRF_IS_FIRSTCALL())
493 MemoryContext oldcontext;
496 funcctx = SRF_FIRSTCALL_INIT();
498 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
500 tupdesc = CreateTemplateTupleDesc(11, false);
501 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "datid", OIDOID, -1, 0);
502 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "procpid", INT4OID, -1, 0);
503 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "usesysid", OIDOID, -1, 0);
504 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "application_name", TEXTOID, -1, 0);
505 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "current_query", TEXTOID, -1, 0);
506 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "waiting", BOOLOID, -1, 0);
507 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "act_start", TIMESTAMPTZOID, -1, 0);
508 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "query_start", TIMESTAMPTZOID, -1, 0);
509 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "backend_start", TIMESTAMPTZOID, -1, 0);
510 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "client_addr", INETOID, -1, 0);
511 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "client_port", INT4OID, -1, 0);
513 funcctx->tuple_desc = BlessTupleDesc(tupdesc);
515 funcctx->user_fctx = palloc0(sizeof(int));
518 /* Get all backends */
519 funcctx->max_calls = pgstat_fetch_stat_numbackends();
524 * Get one backend - locate by pid.
526 * We lookup the backend early, so we can return zero rows if it
527 * doesn't exist, instead of returning a single row full of NULLs.
529 int pid = PG_GETARG_INT32(0);
531 int n = pgstat_fetch_stat_numbackends();
533 for (i = 1; i <= n; i++)
535 PgBackendStatus *be = pgstat_fetch_stat_beentry(i);
539 if (be->st_procpid == pid)
541 *(int *) (funcctx->user_fctx) = i;
547 if (*(int *) (funcctx->user_fctx) == 0)
548 /* Pid not found, return zero rows */
549 funcctx->max_calls = 0;
551 funcctx->max_calls = 1;
554 MemoryContextSwitchTo(oldcontext);
557 /* stuff done on every call of the function */
558 funcctx = SRF_PERCALL_SETUP();
560 if (funcctx->call_cntr < funcctx->max_calls)
566 PgBackendStatus *beentry;
567 SockAddr zero_clientaddr;
569 MemSet(values, 0, sizeof(values));
570 MemSet(nulls, 0, sizeof(nulls));
572 if (*(int *) (funcctx->user_fctx) > 0)
574 /* Get specific pid slot */
575 beentry = pgstat_fetch_stat_beentry(*(int *) (funcctx->user_fctx));
579 /* Get the next one in the list */
580 beentry = pgstat_fetch_stat_beentry(funcctx->call_cntr + 1); /* 1-based index */
586 for (i = 0; i < sizeof(nulls) / sizeof(nulls[0]); i++)
590 values[4] = CStringGetTextDatum("<backend information not available>");
592 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
593 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
596 /* Values available to all callers */
597 values[0] = ObjectIdGetDatum(beentry->st_databaseid);
598 values[1] = Int32GetDatum(beentry->st_procpid);
599 values[2] = ObjectIdGetDatum(beentry->st_userid);
600 if (beentry->st_appname)
601 values[3] = CStringGetTextDatum(beentry->st_appname);
605 /* Values only available to same user or superuser */
606 if (superuser() || beentry->st_userid == GetUserId())
608 if (*(beentry->st_activity) == '\0')
610 values[4] = CStringGetTextDatum("<command string not enabled>");
614 values[4] = CStringGetTextDatum(beentry->st_activity);
617 values[5] = BoolGetDatum(beentry->st_waiting);
619 if (beentry->st_xact_start_timestamp != 0)
620 values[6] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
624 if (beentry->st_activity_start_timestamp != 0)
625 values[7] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
629 if (beentry->st_proc_start_timestamp != 0)
630 values[8] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
634 /* A zeroed client addr means we don't know */
635 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
636 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
637 sizeof(zero_clientaddr) == 0))
644 if (beentry->st_clientaddr.addr.ss_family == AF_INET
646 || beentry->st_clientaddr.addr.ss_family == AF_INET6
650 char remote_host[NI_MAXHOST];
651 char remote_port[NI_MAXSERV];
654 remote_host[0] = '\0';
655 remote_port[0] = '\0';
656 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
657 beentry->st_clientaddr.salen,
658 remote_host, sizeof(remote_host),
659 remote_port, sizeof(remote_port),
660 NI_NUMERICHOST | NI_NUMERICSERV);
668 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
669 values[9] = DirectFunctionCall1(inet_in,
670 CStringGetDatum(remote_host));
671 values[10] = Int32GetDatum(atoi(remote_port));
674 else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
677 * Unix sockets always reports NULL for host and -1 for
678 * port, so it's possible to tell the difference to
679 * connections we have no permissions to view, or with
683 values[10] = DatumGetInt32(-1);
687 /* Unknown address type, should never happen */
695 /* No permissions to view data about this session */
696 values[4] = CStringGetTextDatum("<insufficient privilege>");
705 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
707 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
712 SRF_RETURN_DONE(funcctx);
718 pg_backend_pid(PG_FUNCTION_ARGS)
720 PG_RETURN_INT32(MyProcPid);
725 pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
727 int32 beid = PG_GETARG_INT32(0);
728 PgBackendStatus *beentry;
730 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
733 PG_RETURN_INT32(beentry->st_procpid);
738 pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
740 int32 beid = PG_GETARG_INT32(0);
741 PgBackendStatus *beentry;
743 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
746 PG_RETURN_OID(beentry->st_databaseid);
751 pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
753 int32 beid = PG_GETARG_INT32(0);
754 PgBackendStatus *beentry;
756 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
759 PG_RETURN_OID(beentry->st_userid);
764 pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
766 int32 beid = PG_GETARG_INT32(0);
767 PgBackendStatus *beentry;
768 const char *activity;
770 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
771 activity = "<backend information not available>";
772 else if (!superuser() && beentry->st_userid != GetUserId())
773 activity = "<insufficient privilege>";
774 else if (*(beentry->st_activity) == '\0')
775 activity = "<command string not enabled>";
777 activity = beentry->st_activity;
779 PG_RETURN_TEXT_P(cstring_to_text(activity));
784 pg_stat_get_backend_waiting(PG_FUNCTION_ARGS)
786 int32 beid = PG_GETARG_INT32(0);
788 PgBackendStatus *beentry;
790 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
793 if (!superuser() && beentry->st_userid != GetUserId())
796 result = beentry->st_waiting;
798 PG_RETURN_BOOL(result);
803 pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
805 int32 beid = PG_GETARG_INT32(0);
807 PgBackendStatus *beentry;
809 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
812 if (!superuser() && beentry->st_userid != GetUserId())
815 result = beentry->st_activity_start_timestamp;
818 * No time recorded for start of current query -- this is the case if the
819 * user hasn't enabled query-level stats collection.
824 PG_RETURN_TIMESTAMPTZ(result);
829 pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
831 int32 beid = PG_GETARG_INT32(0);
833 PgBackendStatus *beentry;
835 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
838 if (!superuser() && beentry->st_userid != GetUserId())
841 result = beentry->st_xact_start_timestamp;
843 if (result == 0) /* not in a transaction */
846 PG_RETURN_TIMESTAMPTZ(result);
851 pg_stat_get_backend_start(PG_FUNCTION_ARGS)
853 int32 beid = PG_GETARG_INT32(0);
855 PgBackendStatus *beentry;
857 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
860 if (!superuser() && beentry->st_userid != GetUserId())
863 result = beentry->st_proc_start_timestamp;
865 if (result == 0) /* probably can't happen? */
868 PG_RETURN_TIMESTAMPTZ(result);
873 pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
875 int32 beid = PG_GETARG_INT32(0);
876 PgBackendStatus *beentry;
877 SockAddr zero_clientaddr;
878 char remote_host[NI_MAXHOST];
881 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
884 if (!superuser() && beentry->st_userid != GetUserId())
887 /* A zeroed client addr means we don't know */
888 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
889 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
890 sizeof(zero_clientaddr) == 0))
893 switch (beentry->st_clientaddr.addr.ss_family)
904 remote_host[0] = '\0';
905 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
906 beentry->st_clientaddr.salen,
907 remote_host, sizeof(remote_host),
909 NI_NUMERICHOST | NI_NUMERICSERV);
913 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
915 PG_RETURN_INET_P(DirectFunctionCall1(inet_in,
916 CStringGetDatum(remote_host)));
920 pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
922 int32 beid = PG_GETARG_INT32(0);
923 PgBackendStatus *beentry;
924 SockAddr zero_clientaddr;
925 char remote_port[NI_MAXSERV];
928 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
931 if (!superuser() && beentry->st_userid != GetUserId())
934 /* A zeroed client addr means we don't know */
935 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
936 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
937 sizeof(zero_clientaddr) == 0))
940 switch (beentry->st_clientaddr.addr.ss_family)
953 remote_port[0] = '\0';
954 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
955 beentry->st_clientaddr.salen,
957 remote_port, sizeof(remote_port),
958 NI_NUMERICHOST | NI_NUMERICSERV);
962 PG_RETURN_DATUM(DirectFunctionCall1(int4in,
963 CStringGetDatum(remote_port)));
968 pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
970 Oid dbid = PG_GETARG_OID(0);
972 int tot_backends = pgstat_fetch_stat_numbackends();
976 for (beid = 1; beid <= tot_backends; beid++)
978 PgBackendStatus *beentry = pgstat_fetch_stat_beentry(beid);
980 if (beentry && beentry->st_databaseid == dbid)
984 PG_RETURN_INT32(result);
989 pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS)
991 Oid dbid = PG_GETARG_OID(0);
993 PgStat_StatDBEntry *dbentry;
995 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
998 result = (int64) (dbentry->n_xact_commit);
1000 PG_RETURN_INT64(result);
1005 pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS)
1007 Oid dbid = PG_GETARG_OID(0);
1009 PgStat_StatDBEntry *dbentry;
1011 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1014 result = (int64) (dbentry->n_xact_rollback);
1016 PG_RETURN_INT64(result);
1021 pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS)
1023 Oid dbid = PG_GETARG_OID(0);
1025 PgStat_StatDBEntry *dbentry;
1027 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1030 result = (int64) (dbentry->n_blocks_fetched);
1032 PG_RETURN_INT64(result);
1037 pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS)
1039 Oid dbid = PG_GETARG_OID(0);
1041 PgStat_StatDBEntry *dbentry;
1043 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1046 result = (int64) (dbentry->n_blocks_hit);
1048 PG_RETURN_INT64(result);
1053 pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS)
1055 Oid dbid = PG_GETARG_OID(0);
1057 PgStat_StatDBEntry *dbentry;
1059 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1062 result = (int64) (dbentry->n_tuples_returned);
1064 PG_RETURN_INT64(result);
1069 pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS)
1071 Oid dbid = PG_GETARG_OID(0);
1073 PgStat_StatDBEntry *dbentry;
1075 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1078 result = (int64) (dbentry->n_tuples_fetched);
1080 PG_RETURN_INT64(result);
1085 pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS)
1087 Oid dbid = PG_GETARG_OID(0);
1089 PgStat_StatDBEntry *dbentry;
1091 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1094 result = (int64) (dbentry->n_tuples_inserted);
1096 PG_RETURN_INT64(result);
1101 pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS)
1103 Oid dbid = PG_GETARG_OID(0);
1105 PgStat_StatDBEntry *dbentry;
1107 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1110 result = (int64) (dbentry->n_tuples_updated);
1112 PG_RETURN_INT64(result);
1117 pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS)
1119 Oid dbid = PG_GETARG_OID(0);
1121 PgStat_StatDBEntry *dbentry;
1123 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1126 result = (int64) (dbentry->n_tuples_deleted);
1128 PG_RETURN_INT64(result);
1132 pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS)
1134 PG_RETURN_INT64(pgstat_fetch_global()->timed_checkpoints);
1138 pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS)
1140 PG_RETURN_INT64(pgstat_fetch_global()->requested_checkpoints);
1144 pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS)
1146 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_checkpoints);
1150 pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
1152 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_clean);
1156 pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS)
1158 PG_RETURN_INT64(pgstat_fetch_global()->maxwritten_clean);
1162 pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS)
1164 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_backend);
1168 pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
1170 PG_RETURN_INT64(pgstat_fetch_global()->buf_alloc);
1174 pg_stat_get_xact_numscans(PG_FUNCTION_ARGS)
1176 Oid relid = PG_GETARG_OID(0);
1178 PgStat_TableStatus *tabentry;
1180 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1183 result = (int64) (tabentry->t_counts.t_numscans);
1185 PG_RETURN_INT64(result);
1189 pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS)
1191 Oid relid = PG_GETARG_OID(0);
1193 PgStat_TableStatus *tabentry;
1195 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1198 result = (int64) (tabentry->t_counts.t_tuples_returned);
1200 PG_RETURN_INT64(result);
1204 pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS)
1206 Oid relid = PG_GETARG_OID(0);
1208 PgStat_TableStatus *tabentry;
1210 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1213 result = (int64) (tabentry->t_counts.t_tuples_fetched);
1215 PG_RETURN_INT64(result);
1219 pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS)
1221 Oid relid = PG_GETARG_OID(0);
1223 PgStat_TableStatus *tabentry;
1224 PgStat_TableXactStatus *trans;
1226 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1230 result = tabentry->t_counts.t_tuples_inserted;
1231 /* live subtransactions' counts aren't in t_tuples_inserted yet */
1232 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1233 result += trans->tuples_inserted;
1236 PG_RETURN_INT64(result);
1240 pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS)
1242 Oid relid = PG_GETARG_OID(0);
1244 PgStat_TableStatus *tabentry;
1245 PgStat_TableXactStatus *trans;
1247 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1251 result = tabentry->t_counts.t_tuples_updated;
1252 /* live subtransactions' counts aren't in t_tuples_updated yet */
1253 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1254 result += trans->tuples_updated;
1257 PG_RETURN_INT64(result);
1261 pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS)
1263 Oid relid = PG_GETARG_OID(0);
1265 PgStat_TableStatus *tabentry;
1266 PgStat_TableXactStatus *trans;
1268 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1272 result = tabentry->t_counts.t_tuples_deleted;
1273 /* live subtransactions' counts aren't in t_tuples_deleted yet */
1274 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1275 result += trans->tuples_deleted;
1278 PG_RETURN_INT64(result);
1282 pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS)
1284 Oid relid = PG_GETARG_OID(0);
1286 PgStat_TableStatus *tabentry;
1288 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1291 result = (int64) (tabentry->t_counts.t_tuples_hot_updated);
1293 PG_RETURN_INT64(result);
1297 pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS)
1299 Oid relid = PG_GETARG_OID(0);
1301 PgStat_TableStatus *tabentry;
1303 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1306 result = (int64) (tabentry->t_counts.t_blocks_fetched);
1308 PG_RETURN_INT64(result);
1312 pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS)
1314 Oid relid = PG_GETARG_OID(0);
1316 PgStat_TableStatus *tabentry;
1318 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1321 result = (int64) (tabentry->t_counts.t_blocks_hit);
1323 PG_RETURN_INT64(result);
1327 pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)
1329 Oid funcid = PG_GETARG_OID(0);
1330 PgStat_BackendFunctionEntry *funcentry;
1332 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1334 PG_RETURN_INT64(funcentry->f_counts.f_numcalls);
1338 pg_stat_get_xact_function_time(PG_FUNCTION_ARGS)
1340 Oid funcid = PG_GETARG_OID(0);
1341 PgStat_BackendFunctionEntry *funcentry;
1343 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1345 PG_RETURN_INT64(INSTR_TIME_GET_MICROSEC(funcentry->f_counts.f_time));
1349 pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS)
1351 Oid funcid = PG_GETARG_OID(0);
1352 PgStat_BackendFunctionEntry *funcentry;
1354 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1356 PG_RETURN_INT64(INSTR_TIME_GET_MICROSEC(funcentry->f_counts.f_time_self));
1360 /* Discard the active statistics snapshot */
1362 pg_stat_clear_snapshot(PG_FUNCTION_ARGS)
1364 pgstat_clear_snapshot();
1370 /* Reset all counters for the current database */
1372 pg_stat_reset(PG_FUNCTION_ARGS)
1374 pgstat_reset_counters();
1379 /* Reset some shared cluster-wide counters */
1381 pg_stat_reset_shared(PG_FUNCTION_ARGS)
1383 char *target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1385 pgstat_reset_shared_counters(target);
1390 /* Reset a a single counter in the current database */
1392 pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS)
1394 Oid taboid = PG_GETARG_OID(0);
1396 pgstat_reset_single_counter(taboid, RESET_TABLE);
1402 pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS)
1404 Oid funcoid = PG_GETARG_OID(0);
1406 pgstat_reset_single_counter(funcoid, RESET_FUNCTION);