1 /*-------------------------------------------------------------------------
4 * Functions for accessing the statistics collector data
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
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_clear_snapshot(PG_FUNCTION_ARGS
);
80 extern Datum
pg_stat_reset(PG_FUNCTION_ARGS
);
82 /* Global bgwriter statistics, from bgwriter.c */
83 extern PgStat_MsgBgWriter bgwriterStats
;
86 pg_stat_get_numscans(PG_FUNCTION_ARGS
)
88 Oid relid
= PG_GETARG_OID(0);
90 PgStat_StatTabEntry
*tabentry
;
92 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
95 result
= (int64
) (tabentry
->numscans
);
97 PG_RETURN_INT64(result
);
102 pg_stat_get_tuples_returned(PG_FUNCTION_ARGS
)
104 Oid relid
= PG_GETARG_OID(0);
106 PgStat_StatTabEntry
*tabentry
;
108 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
111 result
= (int64
) (tabentry
->tuples_returned
);
113 PG_RETURN_INT64(result
);
118 pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS
)
120 Oid relid
= PG_GETARG_OID(0);
122 PgStat_StatTabEntry
*tabentry
;
124 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
127 result
= (int64
) (tabentry
->tuples_fetched
);
129 PG_RETURN_INT64(result
);
134 pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS
)
136 Oid relid
= PG_GETARG_OID(0);
138 PgStat_StatTabEntry
*tabentry
;
140 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
143 result
= (int64
) (tabentry
->tuples_inserted
);
145 PG_RETURN_INT64(result
);
150 pg_stat_get_tuples_updated(PG_FUNCTION_ARGS
)
152 Oid relid
= PG_GETARG_OID(0);
154 PgStat_StatTabEntry
*tabentry
;
156 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
159 result
= (int64
) (tabentry
->tuples_updated
);
161 PG_RETURN_INT64(result
);
166 pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS
)
168 Oid relid
= PG_GETARG_OID(0);
170 PgStat_StatTabEntry
*tabentry
;
172 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
175 result
= (int64
) (tabentry
->tuples_deleted
);
177 PG_RETURN_INT64(result
);
182 pg_stat_get_tuples_hot_updated(PG_FUNCTION_ARGS
)
184 Oid relid
= PG_GETARG_OID(0);
186 PgStat_StatTabEntry
*tabentry
;
188 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
191 result
= (int64
) (tabentry
->tuples_hot_updated
);
193 PG_RETURN_INT64(result
);
198 pg_stat_get_live_tuples(PG_FUNCTION_ARGS
)
200 Oid relid
= PG_GETARG_OID(0);
202 PgStat_StatTabEntry
*tabentry
;
204 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
207 result
= (int64
) (tabentry
->n_live_tuples
);
209 PG_RETURN_INT64(result
);
214 pg_stat_get_dead_tuples(PG_FUNCTION_ARGS
)
216 Oid relid
= PG_GETARG_OID(0);
218 PgStat_StatTabEntry
*tabentry
;
220 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
223 result
= (int64
) (tabentry
->n_dead_tuples
);
225 PG_RETURN_INT64(result
);
230 pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS
)
232 Oid relid
= PG_GETARG_OID(0);
234 PgStat_StatTabEntry
*tabentry
;
236 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
239 result
= (int64
) (tabentry
->blocks_fetched
);
241 PG_RETURN_INT64(result
);
246 pg_stat_get_blocks_hit(PG_FUNCTION_ARGS
)
248 Oid relid
= PG_GETARG_OID(0);
250 PgStat_StatTabEntry
*tabentry
;
252 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
255 result
= (int64
) (tabentry
->blocks_hit
);
257 PG_RETURN_INT64(result
);
261 pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS
)
263 Oid relid
= PG_GETARG_OID(0);
265 PgStat_StatTabEntry
*tabentry
;
267 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
270 result
= tabentry
->vacuum_timestamp
;
275 PG_RETURN_TIMESTAMPTZ(result
);
279 pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS
)
281 Oid relid
= PG_GETARG_OID(0);
283 PgStat_StatTabEntry
*tabentry
;
285 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
288 result
= tabentry
->autovac_vacuum_timestamp
;
293 PG_RETURN_TIMESTAMPTZ(result
);
297 pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS
)
299 Oid relid
= PG_GETARG_OID(0);
301 PgStat_StatTabEntry
*tabentry
;
303 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
306 result
= tabentry
->analyze_timestamp
;
311 PG_RETURN_TIMESTAMPTZ(result
);
315 pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS
)
317 Oid relid
= PG_GETARG_OID(0);
319 PgStat_StatTabEntry
*tabentry
;
321 if ((tabentry
= pgstat_fetch_stat_tabentry(relid
)) == NULL
)
324 result
= tabentry
->autovac_analyze_timestamp
;
329 PG_RETURN_TIMESTAMPTZ(result
);
333 pg_stat_get_function_calls(PG_FUNCTION_ARGS
)
335 Oid funcid
= PG_GETARG_OID(0);
336 PgStat_StatFuncEntry
*funcentry
;
338 if ((funcentry
= pgstat_fetch_stat_funcentry(funcid
)) == NULL
)
340 PG_RETURN_INT64(funcentry
->f_numcalls
);
344 pg_stat_get_function_time(PG_FUNCTION_ARGS
)
346 Oid funcid
= PG_GETARG_OID(0);
347 PgStat_StatFuncEntry
*funcentry
;
349 if ((funcentry
= pgstat_fetch_stat_funcentry(funcid
)) == NULL
)
351 PG_RETURN_INT64(funcentry
->f_time
);
355 pg_stat_get_function_self_time(PG_FUNCTION_ARGS
)
357 Oid funcid
= PG_GETARG_OID(0);
358 PgStat_StatFuncEntry
*funcentry
;
360 if ((funcentry
= pgstat_fetch_stat_funcentry(funcid
)) == NULL
)
362 PG_RETURN_INT64(funcentry
->f_time_self
);
366 pg_stat_get_backend_idset(PG_FUNCTION_ARGS
)
368 FuncCallContext
*funcctx
;
372 /* stuff done only on the first call of the function */
373 if (SRF_IS_FIRSTCALL())
375 /* create a function context for cross-call persistence */
376 funcctx
= SRF_FIRSTCALL_INIT();
378 fctx
= MemoryContextAlloc(funcctx
->multi_call_memory_ctx
,
380 funcctx
->user_fctx
= fctx
;
383 fctx
[1] = pgstat_fetch_stat_numbackends();
386 /* stuff done on every call of the function */
387 funcctx
= SRF_PERCALL_SETUP();
388 fctx
= funcctx
->user_fctx
;
393 if (result
<= fctx
[1])
395 /* do when there is more left to send */
396 SRF_RETURN_NEXT(funcctx
, Int32GetDatum(result
));
400 /* do when there is no more left */
401 SRF_RETURN_DONE(funcctx
);
406 pg_stat_get_activity(PG_FUNCTION_ARGS
)
408 FuncCallContext
*funcctx
;
410 if (SRF_IS_FIRSTCALL())
412 MemoryContext oldcontext
;
415 funcctx
= SRF_FIRSTCALL_INIT();
417 oldcontext
= MemoryContextSwitchTo(funcctx
->multi_call_memory_ctx
);
419 tupdesc
= CreateTemplateTupleDesc(10, false);
420 TupleDescInitEntry(tupdesc
, (AttrNumber
) 1, "datid", OIDOID
, -1, 0);
421 TupleDescInitEntry(tupdesc
, (AttrNumber
) 2, "procpid", INT4OID
, -1, 0);
422 TupleDescInitEntry(tupdesc
, (AttrNumber
) 3, "usesysid", OIDOID
, -1, 0);
423 TupleDescInitEntry(tupdesc
, (AttrNumber
) 4, "current_query", TEXTOID
, -1, 0);
424 TupleDescInitEntry(tupdesc
, (AttrNumber
) 5, "waiting", BOOLOID
, -1, 0);
425 TupleDescInitEntry(tupdesc
, (AttrNumber
) 6, "act_start", TIMESTAMPTZOID
, -1, 0);
426 TupleDescInitEntry(tupdesc
, (AttrNumber
) 7, "query_start", TIMESTAMPTZOID
, -1, 0);
427 TupleDescInitEntry(tupdesc
, (AttrNumber
) 8, "backend_start", TIMESTAMPTZOID
, -1, 0);
428 TupleDescInitEntry(tupdesc
, (AttrNumber
) 9, "client_addr", INETOID
, -1, 0);
429 TupleDescInitEntry(tupdesc
, (AttrNumber
) 10, "client_port", INT4OID
, -1, 0);
431 funcctx
->tuple_desc
= BlessTupleDesc(tupdesc
);
433 funcctx
->user_fctx
= palloc0(sizeof(int));
436 /* Get all backends */
437 funcctx
->max_calls
= pgstat_fetch_stat_numbackends();
442 * Get one backend - locate by pid.
444 * We lookup the backend early, so we can return zero rows if it doesn't
445 * exist, instead of returning a single row full of NULLs.
447 int pid
= PG_GETARG_INT32(0);
449 int n
= pgstat_fetch_stat_numbackends();
451 for (i
= 1; i
<= n
; i
++)
453 PgBackendStatus
*be
= pgstat_fetch_stat_beentry(i
);
456 if (be
->st_procpid
== pid
)
458 *(int *)(funcctx
->user_fctx
) = i
;
464 if (*(int *)(funcctx
->user_fctx
) == 0)
465 /* Pid not found, return zero rows */
466 funcctx
->max_calls
= 0;
468 funcctx
->max_calls
= 1;
471 MemoryContextSwitchTo(oldcontext
);
474 /* stuff done on every call of the function */
475 funcctx
= SRF_PERCALL_SETUP();
477 if (funcctx
->call_cntr
< funcctx
->max_calls
)
483 PgBackendStatus
*beentry
;
484 SockAddr zero_clientaddr
;
486 MemSet(values
, 0, sizeof(values
));
487 MemSet(nulls
, 0, sizeof(nulls
));
489 if (*(int *)(funcctx
->user_fctx
) > 0)
490 /* Get specific pid slot */
491 beentry
= pgstat_fetch_stat_beentry(*(int *)(funcctx
->user_fctx
));
493 /* Get the next one in the list */
494 beentry
= pgstat_fetch_stat_beentry(funcctx
->call_cntr
+1); /* 1-based index */
499 for (i
= 0; i
< sizeof(nulls
)/sizeof(nulls
[0]); i
++)
503 values
[3] = CStringGetTextDatum("<backend information not available>");
505 tuple
= heap_form_tuple(funcctx
->tuple_desc
, values
, nulls
);
506 SRF_RETURN_NEXT(funcctx
, HeapTupleGetDatum(tuple
));
509 /* Values available to all callers */
510 values
[0] = ObjectIdGetDatum(beentry
->st_databaseid
);
511 values
[1] = Int32GetDatum(beentry
->st_procpid
);
512 values
[2] = ObjectIdGetDatum(beentry
->st_userid
);
514 /* Values only available to same user or superuser */
515 if (superuser() || beentry
->st_userid
== GetUserId())
517 if (*(beentry
->st_activity
) == '\0')
519 values
[3] = CStringGetTextDatum("<command string not enabled>");
523 values
[3] = CStringGetTextDatum(beentry
->st_activity
);
526 values
[4] = BoolGetDatum(beentry
->st_waiting
);
528 if (beentry
->st_xact_start_timestamp
!= 0)
529 values
[5] = TimestampTzGetDatum(beentry
->st_xact_start_timestamp
);
533 if (beentry
->st_activity_start_timestamp
!= 0)
534 values
[6] = TimestampTzGetDatum(beentry
->st_activity_start_timestamp
);
538 if (beentry
->st_proc_start_timestamp
!= 0)
539 values
[7] = TimestampTzGetDatum(beentry
->st_proc_start_timestamp
);
543 /* A zeroed client addr means we don't know */
544 memset(&zero_clientaddr
, 0, sizeof(zero_clientaddr
));
545 if (memcmp(&(beentry
->st_clientaddr
), &zero_clientaddr
,
546 sizeof(zero_clientaddr
) == 0))
553 if (beentry
->st_clientaddr
.addr
.ss_family
== AF_INET
555 || beentry
->st_clientaddr
.addr
.ss_family
== AF_INET6
559 char remote_host
[NI_MAXHOST
];
560 char remote_port
[NI_MAXSERV
];
563 remote_host
[0] = '\0';
564 remote_port
[0] = '\0';
565 ret
= pg_getnameinfo_all(&beentry
->st_clientaddr
.addr
,
566 beentry
->st_clientaddr
.salen
,
567 remote_host
, sizeof(remote_host
),
568 remote_port
, sizeof(remote_port
),
569 NI_NUMERICHOST
| NI_NUMERICSERV
);
577 clean_ipv6_addr(beentry
->st_clientaddr
.addr
.ss_family
, remote_host
);
578 values
[8] = DirectFunctionCall1(inet_in
,
579 CStringGetDatum(remote_host
));
580 values
[9] = Int32GetDatum(atoi(remote_port
));
583 else if (beentry
->st_clientaddr
.addr
.ss_family
== AF_UNIX
)
586 * Unix sockets always reports NULL for host and -1 for port, so it's
587 * possible to tell the difference to connections we have no
588 * permissions to view, or with errors.
591 values
[9] = DatumGetInt32(-1);
595 /* Unknown address type, should never happen */
603 /* No permissions to view data about this session */
604 values
[3] = CStringGetTextDatum("<insufficient privilege>");
613 tuple
= heap_form_tuple(funcctx
->tuple_desc
, values
, nulls
);
615 SRF_RETURN_NEXT(funcctx
, HeapTupleGetDatum(tuple
));
620 SRF_RETURN_DONE(funcctx
);
626 pg_backend_pid(PG_FUNCTION_ARGS
)
628 PG_RETURN_INT32(MyProcPid
);
633 pg_stat_get_backend_pid(PG_FUNCTION_ARGS
)
635 int32 beid
= PG_GETARG_INT32(0);
636 PgBackendStatus
*beentry
;
638 if ((beentry
= pgstat_fetch_stat_beentry(beid
)) == NULL
)
641 PG_RETURN_INT32(beentry
->st_procpid
);
646 pg_stat_get_backend_dbid(PG_FUNCTION_ARGS
)
648 int32 beid
= PG_GETARG_INT32(0);
649 PgBackendStatus
*beentry
;
651 if ((beentry
= pgstat_fetch_stat_beentry(beid
)) == NULL
)
654 PG_RETURN_OID(beentry
->st_databaseid
);
659 pg_stat_get_backend_userid(PG_FUNCTION_ARGS
)
661 int32 beid
= PG_GETARG_INT32(0);
662 PgBackendStatus
*beentry
;
664 if ((beentry
= pgstat_fetch_stat_beentry(beid
)) == NULL
)
667 PG_RETURN_OID(beentry
->st_userid
);
672 pg_stat_get_backend_activity(PG_FUNCTION_ARGS
)
674 int32 beid
= PG_GETARG_INT32(0);
675 PgBackendStatus
*beentry
;
676 const char *activity
;
678 if ((beentry
= pgstat_fetch_stat_beentry(beid
)) == NULL
)
679 activity
= "<backend information not available>";
680 else if (!superuser() && beentry
->st_userid
!= GetUserId())
681 activity
= "<insufficient privilege>";
682 else if (*(beentry
->st_activity
) == '\0')
683 activity
= "<command string not enabled>";
685 activity
= beentry
->st_activity
;
687 PG_RETURN_TEXT_P(cstring_to_text(activity
));
692 pg_stat_get_backend_waiting(PG_FUNCTION_ARGS
)
694 int32 beid
= PG_GETARG_INT32(0);
696 PgBackendStatus
*beentry
;
698 if ((beentry
= pgstat_fetch_stat_beentry(beid
)) == NULL
)
701 if (!superuser() && beentry
->st_userid
!= GetUserId())
704 result
= beentry
->st_waiting
;
706 PG_RETURN_BOOL(result
);
711 pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS
)
713 int32 beid
= PG_GETARG_INT32(0);
715 PgBackendStatus
*beentry
;
717 if ((beentry
= pgstat_fetch_stat_beentry(beid
)) == NULL
)
720 if (!superuser() && beentry
->st_userid
!= GetUserId())
723 result
= beentry
->st_activity_start_timestamp
;
726 * No time recorded for start of current query -- this is the case if the
727 * user hasn't enabled query-level stats collection.
732 PG_RETURN_TIMESTAMPTZ(result
);
737 pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS
)
739 int32 beid
= PG_GETARG_INT32(0);
741 PgBackendStatus
*beentry
;
743 if ((beentry
= pgstat_fetch_stat_beentry(beid
)) == NULL
)
746 if (!superuser() && beentry
->st_userid
!= GetUserId())
749 result
= beentry
->st_xact_start_timestamp
;
751 if (result
== 0) /* not in a transaction */
754 PG_RETURN_TIMESTAMPTZ(result
);
759 pg_stat_get_backend_start(PG_FUNCTION_ARGS
)
761 int32 beid
= PG_GETARG_INT32(0);
763 PgBackendStatus
*beentry
;
765 if ((beentry
= pgstat_fetch_stat_beentry(beid
)) == NULL
)
768 if (!superuser() && beentry
->st_userid
!= GetUserId())
771 result
= beentry
->st_proc_start_timestamp
;
773 if (result
== 0) /* probably can't happen? */
776 PG_RETURN_TIMESTAMPTZ(result
);
781 pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS
)
783 int32 beid
= PG_GETARG_INT32(0);
784 PgBackendStatus
*beentry
;
785 SockAddr zero_clientaddr
;
786 char remote_host
[NI_MAXHOST
];
789 if ((beentry
= pgstat_fetch_stat_beentry(beid
)) == NULL
)
792 if (!superuser() && beentry
->st_userid
!= GetUserId())
795 /* A zeroed client addr means we don't know */
796 memset(&zero_clientaddr
, 0, sizeof(zero_clientaddr
));
797 if (memcmp(&(beentry
->st_clientaddr
), &zero_clientaddr
,
798 sizeof(zero_clientaddr
) == 0))
801 switch (beentry
->st_clientaddr
.addr
.ss_family
)
812 remote_host
[0] = '\0';
813 ret
= pg_getnameinfo_all(&beentry
->st_clientaddr
.addr
,
814 beentry
->st_clientaddr
.salen
,
815 remote_host
, sizeof(remote_host
),
817 NI_NUMERICHOST
| NI_NUMERICSERV
);
821 clean_ipv6_addr(beentry
->st_clientaddr
.addr
.ss_family
, remote_host
);
823 PG_RETURN_INET_P(DirectFunctionCall1(inet_in
,
824 CStringGetDatum(remote_host
)));
828 pg_stat_get_backend_client_port(PG_FUNCTION_ARGS
)
830 int32 beid
= PG_GETARG_INT32(0);
831 PgBackendStatus
*beentry
;
832 SockAddr zero_clientaddr
;
833 char remote_port
[NI_MAXSERV
];
836 if ((beentry
= pgstat_fetch_stat_beentry(beid
)) == NULL
)
839 if (!superuser() && beentry
->st_userid
!= GetUserId())
842 /* A zeroed client addr means we don't know */
843 memset(&zero_clientaddr
, 0, sizeof(zero_clientaddr
));
844 if (memcmp(&(beentry
->st_clientaddr
), &zero_clientaddr
,
845 sizeof(zero_clientaddr
) == 0))
848 switch (beentry
->st_clientaddr
.addr
.ss_family
)
861 remote_port
[0] = '\0';
862 ret
= pg_getnameinfo_all(&beentry
->st_clientaddr
.addr
,
863 beentry
->st_clientaddr
.salen
,
865 remote_port
, sizeof(remote_port
),
866 NI_NUMERICHOST
| NI_NUMERICSERV
);
870 PG_RETURN_DATUM(DirectFunctionCall1(int4in
,
871 CStringGetDatum(remote_port
)));
876 pg_stat_get_db_numbackends(PG_FUNCTION_ARGS
)
878 Oid dbid
= PG_GETARG_OID(0);
880 int tot_backends
= pgstat_fetch_stat_numbackends();
884 for (beid
= 1; beid
<= tot_backends
; beid
++)
886 PgBackendStatus
*beentry
= pgstat_fetch_stat_beentry(beid
);
888 if (beentry
&& beentry
->st_databaseid
== dbid
)
892 PG_RETURN_INT32(result
);
897 pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS
)
899 Oid dbid
= PG_GETARG_OID(0);
901 PgStat_StatDBEntry
*dbentry
;
903 if ((dbentry
= pgstat_fetch_stat_dbentry(dbid
)) == NULL
)
906 result
= (int64
) (dbentry
->n_xact_commit
);
908 PG_RETURN_INT64(result
);
913 pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS
)
915 Oid dbid
= PG_GETARG_OID(0);
917 PgStat_StatDBEntry
*dbentry
;
919 if ((dbentry
= pgstat_fetch_stat_dbentry(dbid
)) == NULL
)
922 result
= (int64
) (dbentry
->n_xact_rollback
);
924 PG_RETURN_INT64(result
);
929 pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS
)
931 Oid dbid
= PG_GETARG_OID(0);
933 PgStat_StatDBEntry
*dbentry
;
935 if ((dbentry
= pgstat_fetch_stat_dbentry(dbid
)) == NULL
)
938 result
= (int64
) (dbentry
->n_blocks_fetched
);
940 PG_RETURN_INT64(result
);
945 pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS
)
947 Oid dbid
= PG_GETARG_OID(0);
949 PgStat_StatDBEntry
*dbentry
;
951 if ((dbentry
= pgstat_fetch_stat_dbentry(dbid
)) == NULL
)
954 result
= (int64
) (dbentry
->n_blocks_hit
);
956 PG_RETURN_INT64(result
);
961 pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS
)
963 Oid dbid
= PG_GETARG_OID(0);
965 PgStat_StatDBEntry
*dbentry
;
967 if ((dbentry
= pgstat_fetch_stat_dbentry(dbid
)) == NULL
)
970 result
= (int64
) (dbentry
->n_tuples_returned
);
972 PG_RETURN_INT64(result
);
977 pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS
)
979 Oid dbid
= PG_GETARG_OID(0);
981 PgStat_StatDBEntry
*dbentry
;
983 if ((dbentry
= pgstat_fetch_stat_dbentry(dbid
)) == NULL
)
986 result
= (int64
) (dbentry
->n_tuples_fetched
);
988 PG_RETURN_INT64(result
);
993 pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS
)
995 Oid dbid
= PG_GETARG_OID(0);
997 PgStat_StatDBEntry
*dbentry
;
999 if ((dbentry
= pgstat_fetch_stat_dbentry(dbid
)) == NULL
)
1002 result
= (int64
) (dbentry
->n_tuples_inserted
);
1004 PG_RETURN_INT64(result
);
1009 pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS
)
1011 Oid dbid
= PG_GETARG_OID(0);
1013 PgStat_StatDBEntry
*dbentry
;
1015 if ((dbentry
= pgstat_fetch_stat_dbentry(dbid
)) == NULL
)
1018 result
= (int64
) (dbentry
->n_tuples_updated
);
1020 PG_RETURN_INT64(result
);
1025 pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS
)
1027 Oid dbid
= PG_GETARG_OID(0);
1029 PgStat_StatDBEntry
*dbentry
;
1031 if ((dbentry
= pgstat_fetch_stat_dbentry(dbid
)) == NULL
)
1034 result
= (int64
) (dbentry
->n_tuples_deleted
);
1036 PG_RETURN_INT64(result
);
1040 pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS
)
1042 PG_RETURN_INT64(pgstat_fetch_global()->timed_checkpoints
);
1046 pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS
)
1048 PG_RETURN_INT64(pgstat_fetch_global()->requested_checkpoints
);
1052 pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS
)
1054 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_checkpoints
);
1058 pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS
)
1060 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_clean
);
1064 pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS
)
1066 PG_RETURN_INT64(pgstat_fetch_global()->maxwritten_clean
);
1070 pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS
)
1072 PG_RETURN_INT64(pgstat_fetch_global()->buf_written_backend
);
1076 pg_stat_get_buf_alloc(PG_FUNCTION_ARGS
)
1078 PG_RETURN_INT64(pgstat_fetch_global()->buf_alloc
);
1082 /* Discard the active statistics snapshot */
1084 pg_stat_clear_snapshot(PG_FUNCTION_ARGS
)
1086 pgstat_clear_snapshot();
1092 /* Reset all counters for the current database */
1094 pg_stat_reset(PG_FUNCTION_ARGS
)
1096 pgstat_reset_counters();