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.61 2010/08/08 16:27:04 tgl 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);
42 extern Datum pg_stat_get_function_calls(PG_FUNCTION_ARGS);
43 extern Datum pg_stat_get_function_time(PG_FUNCTION_ARGS);
44 extern Datum pg_stat_get_function_self_time(PG_FUNCTION_ARGS);
46 extern Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS);
47 extern Datum pg_stat_get_activity(PG_FUNCTION_ARGS);
48 extern Datum pg_backend_pid(PG_FUNCTION_ARGS);
49 extern Datum pg_stat_get_backend_pid(PG_FUNCTION_ARGS);
50 extern Datum pg_stat_get_backend_dbid(PG_FUNCTION_ARGS);
51 extern Datum pg_stat_get_backend_userid(PG_FUNCTION_ARGS);
52 extern Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS);
53 extern Datum pg_stat_get_backend_waiting(PG_FUNCTION_ARGS);
54 extern Datum pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS);
55 extern Datum pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS);
56 extern Datum pg_stat_get_backend_start(PG_FUNCTION_ARGS);
57 extern Datum pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS);
58 extern Datum pg_stat_get_backend_client_port(PG_FUNCTION_ARGS);
60 extern Datum pg_stat_get_db_numbackends(PG_FUNCTION_ARGS);
61 extern Datum pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS);
62 extern Datum pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS);
63 extern Datum pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS);
64 extern Datum pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS);
65 extern Datum pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS);
66 extern Datum pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS);
67 extern Datum pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS);
68 extern Datum pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS);
69 extern Datum pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS);
71 extern Datum pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS);
72 extern Datum pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS);
73 extern Datum pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS);
74 extern Datum pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS);
75 extern Datum pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS);
76 extern Datum pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS);
77 extern Datum pg_stat_get_buf_alloc(PG_FUNCTION_ARGS);
79 extern Datum pg_stat_get_xact_numscans(PG_FUNCTION_ARGS);
80 extern Datum pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS);
81 extern Datum pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS);
82 extern Datum pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS);
83 extern Datum pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS);
84 extern Datum pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS);
85 extern Datum pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS);
86 extern Datum pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS);
87 extern Datum pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS);
89 extern Datum pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS);
90 extern Datum pg_stat_get_xact_function_time(PG_FUNCTION_ARGS);
91 extern Datum pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS);
93 extern Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS);
94 extern Datum pg_stat_reset(PG_FUNCTION_ARGS);
95 extern Datum pg_stat_reset_shared(PG_FUNCTION_ARGS);
96 extern Datum pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS);
97 extern Datum pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS);
99 /* Global bgwriter statistics, from bgwriter.c */
100 extern PgStat_MsgBgWriter bgwriterStats;
103 pg_stat_get_numscans(PG_FUNCTION_ARGS)
105 Oid relid = PG_GETARG_OID(0);
107 PgStat_StatTabEntry *tabentry;
109 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
112 result = (int64) (tabentry->numscans);
114 PG_RETURN_INT64(result);
119 pg_stat_get_tuples_returned(PG_FUNCTION_ARGS)
121 Oid relid = PG_GETARG_OID(0);
123 PgStat_StatTabEntry *tabentry;
125 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
128 result = (int64) (tabentry->tuples_returned);
130 PG_RETURN_INT64(result);
135 pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS)
137 Oid relid = PG_GETARG_OID(0);
139 PgStat_StatTabEntry *tabentry;
141 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
144 result = (int64) (tabentry->tuples_fetched);
146 PG_RETURN_INT64(result);
151 pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS)
153 Oid relid = PG_GETARG_OID(0);
155 PgStat_StatTabEntry *tabentry;
157 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
160 result = (int64) (tabentry->tuples_inserted);
162 PG_RETURN_INT64(result);
167 pg_stat_get_tuples_updated(PG_FUNCTION_ARGS)
169 Oid relid = PG_GETARG_OID(0);
171 PgStat_StatTabEntry *tabentry;
173 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
176 result = (int64) (tabentry->tuples_updated);
178 PG_RETURN_INT64(result);
183 pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS)
185 Oid relid = PG_GETARG_OID(0);
187 PgStat_StatTabEntry *tabentry;
189 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
192 result = (int64) (tabentry->tuples_deleted);
194 PG_RETURN_INT64(result);
199 pg_stat_get_tuples_hot_updated(PG_FUNCTION_ARGS)
201 Oid relid = PG_GETARG_OID(0);
203 PgStat_StatTabEntry *tabentry;
205 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
208 result = (int64) (tabentry->tuples_hot_updated);
210 PG_RETURN_INT64(result);
215 pg_stat_get_live_tuples(PG_FUNCTION_ARGS)
217 Oid relid = PG_GETARG_OID(0);
219 PgStat_StatTabEntry *tabentry;
221 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
224 result = (int64) (tabentry->n_live_tuples);
226 PG_RETURN_INT64(result);
231 pg_stat_get_dead_tuples(PG_FUNCTION_ARGS)
233 Oid relid = PG_GETARG_OID(0);
235 PgStat_StatTabEntry *tabentry;
237 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
240 result = (int64) (tabentry->n_dead_tuples);
242 PG_RETURN_INT64(result);
247 pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS)
249 Oid relid = PG_GETARG_OID(0);
251 PgStat_StatTabEntry *tabentry;
253 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
256 result = (int64) (tabentry->blocks_fetched);
258 PG_RETURN_INT64(result);
263 pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
265 Oid relid = PG_GETARG_OID(0);
267 PgStat_StatTabEntry *tabentry;
269 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
272 result = (int64) (tabentry->blocks_hit);
274 PG_RETURN_INT64(result);
278 pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS)
280 Oid relid = PG_GETARG_OID(0);
282 PgStat_StatTabEntry *tabentry;
284 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
287 result = tabentry->vacuum_timestamp;
292 PG_RETURN_TIMESTAMPTZ(result);
296 pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS)
298 Oid relid = PG_GETARG_OID(0);
300 PgStat_StatTabEntry *tabentry;
302 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
305 result = tabentry->autovac_vacuum_timestamp;
310 PG_RETURN_TIMESTAMPTZ(result);
314 pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS)
316 Oid relid = PG_GETARG_OID(0);
318 PgStat_StatTabEntry *tabentry;
320 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
323 result = tabentry->analyze_timestamp;
328 PG_RETURN_TIMESTAMPTZ(result);
332 pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS)
334 Oid relid = PG_GETARG_OID(0);
336 PgStat_StatTabEntry *tabentry;
338 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
341 result = tabentry->autovac_analyze_timestamp;
346 PG_RETURN_TIMESTAMPTZ(result);
350 pg_stat_get_function_calls(PG_FUNCTION_ARGS)
352 Oid funcid = PG_GETARG_OID(0);
353 PgStat_StatFuncEntry *funcentry;
355 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
357 PG_RETURN_INT64(funcentry->f_numcalls);
361 pg_stat_get_function_time(PG_FUNCTION_ARGS)
363 Oid funcid = PG_GETARG_OID(0);
364 PgStat_StatFuncEntry *funcentry;
366 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
368 PG_RETURN_INT64(funcentry->f_time);
372 pg_stat_get_function_self_time(PG_FUNCTION_ARGS)
374 Oid funcid = PG_GETARG_OID(0);
375 PgStat_StatFuncEntry *funcentry;
377 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
379 PG_RETURN_INT64(funcentry->f_time_self);
383 pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
385 FuncCallContext *funcctx;
389 /* stuff done only on the first call of the function */
390 if (SRF_IS_FIRSTCALL())
392 /* create a function context for cross-call persistence */
393 funcctx = SRF_FIRSTCALL_INIT();
395 fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
397 funcctx->user_fctx = fctx;
400 fctx[1] = pgstat_fetch_stat_numbackends();
403 /* stuff done on every call of the function */
404 funcctx = SRF_PERCALL_SETUP();
405 fctx = funcctx->user_fctx;
410 if (result <= fctx[1])
412 /* do when there is more left to send */
413 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
417 /* do when there is no more left */
418 SRF_RETURN_DONE(funcctx);
423 pg_stat_get_activity(PG_FUNCTION_ARGS)
425 FuncCallContext *funcctx;
427 if (SRF_IS_FIRSTCALL())
429 MemoryContext oldcontext;
432 funcctx = SRF_FIRSTCALL_INIT();
434 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
436 tupdesc = CreateTemplateTupleDesc(11, false);
437 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "datid", OIDOID, -1, 0);
438 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "procpid", INT4OID, -1, 0);
439 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "usesysid", OIDOID, -1, 0);
440 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "application_name", TEXTOID, -1, 0);
441 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "current_query", TEXTOID, -1, 0);
442 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "waiting", BOOLOID, -1, 0);
443 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "act_start", TIMESTAMPTZOID, -1, 0);
444 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "query_start", TIMESTAMPTZOID, -1, 0);
445 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "backend_start", TIMESTAMPTZOID, -1, 0);
446 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "client_addr", INETOID, -1, 0);
447 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "client_port", INT4OID, -1, 0);
449 funcctx->tuple_desc = BlessTupleDesc(tupdesc);
451 funcctx->user_fctx = palloc0(sizeof(int));
454 /* Get all backends */
455 funcctx->max_calls = pgstat_fetch_stat_numbackends();
460 * Get one backend - locate by pid.
462 * We lookup the backend early, so we can return zero rows if it
463 * doesn't exist, instead of returning a single row full of NULLs.
465 int pid = PG_GETARG_INT32(0);
467 int n = pgstat_fetch_stat_numbackends();
469 for (i = 1; i <= n; i++)
471 PgBackendStatus *be = pgstat_fetch_stat_beentry(i);
475 if (be->st_procpid == pid)
477 *(int *) (funcctx->user_fctx) = i;
483 if (*(int *) (funcctx->user_fctx) == 0)
484 /* Pid not found, return zero rows */
485 funcctx->max_calls = 0;
487 funcctx->max_calls = 1;
490 MemoryContextSwitchTo(oldcontext);
493 /* stuff done on every call of the function */
494 funcctx = SRF_PERCALL_SETUP();
496 if (funcctx->call_cntr < funcctx->max_calls)
502 PgBackendStatus *beentry;
503 SockAddr zero_clientaddr;
505 MemSet(values, 0, sizeof(values));
506 MemSet(nulls, 0, sizeof(nulls));
508 if (*(int *) (funcctx->user_fctx) > 0)
510 /* Get specific pid slot */
511 beentry = pgstat_fetch_stat_beentry(*(int *) (funcctx->user_fctx));
515 /* Get the next one in the list */
516 beentry = pgstat_fetch_stat_beentry(funcctx->call_cntr + 1); /* 1-based index */
522 for (i = 0; i < sizeof(nulls) / sizeof(nulls[0]); i++)
526 values[4] = CStringGetTextDatum("<backend information not available>");
528 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
529 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
532 /* Values available to all callers */
533 values[0] = ObjectIdGetDatum(beentry->st_databaseid);
534 values[1] = Int32GetDatum(beentry->st_procpid);
535 values[2] = ObjectIdGetDatum(beentry->st_userid);
536 if (beentry->st_appname)
537 values[3] = CStringGetTextDatum(beentry->st_appname);
541 /* Values only available to same user or superuser */
542 if (superuser() || beentry->st_userid == GetUserId())
544 if (*(beentry->st_activity) == '\0')
546 values[4] = CStringGetTextDatum("<command string not enabled>");
550 values[4] = CStringGetTextDatum(beentry->st_activity);
553 values[5] = BoolGetDatum(beentry->st_waiting);
555 if (beentry->st_xact_start_timestamp != 0)
556 values[6] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
560 if (beentry->st_activity_start_timestamp != 0)
561 values[7] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
565 if (beentry->st_proc_start_timestamp != 0)
566 values[8] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
570 /* A zeroed client addr means we don't know */
571 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
572 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
573 sizeof(zero_clientaddr) == 0))
580 if (beentry->st_clientaddr.addr.ss_family == AF_INET
582 || beentry->st_clientaddr.addr.ss_family == AF_INET6
586 char remote_host[NI_MAXHOST];
587 char remote_port[NI_MAXSERV];
590 remote_host[0] = '\0';
591 remote_port[0] = '\0';
592 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
593 beentry->st_clientaddr.salen,
594 remote_host, sizeof(remote_host),
595 remote_port, sizeof(remote_port),
596 NI_NUMERICHOST | NI_NUMERICSERV);
604 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
605 values[9] = DirectFunctionCall1(inet_in,
606 CStringGetDatum(remote_host));
607 values[10] = Int32GetDatum(atoi(remote_port));
610 else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
613 * Unix sockets always reports NULL for host and -1 for
614 * port, so it's possible to tell the difference to
615 * connections we have no permissions to view, or with
619 values[10] = DatumGetInt32(-1);
623 /* Unknown address type, should never happen */
631 /* No permissions to view data about this session */
632 values[4] = CStringGetTextDatum("<insufficient privilege>");
641 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
643 SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
648 SRF_RETURN_DONE(funcctx);
654 pg_backend_pid(PG_FUNCTION_ARGS)
656 PG_RETURN_INT32(MyProcPid);
661 pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
663 int32 beid = PG_GETARG_INT32(0);
664 PgBackendStatus *beentry;
666 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
669 PG_RETURN_INT32(beentry->st_procpid);
674 pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
676 int32 beid = PG_GETARG_INT32(0);
677 PgBackendStatus *beentry;
679 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
682 PG_RETURN_OID(beentry->st_databaseid);
687 pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
689 int32 beid = PG_GETARG_INT32(0);
690 PgBackendStatus *beentry;
692 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
695 PG_RETURN_OID(beentry->st_userid);
700 pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
702 int32 beid = PG_GETARG_INT32(0);
703 PgBackendStatus *beentry;
704 const char *activity;
706 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
707 activity = "<backend information not available>";
708 else if (!superuser() && beentry->st_userid != GetUserId())
709 activity = "<insufficient privilege>";
710 else if (*(beentry->st_activity) == '\0')
711 activity = "<command string not enabled>";
713 activity = beentry->st_activity;
715 PG_RETURN_TEXT_P(cstring_to_text(activity));
720 pg_stat_get_backend_waiting(PG_FUNCTION_ARGS)
722 int32 beid = PG_GETARG_INT32(0);
724 PgBackendStatus *beentry;
726 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
729 if (!superuser() && beentry->st_userid != GetUserId())
732 result = beentry->st_waiting;
734 PG_RETURN_BOOL(result);
739 pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
741 int32 beid = PG_GETARG_INT32(0);
743 PgBackendStatus *beentry;
745 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
748 if (!superuser() && beentry->st_userid != GetUserId())
751 result = beentry->st_activity_start_timestamp;
754 * No time recorded for start of current query -- this is the case if the
755 * user hasn't enabled query-level stats collection.
760 PG_RETURN_TIMESTAMPTZ(result);
765 pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
767 int32 beid = PG_GETARG_INT32(0);
769 PgBackendStatus *beentry;
771 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
774 if (!superuser() && beentry->st_userid != GetUserId())
777 result = beentry->st_xact_start_timestamp;
779 if (result == 0) /* not in a transaction */
782 PG_RETURN_TIMESTAMPTZ(result);
787 pg_stat_get_backend_start(PG_FUNCTION_ARGS)
789 int32 beid = PG_GETARG_INT32(0);
791 PgBackendStatus *beentry;
793 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
796 if (!superuser() && beentry->st_userid != GetUserId())
799 result = beentry->st_proc_start_timestamp;
801 if (result == 0) /* probably can't happen? */
804 PG_RETURN_TIMESTAMPTZ(result);
809 pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
811 int32 beid = PG_GETARG_INT32(0);
812 PgBackendStatus *beentry;
813 SockAddr zero_clientaddr;
814 char remote_host[NI_MAXHOST];
817 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
820 if (!superuser() && beentry->st_userid != GetUserId())
823 /* A zeroed client addr means we don't know */
824 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
825 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
826 sizeof(zero_clientaddr) == 0))
829 switch (beentry->st_clientaddr.addr.ss_family)
840 remote_host[0] = '\0';
841 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
842 beentry->st_clientaddr.salen,
843 remote_host, sizeof(remote_host),
845 NI_NUMERICHOST | NI_NUMERICSERV);
849 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
851 PG_RETURN_INET_P(DirectFunctionCall1(inet_in,
852 CStringGetDatum(remote_host)));
856 pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
858 int32 beid = PG_GETARG_INT32(0);
859 PgBackendStatus *beentry;
860 SockAddr zero_clientaddr;
861 char remote_port[NI_MAXSERV];
864 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
867 if (!superuser() && beentry->st_userid != GetUserId())
870 /* A zeroed client addr means we don't know */
871 memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
872 if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
873 sizeof(zero_clientaddr) == 0))
876 switch (beentry->st_clientaddr.addr.ss_family)
889 remote_port[0] = '\0';
890 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
891 beentry->st_clientaddr.salen,
893 remote_port, sizeof(remote_port),
894 NI_NUMERICHOST | NI_NUMERICSERV);
898 PG_RETURN_DATUM(DirectFunctionCall1(int4in,
899 CStringGetDatum(remote_port)));
904 pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
906 Oid dbid = PG_GETARG_OID(0);
908 int tot_backends = pgstat_fetch_stat_numbackends();
912 for (beid = 1; beid <= tot_backends; beid++)
914 PgBackendStatus *beentry = pgstat_fetch_stat_beentry(beid);
916 if (beentry && beentry->st_databaseid == dbid)
920 PG_RETURN_INT32(result);
925 pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS)
927 Oid dbid = PG_GETARG_OID(0);
929 PgStat_StatDBEntry *dbentry;
931 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
934 result = (int64) (dbentry->n_xact_commit);
936 PG_RETURN_INT64(result);
941 pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS)
943 Oid dbid = PG_GETARG_OID(0);
945 PgStat_StatDBEntry *dbentry;
947 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
950 result = (int64) (dbentry->n_xact_rollback);
952 PG_RETURN_INT64(result);
957 pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS)
959 Oid dbid = PG_GETARG_OID(0);
961 PgStat_StatDBEntry *dbentry;
963 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
966 result = (int64) (dbentry->n_blocks_fetched);
968 PG_RETURN_INT64(result);
973 pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS)
975 Oid dbid = PG_GETARG_OID(0);
977 PgStat_StatDBEntry *dbentry;
979 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
982 result = (int64) (dbentry->n_blocks_hit);
984 PG_RETURN_INT64(result);
989 pg_stat_get_db_tuples_returned(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_tuples_returned);
1000 PG_RETURN_INT64(result);
1005 pg_stat_get_db_tuples_fetched(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_tuples_fetched);
1016 PG_RETURN_INT64(result);
1021 pg_stat_get_db_tuples_inserted(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_tuples_inserted);
1032 PG_RETURN_INT64(result);
1037 pg_stat_get_db_tuples_updated(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_tuples_updated);
1048 PG_RETURN_INT64(result);
1053 pg_stat_get_db_tuples_deleted(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_deleted);
1064 PG_RETURN_INT64(result);
1068 pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS)
1070 PG_RETURN_INT64(pgstat_fetch_global()->timed_checkpoints);
1074 pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS)
1076 PG_RETURN_INT64(pgstat_fetch_global()->requested_checkpoints);
1080 pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS)
1082 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_checkpoints);
1086 pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
1088 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_clean);
1092 pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS)
1094 PG_RETURN_INT64(pgstat_fetch_global()->maxwritten_clean);
1098 pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS)
1100 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_backend);
1104 pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
1106 PG_RETURN_INT64(pgstat_fetch_global()->buf_alloc);
1110 pg_stat_get_xact_numscans(PG_FUNCTION_ARGS)
1112 Oid relid = PG_GETARG_OID(0);
1114 PgStat_TableStatus *tabentry;
1116 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1119 result = (int64) (tabentry->t_counts.t_numscans);
1121 PG_RETURN_INT64(result);
1125 pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS)
1127 Oid relid = PG_GETARG_OID(0);
1129 PgStat_TableStatus *tabentry;
1131 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1134 result = (int64) (tabentry->t_counts.t_tuples_returned);
1136 PG_RETURN_INT64(result);
1140 pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS)
1142 Oid relid = PG_GETARG_OID(0);
1144 PgStat_TableStatus *tabentry;
1146 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1149 result = (int64) (tabentry->t_counts.t_tuples_fetched);
1151 PG_RETURN_INT64(result);
1155 pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS)
1157 Oid relid = PG_GETARG_OID(0);
1159 PgStat_TableStatus *tabentry;
1160 PgStat_TableXactStatus *trans;
1162 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1166 result = tabentry->t_counts.t_tuples_inserted;
1167 /* live subtransactions' counts aren't in t_tuples_inserted yet */
1168 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1169 result += trans->tuples_inserted;
1172 PG_RETURN_INT64(result);
1176 pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS)
1178 Oid relid = PG_GETARG_OID(0);
1180 PgStat_TableStatus *tabentry;
1181 PgStat_TableXactStatus *trans;
1183 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1187 result = tabentry->t_counts.t_tuples_updated;
1188 /* live subtransactions' counts aren't in t_tuples_updated yet */
1189 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1190 result += trans->tuples_updated;
1193 PG_RETURN_INT64(result);
1197 pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS)
1199 Oid relid = PG_GETARG_OID(0);
1201 PgStat_TableStatus *tabentry;
1202 PgStat_TableXactStatus *trans;
1204 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1208 result = tabentry->t_counts.t_tuples_deleted;
1209 /* live subtransactions' counts aren't in t_tuples_deleted yet */
1210 for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1211 result += trans->tuples_deleted;
1214 PG_RETURN_INT64(result);
1218 pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS)
1220 Oid relid = PG_GETARG_OID(0);
1222 PgStat_TableStatus *tabentry;
1224 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1227 result = (int64) (tabentry->t_counts.t_tuples_hot_updated);
1229 PG_RETURN_INT64(result);
1233 pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS)
1235 Oid relid = PG_GETARG_OID(0);
1237 PgStat_TableStatus *tabentry;
1239 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1242 result = (int64) (tabentry->t_counts.t_blocks_fetched);
1244 PG_RETURN_INT64(result);
1248 pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS)
1250 Oid relid = PG_GETARG_OID(0);
1252 PgStat_TableStatus *tabentry;
1254 if ((tabentry = find_tabstat_entry(relid)) == NULL)
1257 result = (int64) (tabentry->t_counts.t_blocks_hit);
1259 PG_RETURN_INT64(result);
1263 pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)
1265 Oid funcid = PG_GETARG_OID(0);
1266 PgStat_BackendFunctionEntry *funcentry;
1268 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1270 PG_RETURN_INT64(funcentry->f_counts.f_numcalls);
1274 pg_stat_get_xact_function_time(PG_FUNCTION_ARGS)
1276 Oid funcid = PG_GETARG_OID(0);
1277 PgStat_BackendFunctionEntry *funcentry;
1279 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1281 PG_RETURN_INT64(INSTR_TIME_GET_MICROSEC(funcentry->f_counts.f_time));
1285 pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS)
1287 Oid funcid = PG_GETARG_OID(0);
1288 PgStat_BackendFunctionEntry *funcentry;
1290 if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1292 PG_RETURN_INT64(INSTR_TIME_GET_MICROSEC(funcentry->f_counts.f_time_self));
1296 /* Discard the active statistics snapshot */
1298 pg_stat_clear_snapshot(PG_FUNCTION_ARGS)
1300 pgstat_clear_snapshot();
1306 /* Reset all counters for the current database */
1308 pg_stat_reset(PG_FUNCTION_ARGS)
1310 pgstat_reset_counters();
1315 /* Reset some shared cluster-wide counters */
1317 pg_stat_reset_shared(PG_FUNCTION_ARGS)
1319 char *target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1321 pgstat_reset_shared_counters(target);
1326 /* Reset a a single counter in the current database */
1328 pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS)
1330 Oid taboid = PG_GETARG_OID(0);
1332 pgstat_reset_single_counter(taboid, RESET_TABLE);
1338 pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS)
1340 Oid funcoid = PG_GETARG_OID(0);
1342 pgstat_reset_single_counter(funcoid, RESET_FUNCTION);