1 /*-------------------------------------------------------------------------
4 * Functions for accessing the statistics collector data
6 * Portions Copyright (c) 1996-2011, 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);
74 extern Datum pg_stat_get_db_conflict_tablespace(PG_FUNCTION_ARGS);
75 extern Datum pg_stat_get_db_conflict_lock(PG_FUNCTION_ARGS);
76 extern Datum pg_stat_get_db_conflict_snapshot(PG_FUNCTION_ARGS);
77 extern Datum pg_stat_get_db_conflict_bufferpin(PG_FUNCTION_ARGS);
78 extern Datum pg_stat_get_db_conflict_startup_deadlock(PG_FUNCTION_ARGS);
79 extern Datum pg_stat_get_db_conflict_all(PG_FUNCTION_ARGS);
80 extern Datum pg_stat_get_db_stat_reset_time(PG_FUNCTION_ARGS);
82 extern Datum pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS);
83 extern Datum pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS);
84 extern Datum pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS);
85 extern Datum pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS);
86 extern Datum pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS);
87 extern Datum pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS);
88 extern Datum pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS);
89 extern Datum pg_stat_get_buf_fsync_backend(PG_FUNCTION_ARGS);
90 extern Datum pg_stat_get_buf_alloc(PG_FUNCTION_ARGS);
92 extern Datum pg_stat_get_xact_numscans(PG_FUNCTION_ARGS);
93 extern Datum pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS);
94 extern Datum pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS);
95 extern Datum pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS);
96 extern Datum pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS);
97 extern Datum pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS);
98 extern Datum pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS);
99 extern Datum pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS);
100 extern Datum pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS);
102 extern Datum pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS);
103 extern Datum pg_stat_get_xact_function_time(PG_FUNCTION_ARGS);
104 extern Datum pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS);
106 extern Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS);
107 extern Datum pg_stat_reset(PG_FUNCTION_ARGS);
108 extern Datum pg_stat_reset_shared(PG_FUNCTION_ARGS);
109 extern Datum pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS);
110 extern Datum pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS);
112 /* Global bgwriter statistics, from bgwriter.c */
113 extern PgStat_MsgBgWriter bgwriterStats;
116 pg_stat_get_numscans(PG_FUNCTION_ARGS)
118 Oid relid = PG_GETARG_OID(0);
120 PgStat_StatTabEntry *tabentry;
122 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
125 result = (int64) (tabentry->numscans);
127 PG_RETURN_INT64(result);
132 pg_stat_get_tuples_returned(PG_FUNCTION_ARGS)
134 Oid relid = PG_GETARG_OID(0);
136 PgStat_StatTabEntry *tabentry;
138 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
141 result = (int64) (tabentry->tuples_returned);
143 PG_RETURN_INT64(result);
148 pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS)
150 Oid relid = PG_GETARG_OID(0);
152 PgStat_StatTabEntry *tabentry;
154 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
157 result = (int64) (tabentry->tuples_fetched);
159 PG_RETURN_INT64(result);
164 pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS)
166 Oid relid = PG_GETARG_OID(0);
168 PgStat_StatTabEntry *tabentry;
170 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
173 result = (int64) (tabentry->tuples_inserted);
175 PG_RETURN_INT64(result);
180 pg_stat_get_tuples_updated(PG_FUNCTION_ARGS)
182 Oid relid = PG_GETARG_OID(0);
184 PgStat_StatTabEntry *tabentry;
186 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
189 result = (int64) (tabentry->tuples_updated);
191 PG_RETURN_INT64(result);
196 pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS)
198 Oid relid = PG_GETARG_OID(0);
200 PgStat_StatTabEntry *tabentry;
202 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
205 result = (int64) (tabentry->tuples_deleted);
207 PG_RETURN_INT64(result);
212 pg_stat_get_tuples_hot_updated(PG_FUNCTION_ARGS)
214 Oid relid = PG_GETARG_OID(0);
216 PgStat_StatTabEntry *tabentry;
218 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
221 result = (int64) (tabentry->tuples_hot_updated);
223 PG_RETURN_INT64(result);
228 pg_stat_get_live_tuples(PG_FUNCTION_ARGS)
230 Oid relid = PG_GETARG_OID(0);
232 PgStat_StatTabEntry *tabentry;
234 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
237 result = (int64) (tabentry->n_live_tuples);
239 PG_RETURN_INT64(result);
244 pg_stat_get_dead_tuples(PG_FUNCTION_ARGS)
246 Oid relid = PG_GETARG_OID(0);
248 PgStat_StatTabEntry *tabentry;
250 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
253 result = (int64) (tabentry->n_dead_tuples);
255 PG_RETURN_INT64(result);
260 pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS)
262 Oid relid = PG_GETARG_OID(0);
264 PgStat_StatTabEntry *tabentry;
266 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
269 result = (int64) (tabentry->blocks_fetched);
271 PG_RETURN_INT64(result);
276 pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
278 Oid relid = PG_GETARG_OID(0);
280 PgStat_StatTabEntry *tabentry;
282 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
285 result = (int64) (tabentry->blocks_hit);
287 PG_RETURN_INT64(result);
291 pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS)
293 Oid relid = PG_GETARG_OID(0);
295 PgStat_StatTabEntry *tabentry;
297 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
300 result = tabentry->vacuum_timestamp;
305 PG_RETURN_TIMESTAMPTZ(result);
309 pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS)
311 Oid relid = PG_GETARG_OID(0);
313 PgStat_StatTabEntry *tabentry;
315 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
318 result = tabentry->autovac_vacuum_timestamp;
323 PG_RETURN_TIMESTAMPTZ(result);
327 pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS)
329 Oid relid = PG_GETARG_OID(0);
331 PgStat_StatTabEntry *tabentry;
333 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
336 result = tabentry->analyze_timestamp;
341 PG_RETURN_TIMESTAMPTZ(result);
345 pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS)
347 Oid relid = PG_GETARG_OID(0);
349 PgStat_StatTabEntry *tabentry;
351 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
354 result = tabentry->autovac_analyze_timestamp;
359 PG_RETURN_TIMESTAMPTZ(result);
363 pg_stat_get_vacuum_count(PG_FUNCTION_ARGS)
365 Oid relid = PG_GETARG_OID(0);
367 PgStat_StatTabEntry *tabentry;
369 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
372 result = (int64) (tabentry->vacuum_count);
374 PG_RETURN_INT64(result);
378 pg_stat_get_autovacuum_count(PG_FUNCTION_ARGS)
380 Oid relid = PG_GETARG_OID(0);
382 PgStat_StatTabEntry *tabentry;
384 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
387 result = (int64) (tabentry->autovac_vacuum_count);
389 PG_RETURN_INT64(result);
393 pg_stat_get_analyze_count(PG_FUNCTION_ARGS)
395 Oid relid = PG_GETARG_OID(0);
397 PgStat_StatTabEntry *tabentry;
399 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
402 result = (int64) (tabentry->analyze_count);
404 PG_RETURN_INT64(result);
408 pg_stat_get_autoanalyze_count(PG_FUNCTION_ARGS)
410 Oid relid = PG_GETARG_OID(0);
412 PgStat_StatTabEntry *tabentry;
414 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
417 result = (int64) (tabentry->autovac_analyze_count);
419 PG_RETURN_INT64(result);
423 pg_stat_get_function_calls(PG_FUNCTION_ARGS)
425 Oid funcid = PG_GETARG_OID(0);
426 PgStat_StatFuncEntry *funcentry;
428 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
430 PG_RETURN_INT64(funcentry->f_numcalls);
434 pg_stat_get_function_time(PG_FUNCTION_ARGS)
436 Oid funcid = PG_GETARG_OID(0);
437 PgStat_StatFuncEntry *funcentry;
439 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
441 PG_RETURN_INT64(funcentry->f_time);
445 pg_stat_get_function_self_time(PG_FUNCTION_ARGS)
447 Oid funcid = PG_GETARG_OID(0);
448 PgStat_StatFuncEntry *funcentry;
450 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
452 PG_RETURN_INT64(funcentry->f_time_self);
456 pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
458 FuncCallContext *funcctx;
462 /* stuff done only on the first call of the function */
463 if (SRF_IS_FIRSTCALL())
465 /* create a function context for cross-call persistence */
466 funcctx = SRF_FIRSTCALL_INIT();
468 fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
470 funcctx->user_fctx = fctx;
473 fctx[1] = pgstat_fetch_stat_numbackends();
476 /* stuff done on every call of the function */
477 funcctx = SRF_PERCALL_SETUP();
478 fctx = funcctx->user_fctx;
483 if (result <= fctx[1])
485 /* do when there is more left to send */
486 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
490 /* do when there is no more left */
491 SRF_RETURN_DONE(funcctx);
496 pg_stat_get_activity(PG_FUNCTION_ARGS)
498 FuncCallContext *funcctx;
500 if (SRF_IS_FIRSTCALL())
502 MemoryContext oldcontext;
505 funcctx = SRF_FIRSTCALL_INIT();
507 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
509 tupdesc = CreateTemplateTupleDesc(12, false);
510 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "datid",
512 /* This should have been called 'pid'; can't change it. 2011-06-11 */
513 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "procpid",
515 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "usesysid",
517 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "application_name",
519 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "current_query",
521 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "waiting",
523 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "act_start",
524 TIMESTAMPTZOID, -1, 0);
525 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "query_start",
526 TIMESTAMPTZOID, -1, 0);
527 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "backend_start",
528 TIMESTAMPTZOID, -1, 0);
529 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "client_addr",
531 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "client_hostname",
533 TupleDescInitEntry(tupdesc, (AttrNumber) 12, "client_port",
536 funcctx->tuple_desc = BlessTupleDesc(tupdesc);
538 funcctx->user_fctx = palloc0(sizeof(int));
541 /* Get all backends */
542 funcctx->max_calls = pgstat_fetch_stat_numbackends();
547 * Get one backend - locate by pid.
549 * We lookup the backend early, so we can return zero rows if it
550 * doesn't exist, instead of returning a single row full of NULLs.
552 int pid = PG_GETARG_INT32(0);
554 int n = pgstat_fetch_stat_numbackends();
556 for (i = 1; i <= n; i++)
558 PgBackendStatus *be = pgstat_fetch_stat_beentry(i);
562 if (be->st_procpid == pid)
564 *(int *) (funcctx->user_fctx) = i;
570 if (*(int *) (funcctx->user_fctx) == 0)
571 /* Pid not found, return zero rows */
572 funcctx->max_calls = 0;
574 funcctx->max_calls = 1;
577 MemoryContextSwitchTo(oldcontext);
580 /* stuff done on every call of the function */
581 funcctx = SRF_PERCALL_SETUP();
583 if (funcctx->call_cntr < funcctx->max_calls)
589 PgBackendStatus *beentry;
590 SockAddr zero_clientaddr;
592 MemSet(values, 0, sizeof(values));
593 MemSet(nulls, 0, sizeof(nulls));
595 if (*(int *) (funcctx->user_fctx) > 0)
597 /* Get specific pid slot */
598 beentry = pgstat_fetch_stat_beentry(*(int *) (funcctx->user_fctx));
602 /* Get the next one in the list */
603 beentry = pgstat_fetch_stat_beentry(funcctx->call_cntr + 1); /* 1-based index */
609 for (i = 0; i < sizeof(nulls) / sizeof(nulls[0]); i++)
613 values[4] = CStringGetTextDatum("<backend information not available>");
615 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
616 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
619 /* Values available to all callers */
620 values[0] = ObjectIdGetDatum(beentry->st_databaseid);
621 values[1] = Int32GetDatum(beentry->st_procpid);
622 values[2] = ObjectIdGetDatum(beentry->st_userid);
623 if (beentry->st_appname)
624 values[3] = CStringGetTextDatum(beentry->st_appname);
628 /* Values only available to same user or superuser */
629 if (superuser() || beentry->st_userid == GetUserId())
631 if (*(beentry->st_activity) == '\0')
633 values[4] = CStringGetTextDatum("<command string not enabled>");
637 values[4] = CStringGetTextDatum(beentry->st_activity);
640 values[5] = BoolGetDatum(beentry->st_waiting);
642 if (beentry->st_xact_start_timestamp != 0)
643 values[6] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
647 if (beentry->st_activity_start_timestamp != 0)
648 values[7] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
652 if (beentry->st_proc_start_timestamp != 0)
653 values[8] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
657 /* A zeroed client addr means we don't know */
658 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
659 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
660 sizeof(zero_clientaddr) == 0))
668 if (beentry->st_clientaddr.addr.ss_family == AF_INET
670 || beentry->st_clientaddr.addr.ss_family == AF_INET6
674 char remote_host[NI_MAXHOST];
675 char remote_port[NI_MAXSERV];
678 remote_host[0] = '\0';
679 remote_port[0] = '\0';
680 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
681 beentry->st_clientaddr.salen,
682 remote_host, sizeof(remote_host),
683 remote_port, sizeof(remote_port),
684 NI_NUMERICHOST | NI_NUMERICSERV);
693 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
694 values[9] = DirectFunctionCall1(inet_in,
695 CStringGetDatum(remote_host));
696 if (beentry->st_clienthostname)
697 values[10] = CStringGetTextDatum(beentry->st_clienthostname);
700 values[11] = Int32GetDatum(atoi(remote_port));
703 else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
706 * Unix sockets always reports NULL for host and -1 for
707 * port, so it's possible to tell the difference to
708 * connections we have no permissions to view, or with
713 values[11] = DatumGetInt32(-1);
717 /* Unknown address type, should never happen */
726 /* No permissions to view data about this session */
727 values[4] = CStringGetTextDatum("<insufficient privilege>");
737 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
739 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
744 SRF_RETURN_DONE(funcctx);
750 pg_backend_pid(PG_FUNCTION_ARGS)
752 PG_RETURN_INT32(MyProcPid);
757 pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
759 int32 beid = PG_GETARG_INT32(0);
760 PgBackendStatus *beentry;
762 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
765 PG_RETURN_INT32(beentry->st_procpid);
770 pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
772 int32 beid = PG_GETARG_INT32(0);
773 PgBackendStatus *beentry;
775 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
778 PG_RETURN_OID(beentry->st_databaseid);
783 pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
785 int32 beid = PG_GETARG_INT32(0);
786 PgBackendStatus *beentry;
788 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
791 PG_RETURN_OID(beentry->st_userid);
796 pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
798 int32 beid = PG_GETARG_INT32(0);
799 PgBackendStatus *beentry;
800 const char *activity;
802 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
803 activity = "<backend information not available>";
804 else if (!superuser() && beentry->st_userid != GetUserId())
805 activity = "<insufficient privilege>";
806 else if (*(beentry->st_activity) == '\0')
807 activity = "<command string not enabled>";
809 activity = beentry->st_activity;
811 PG_RETURN_TEXT_P(cstring_to_text(activity));
816 pg_stat_get_backend_waiting(PG_FUNCTION_ARGS)
818 int32 beid = PG_GETARG_INT32(0);
820 PgBackendStatus *beentry;
822 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
825 if (!superuser() && beentry->st_userid != GetUserId())
828 result = beentry->st_waiting;
830 PG_RETURN_BOOL(result);
835 pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
837 int32 beid = PG_GETARG_INT32(0);
839 PgBackendStatus *beentry;
841 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
844 if (!superuser() && beentry->st_userid != GetUserId())
847 result = beentry->st_activity_start_timestamp;
850 * No time recorded for start of current query -- this is the case if the
851 * user hasn't enabled query-level stats collection.
856 PG_RETURN_TIMESTAMPTZ(result);
861 pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
863 int32 beid = PG_GETARG_INT32(0);
865 PgBackendStatus *beentry;
867 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
870 if (!superuser() && beentry->st_userid != GetUserId())
873 result = beentry->st_xact_start_timestamp;
875 if (result == 0) /* not in a transaction */
878 PG_RETURN_TIMESTAMPTZ(result);
883 pg_stat_get_backend_start(PG_FUNCTION_ARGS)
885 int32 beid = PG_GETARG_INT32(0);
887 PgBackendStatus *beentry;
889 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
892 if (!superuser() && beentry->st_userid != GetUserId())
895 result = beentry->st_proc_start_timestamp;
897 if (result == 0) /* probably can't happen? */
900 PG_RETURN_TIMESTAMPTZ(result);
905 pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
907 int32 beid = PG_GETARG_INT32(0);
908 PgBackendStatus *beentry;
909 SockAddr zero_clientaddr;
910 char remote_host[NI_MAXHOST];
913 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
916 if (!superuser() && beentry->st_userid != GetUserId())
919 /* A zeroed client addr means we don't know */
920 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
921 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
922 sizeof(zero_clientaddr) == 0))
925 switch (beentry->st_clientaddr.addr.ss_family)
936 remote_host[0] = '\0';
937 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
938 beentry->st_clientaddr.salen,
939 remote_host, sizeof(remote_host),
941 NI_NUMERICHOST | NI_NUMERICSERV);
945 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
947 PG_RETURN_INET_P(DirectFunctionCall1(inet_in,
948 CStringGetDatum(remote_host)));
952 pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
954 int32 beid = PG_GETARG_INT32(0);
955 PgBackendStatus *beentry;
956 SockAddr zero_clientaddr;
957 char remote_port[NI_MAXSERV];
960 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
963 if (!superuser() && beentry->st_userid != GetUserId())
966 /* A zeroed client addr means we don't know */
967 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
968 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
969 sizeof(zero_clientaddr) == 0))
972 switch (beentry->st_clientaddr.addr.ss_family)
985 remote_port[0] = '\0';
986 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
987 beentry->st_clientaddr.salen,
989 remote_port, sizeof(remote_port),
990 NI_NUMERICHOST | NI_NUMERICSERV);
994 PG_RETURN_DATUM(DirectFunctionCall1(int4in,
995 CStringGetDatum(remote_port)));
1000 pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
1002 Oid dbid = PG_GETARG_OID(0);
1004 int tot_backends = pgstat_fetch_stat_numbackends();
1008 for (beid = 1; beid <= tot_backends; beid++)
1010 PgBackendStatus *beentry = pgstat_fetch_stat_beentry(beid);
1012 if (beentry && beentry->st_databaseid == dbid)
1016 PG_RETURN_INT32(result);
1021 pg_stat_get_db_xact_commit(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_xact_commit);
1032 PG_RETURN_INT64(result);
1037 pg_stat_get_db_xact_rollback(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_xact_rollback);
1048 PG_RETURN_INT64(result);
1053 pg_stat_get_db_blocks_fetched(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_blocks_fetched);
1064 PG_RETURN_INT64(result);
1069 pg_stat_get_db_blocks_hit(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_blocks_hit);
1080 PG_RETURN_INT64(result);
1085 pg_stat_get_db_tuples_returned(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_returned);
1096 PG_RETURN_INT64(result);
1101 pg_stat_get_db_tuples_fetched(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_fetched);
1112 PG_RETURN_INT64(result);
1117 pg_stat_get_db_tuples_inserted(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_inserted);
1128 PG_RETURN_INT64(result);
1133 pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS)
1135 Oid dbid = PG_GETARG_OID(0);
1137 PgStat_StatDBEntry *dbentry;
1139 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1142 result = (int64) (dbentry->n_tuples_updated);
1144 PG_RETURN_INT64(result);
1149 pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS)
1151 Oid dbid = PG_GETARG_OID(0);
1153 PgStat_StatDBEntry *dbentry;
1155 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1158 result = (int64) (dbentry->n_tuples_deleted);
1160 PG_RETURN_INT64(result);
1164 pg_stat_get_db_stat_reset_time(PG_FUNCTION_ARGS)
1166 Oid dbid = PG_GETARG_OID(0);
1168 PgStat_StatDBEntry *dbentry;
1170 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1173 result = dbentry->stat_reset_timestamp;
1178 PG_RETURN_TIMESTAMPTZ(result);
1182 pg_stat_get_db_conflict_tablespace(PG_FUNCTION_ARGS)
1184 Oid dbid = PG_GETARG_OID(0);
1186 PgStat_StatDBEntry *dbentry;
1188 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1191 result = (int64) (dbentry->n_conflict_tablespace);
1193 PG_RETURN_INT64(result);
1197 pg_stat_get_db_conflict_lock(PG_FUNCTION_ARGS)
1199 Oid dbid = PG_GETARG_OID(0);
1201 PgStat_StatDBEntry *dbentry;
1203 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1206 result = (int64) (dbentry->n_conflict_lock);
1208 PG_RETURN_INT64(result);
1212 pg_stat_get_db_conflict_snapshot(PG_FUNCTION_ARGS)
1214 Oid dbid = PG_GETARG_OID(0);
1216 PgStat_StatDBEntry *dbentry;
1218 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1221 result = (int64) (dbentry->n_conflict_snapshot);
1223 PG_RETURN_INT64(result);
1227 pg_stat_get_db_conflict_bufferpin(PG_FUNCTION_ARGS)
1229 Oid dbid = PG_GETARG_OID(0);
1231 PgStat_StatDBEntry *dbentry;
1233 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1236 result = (int64) (dbentry->n_conflict_bufferpin);
1238 PG_RETURN_INT64(result);
1242 pg_stat_get_db_conflict_startup_deadlock(PG_FUNCTION_ARGS)
1244 Oid dbid = PG_GETARG_OID(0);
1246 PgStat_StatDBEntry *dbentry;
1248 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1251 result = (int64) (dbentry->n_conflict_startup_deadlock);
1253 PG_RETURN_INT64(result);
1257 pg_stat_get_db_conflict_all(PG_FUNCTION_ARGS)
1259 Oid dbid = PG_GETARG_OID(0);
1261 PgStat_StatDBEntry *dbentry;
1263 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1267 dbentry->n_conflict_tablespace +
1268 dbentry->n_conflict_lock +
1269 dbentry->n_conflict_snapshot +
1270 dbentry->n_conflict_bufferpin +
1271 dbentry->n_conflict_startup_deadlock);
1273 PG_RETURN_INT64(result);
1277 pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS)
1279 PG_RETURN_INT64(pgstat_fetch_global()->timed_checkpoints);
1283 pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS)
1285 PG_RETURN_INT64(pgstat_fetch_global()->requested_checkpoints);
1289 pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS)
1291 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_checkpoints);
1295 pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
1297 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_clean);
1301 pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS)
1303 PG_RETURN_INT64(pgstat_fetch_global()->maxwritten_clean);
1307 pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS)
1309 PG_RETURN_TIMESTAMPTZ(pgstat_fetch_global()->stat_reset_timestamp);
1313 pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS)
1315 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_backend);
1319 pg_stat_get_buf_fsync_backend(PG_FUNCTION_ARGS)
1321 PG_RETURN_INT64(pgstat_fetch_global()->buf_fsync_backend);
1325 pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
1327 PG_RETURN_INT64(pgstat_fetch_global()->buf_alloc);
1331 pg_stat_get_xact_numscans(PG_FUNCTION_ARGS)
1333 Oid relid = PG_GETARG_OID(0);
1335 PgStat_TableStatus *tabentry;
1337 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1340 result = (int64) (tabentry->t_counts.t_numscans);
1342 PG_RETURN_INT64(result);
1346 pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS)
1348 Oid relid = PG_GETARG_OID(0);
1350 PgStat_TableStatus *tabentry;
1352 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1355 result = (int64) (tabentry->t_counts.t_tuples_returned);
1357 PG_RETURN_INT64(result);
1361 pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS)
1363 Oid relid = PG_GETARG_OID(0);
1365 PgStat_TableStatus *tabentry;
1367 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1370 result = (int64) (tabentry->t_counts.t_tuples_fetched);
1372 PG_RETURN_INT64(result);
1376 pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS)
1378 Oid relid = PG_GETARG_OID(0);
1380 PgStat_TableStatus *tabentry;
1381 PgStat_TableXactStatus *trans;
1383 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1387 result = tabentry->t_counts.t_tuples_inserted;
1388 /* live subtransactions' counts aren't in t_tuples_inserted yet */
1389 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1390 result += trans->tuples_inserted;
1393 PG_RETURN_INT64(result);
1397 pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS)
1399 Oid relid = PG_GETARG_OID(0);
1401 PgStat_TableStatus *tabentry;
1402 PgStat_TableXactStatus *trans;
1404 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1408 result = tabentry->t_counts.t_tuples_updated;
1409 /* live subtransactions' counts aren't in t_tuples_updated yet */
1410 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1411 result += trans->tuples_updated;
1414 PG_RETURN_INT64(result);
1418 pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS)
1420 Oid relid = PG_GETARG_OID(0);
1422 PgStat_TableStatus *tabentry;
1423 PgStat_TableXactStatus *trans;
1425 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1429 result = tabentry->t_counts.t_tuples_deleted;
1430 /* live subtransactions' counts aren't in t_tuples_deleted yet */
1431 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1432 result += trans->tuples_deleted;
1435 PG_RETURN_INT64(result);
1439 pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS)
1441 Oid relid = PG_GETARG_OID(0);
1443 PgStat_TableStatus *tabentry;
1445 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1448 result = (int64) (tabentry->t_counts.t_tuples_hot_updated);
1450 PG_RETURN_INT64(result);
1454 pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS)
1456 Oid relid = PG_GETARG_OID(0);
1458 PgStat_TableStatus *tabentry;
1460 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1463 result = (int64) (tabentry->t_counts.t_blocks_fetched);
1465 PG_RETURN_INT64(result);
1469 pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS)
1471 Oid relid = PG_GETARG_OID(0);
1473 PgStat_TableStatus *tabentry;
1475 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1478 result = (int64) (tabentry->t_counts.t_blocks_hit);
1480 PG_RETURN_INT64(result);
1484 pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)
1486 Oid funcid = PG_GETARG_OID(0);
1487 PgStat_BackendFunctionEntry *funcentry;
1489 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1491 PG_RETURN_INT64(funcentry->f_counts.f_numcalls);
1495 pg_stat_get_xact_function_time(PG_FUNCTION_ARGS)
1497 Oid funcid = PG_GETARG_OID(0);
1498 PgStat_BackendFunctionEntry *funcentry;
1500 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1502 PG_RETURN_INT64(INSTR_TIME_GET_MICROSEC(funcentry->f_counts.f_time));
1506 pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS)
1508 Oid funcid = PG_GETARG_OID(0);
1509 PgStat_BackendFunctionEntry *funcentry;
1511 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1513 PG_RETURN_INT64(INSTR_TIME_GET_MICROSEC(funcentry->f_counts.f_time_self));
1517 /* Discard the active statistics snapshot */
1519 pg_stat_clear_snapshot(PG_FUNCTION_ARGS)
1521 pgstat_clear_snapshot();
1527 /* Reset all counters for the current database */
1529 pg_stat_reset(PG_FUNCTION_ARGS)
1531 pgstat_reset_counters();
1536 /* Reset some shared cluster-wide counters */
1538 pg_stat_reset_shared(PG_FUNCTION_ARGS)
1540 char *target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1542 pgstat_reset_shared_counters(target);
1547 /* Reset a a single counter in the current database */
1549 pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS)
1551 Oid taboid = PG_GETARG_OID(0);
1553 pgstat_reset_single_counter(taboid, RESET_TABLE);
1559 pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS)
1561 Oid funcoid = PG_GETARG_OID(0);
1563 pgstat_reset_single_counter(funcoid, RESET_FUNCTION);