PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pgstatfuncs.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * pgstatfuncs.c
4 * Functions for accessing various forms of statistics data
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/utils/adt/pgstatfuncs.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "postgres.h"
16
17#include "access/htup_details.h"
18#include "access/xlog.h"
20#include "catalog/catalog.h"
21#include "catalog/pg_authid.h"
22#include "catalog/pg_type.h"
23#include "common/ip.h"
24#include "funcapi.h"
25#include "miscadmin.h"
26#include "pgstat.h"
27#include "postmaster/bgworker.h"
29#include "storage/proc.h"
30#include "storage/procarray.h"
31#include "utils/acl.h"
32#include "utils/builtins.h"
33#include "utils/timestamp.h"
34#include "utils/tuplestore.h"
35#include "utils/wait_event.h"
36
37#define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
38
39#define HAS_PGSTAT_PERMISSIONS(role) (has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS) || has_privs_of_role(GetUserId(), role))
40
41#define PG_STAT_GET_RELENTRY_INT64(stat) \
42Datum \
43CppConcat(pg_stat_get_,stat)(PG_FUNCTION_ARGS) \
44{ \
45 Oid relid = PG_GETARG_OID(0); \
46 int64 result; \
47 PgStat_StatTabEntry *tabentry; \
48 \
49 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL) \
50 result = 0; \
51 else \
52 result = (int64) (tabentry->stat); \
53 \
54 PG_RETURN_INT64(result); \
55}
56
57/* pg_stat_get_analyze_count */
58PG_STAT_GET_RELENTRY_INT64(analyze_count)
59
60/* pg_stat_get_autoanalyze_count */
61PG_STAT_GET_RELENTRY_INT64(autoanalyze_count)
62
63/* pg_stat_get_autovacuum_count */
64PG_STAT_GET_RELENTRY_INT64(autovacuum_count)
65
66/* pg_stat_get_blocks_fetched */
67PG_STAT_GET_RELENTRY_INT64(blocks_fetched)
68
69/* pg_stat_get_blocks_hit */
71
72/* pg_stat_get_dead_tuples */
74
75/* pg_stat_get_ins_since_vacuum */
76PG_STAT_GET_RELENTRY_INT64(ins_since_vacuum)
77
78/* pg_stat_get_live_tuples */
80
81/* pg_stat_get_mod_since_analyze */
82PG_STAT_GET_RELENTRY_INT64(mod_since_analyze)
83
84/* pg_stat_get_numscans */
86
87/* pg_stat_get_tuples_deleted */
88PG_STAT_GET_RELENTRY_INT64(tuples_deleted)
89
90/* pg_stat_get_tuples_fetched */
91PG_STAT_GET_RELENTRY_INT64(tuples_fetched)
92
93/* pg_stat_get_tuples_hot_updated */
94PG_STAT_GET_RELENTRY_INT64(tuples_hot_updated)
95
96/* pg_stat_get_tuples_newpage_updated */
97PG_STAT_GET_RELENTRY_INT64(tuples_newpage_updated)
98
99/* pg_stat_get_tuples_inserted */
100PG_STAT_GET_RELENTRY_INT64(tuples_inserted)
101
102/* pg_stat_get_tuples_returned */
103PG_STAT_GET_RELENTRY_INT64(tuples_returned)
104
105/* pg_stat_get_tuples_updated */
106PG_STAT_GET_RELENTRY_INT64(tuples_updated)
107
108/* pg_stat_get_vacuum_count */
109PG_STAT_GET_RELENTRY_INT64(vacuum_count)
110
111#define PG_STAT_GET_RELENTRY_FLOAT8(stat) \
112Datum \
113CppConcat(pg_stat_get_,stat)(PG_FUNCTION_ARGS) \
114{ \
115 Oid relid = PG_GETARG_OID(0); \
116 double result; \
117 PgStat_StatTabEntry *tabentry; \
118 \
119 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL) \
120 result = 0; \
121 else \
122 result = (double) (tabentry->stat); \
123 \
124 PG_RETURN_FLOAT8(result); \
125}
126
127/* pg_stat_get_total_vacuum_time */
128PG_STAT_GET_RELENTRY_FLOAT8(total_vacuum_time)
129
130/* pg_stat_get_total_autovacuum_time */
131PG_STAT_GET_RELENTRY_FLOAT8(total_autovacuum_time)
132
133/* pg_stat_get_total_analyze_time */
134PG_STAT_GET_RELENTRY_FLOAT8(total_analyze_time)
135
136/* pg_stat_get_total_autoanalyze_time */
137PG_STAT_GET_RELENTRY_FLOAT8(total_autoanalyze_time)
138
139#define PG_STAT_GET_RELENTRY_TIMESTAMPTZ(stat) \
140Datum \
141CppConcat(pg_stat_get_,stat)(PG_FUNCTION_ARGS) \
142{ \
143 Oid relid = PG_GETARG_OID(0); \
144 TimestampTz result; \
145 PgStat_StatTabEntry *tabentry; \
146 \
147 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL) \
148 result = 0; \
149 else \
150 result = tabentry->stat; \
151 \
152 if (result == 0) \
153 PG_RETURN_NULL(); \
154 else \
155 PG_RETURN_TIMESTAMPTZ(result); \
156}
157
158/* pg_stat_get_last_analyze_time */
159PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_analyze_time)
160
161/* pg_stat_get_last_autoanalyze_time */
162PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_autoanalyze_time)
163
164/* pg_stat_get_last_autovacuum_time */
165PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_autovacuum_time)
166
167/* pg_stat_get_last_vacuum_time */
168PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_vacuum_time)
169
170/* pg_stat_get_lastscan */
172
173/* pg_stat_get_stat_reset_time */
175
176Datum
186
187/* convert counter from microsec to millisec for display */
188#define PG_STAT_GET_FUNCENTRY_FLOAT8_MS(stat) \
189Datum \
190CppConcat(pg_stat_get_function_,stat)(PG_FUNCTION_ARGS) \
191{ \
192 Oid funcid = PG_GETARG_OID(0); \
193 double result; \
194 PgStat_StatFuncEntry *funcentry; \
195 \
196 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL) \
197 PG_RETURN_NULL(); \
198 result = ((double) funcentry->stat) / 1000.0; \
199 PG_RETURN_FLOAT8(result); \
200}
201
202/* pg_stat_get_function_total_time */
204
205/* pg_stat_get_function_self_time */
207
208Datum
225
226Datum
228{
230 int *fctx;
231
232 /* stuff done only on the first call of the function */
233 if (SRF_IS_FIRSTCALL())
234 {
235 /* create a function context for cross-call persistence */
237
238 fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
239 sizeof(int));
240 funcctx->user_fctx = fctx;
241
242 fctx[0] = 0;
243 }
244
245 /* stuff done on every call of the function */
247 fctx = funcctx->user_fctx;
248
249 fctx[0] += 1;
250
251 /*
252 * We recheck pgstat_fetch_stat_numbackends() each time through, just in
253 * case the local status data has been refreshed since we started. It's
254 * plenty cheap enough if not. If a refresh does happen, we'll likely
255 * miss or duplicate some backend IDs, but we're content not to crash.
256 * (Refreshing midway through such a query would be problematic usage
257 * anyway, since the backend IDs we've already returned might no longer
258 * refer to extant sessions.)
259 */
261 {
262 /* do when there is more left to send */
264
266 }
267 else
268 {
269 /* do when there is no more left */
271 }
272}
273
274/*
275 * Returns command progress information for the named command.
276 */
277Datum
279{
280#define PG_STAT_GET_PROGRESS_COLS PGSTAT_NUM_PROGRESS_PARAM + 3
282 int curr_backend;
283 char *cmd = text_to_cstring(PG_GETARG_TEXT_PP(0));
284 ProgressCommandType cmdtype;
285 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
286
287 /* Translate command name into command type code. */
288 if (pg_strcasecmp(cmd, "VACUUM") == 0)
289 cmdtype = PROGRESS_COMMAND_VACUUM;
290 else if (pg_strcasecmp(cmd, "ANALYZE") == 0)
291 cmdtype = PROGRESS_COMMAND_ANALYZE;
292 else if (pg_strcasecmp(cmd, "REPACK") == 0)
293 cmdtype = PROGRESS_COMMAND_REPACK;
294 else if (pg_strcasecmp(cmd, "CREATE INDEX") == 0)
296 else if (pg_strcasecmp(cmd, "BASEBACKUP") == 0)
298 else if (pg_strcasecmp(cmd, "COPY") == 0)
299 cmdtype = PROGRESS_COMMAND_COPY;
300 else if (pg_strcasecmp(cmd, "DATACHECKSUMS") == 0)
302 else
305 errmsg("invalid command name: \"%s\"", cmd)));
306
307 InitMaterializedSRF(fcinfo, 0);
308
309 /* 1-based index */
311 {
315 bool nulls[PG_STAT_GET_PROGRESS_COLS] = {0};
316 int i;
317
319 beentry = &local_beentry->backendStatus;
320
321 /*
322 * Report values for only those backends which are running the given
323 * command.
324 */
325 if (beentry->st_progress_command != cmdtype)
326 continue;
327
328 /* Value available to all callers */
329 values[0] = Int32GetDatum(beentry->st_procpid);
330 values[1] = ObjectIdGetDatum(beentry->st_databaseid);
331
332 /* show rest of the values including relid only to role members */
333 if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
334 {
335 values[2] = ObjectIdGetDatum(beentry->st_progress_command_target);
336 for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
337 values[i + 3] = Int64GetDatum(beentry->st_progress_param[i]);
338 }
339 else
340 {
341 nulls[2] = true;
342 for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
343 nulls[i + 3] = true;
344 }
345
346 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
347 }
348
349 return (Datum) 0;
350}
351
352/*
353 * Returns activity of PG backends.
354 */
355Datum
357{
358#define PG_STAT_GET_ACTIVITY_COLS 31
360 int curr_backend;
361 int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
362 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
363
364 InitMaterializedSRF(fcinfo, 0);
365
366 /* 1-based index */
368 {
369 /* for each row */
371 bool nulls[PG_STAT_GET_ACTIVITY_COLS] = {0};
374 PGPROC *proc;
375 const char *wait_event_type = NULL;
376 const char *wait_event = NULL;
377
378 /* Get the next one in the list */
380 beentry = &local_beentry->backendStatus;
381
382 /* If looking for specific PID, ignore all the others */
383 if (pid != -1 && beentry->st_procpid != pid)
384 continue;
385
386 /* Values available to all callers */
387 if (beentry->st_databaseid != InvalidOid)
388 values[0] = ObjectIdGetDatum(beentry->st_databaseid);
389 else
390 nulls[0] = true;
391
392 values[1] = Int32GetDatum(beentry->st_procpid);
393
394 if (beentry->st_userid != InvalidOid)
395 values[2] = ObjectIdGetDatum(beentry->st_userid);
396 else
397 nulls[2] = true;
398
399 if (beentry->st_appname)
400 values[3] = CStringGetTextDatum(beentry->st_appname);
401 else
402 nulls[3] = true;
403
404 if (TransactionIdIsValid(local_beentry->backend_xid))
405 values[15] = TransactionIdGetDatum(local_beentry->backend_xid);
406 else
407 nulls[15] = true;
408
409 if (TransactionIdIsValid(local_beentry->backend_xmin))
410 values[16] = TransactionIdGetDatum(local_beentry->backend_xmin);
411 else
412 nulls[16] = true;
413
414 /* Values only available to role member or pg_read_all_stats */
415 if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
416 {
417 char *clipped_activity;
418
419 switch (beentry->st_state)
420 {
421 case STATE_STARTING:
422 values[4] = CStringGetTextDatum("starting");
423 break;
424 case STATE_IDLE:
425 values[4] = CStringGetTextDatum("idle");
426 break;
427 case STATE_RUNNING:
428 values[4] = CStringGetTextDatum("active");
429 break;
431 values[4] = CStringGetTextDatum("idle in transaction");
432 break;
433 case STATE_FASTPATH:
434 values[4] = CStringGetTextDatum("fastpath function call");
435 break;
437 values[4] = CStringGetTextDatum("idle in transaction (aborted)");
438 break;
439 case STATE_DISABLED:
440 values[4] = CStringGetTextDatum("disabled");
441 break;
442 case STATE_UNDEFINED:
443 nulls[4] = true;
444 break;
445 }
446
450
451 /* leader_pid */
452 nulls[29] = true;
453
454 proc = BackendPidGetProc(beentry->st_procpid);
455
456 if (proc == NULL && (beentry->st_backendType != B_BACKEND))
457 {
458 /*
459 * For an auxiliary process, retrieve process info from
460 * AuxiliaryProcs stored in shared-memory.
461 */
462 proc = AuxiliaryPidGetProc(beentry->st_procpid);
463 }
464
465 /*
466 * If a PGPROC entry was retrieved, display wait events and lock
467 * group leader or apply leader information if any. To avoid
468 * extra overhead, no extra lock is being held, so there is no
469 * guarantee of consistency across multiple rows.
470 */
471 if (proc != NULL)
472 {
474 PGPROC *leader;
475
479
480 leader = proc->lockGroupLeader;
481
482 /*
483 * Show the leader only for active parallel workers. This
484 * leaves the field as NULL for the leader of a parallel group
485 * or the leader of parallel apply workers.
486 */
487 if (leader && leader->pid != beentry->st_procpid)
488 {
489 values[29] = Int32GetDatum(leader->pid);
490 nulls[29] = false;
491 }
492 else if (beentry->st_backendType == B_BG_WORKER)
493 {
494 int leader_pid = GetLeaderApplyWorkerPid(beentry->st_procpid);
495
496 if (leader_pid != InvalidPid)
497 {
498 values[29] = Int32GetDatum(leader_pid);
499 nulls[29] = false;
500 }
501 }
502 }
503
504 if (wait_event_type)
506 else
507 nulls[6] = true;
508
509 if (wait_event)
511 else
512 nulls[7] = true;
513
514 /*
515 * Don't expose transaction time for walsenders; it confuses
516 * monitoring, particularly because we don't keep the time up-to-
517 * date.
518 */
519 if (beentry->st_xact_start_timestamp != 0 &&
520 beentry->st_backendType != B_WAL_SENDER)
521 values[8] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
522 else
523 nulls[8] = true;
524
525 if (beentry->st_activity_start_timestamp != 0)
526 values[9] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
527 else
528 nulls[9] = true;
529
530 if (beentry->st_proc_start_timestamp != 0)
531 values[10] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
532 else
533 nulls[10] = true;
534
535 if (beentry->st_state_start_timestamp != 0)
536 values[11] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
537 else
538 nulls[11] = true;
539
540 /* A zeroed client addr means we don't know */
541 if (pg_memory_is_all_zeros(&beentry->st_clientaddr,
542 sizeof(beentry->st_clientaddr)))
543 {
544 nulls[12] = true;
545 nulls[13] = true;
546 nulls[14] = true;
547 }
548 else
549 {
550 if (beentry->st_clientaddr.addr.ss_family == AF_INET ||
551 beentry->st_clientaddr.addr.ss_family == AF_INET6)
552 {
553 char remote_host[NI_MAXHOST];
554 char remote_port[NI_MAXSERV];
555 int ret;
556
557 remote_host[0] = '\0';
558 remote_port[0] = '\0';
559 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
560 beentry->st_clientaddr.salen,
561 remote_host, sizeof(remote_host),
562 remote_port, sizeof(remote_port),
564 if (ret == 0)
565 {
566 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
568 CStringGetDatum(remote_host));
569 if (beentry->st_clienthostname &&
570 beentry->st_clienthostname[0])
571 values[13] = CStringGetTextDatum(beentry->st_clienthostname);
572 else
573 nulls[13] = true;
574 values[14] = Int32GetDatum(atoi(remote_port));
575 }
576 else
577 {
578 nulls[12] = true;
579 nulls[13] = true;
580 nulls[14] = true;
581 }
582 }
583 else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
584 {
585 /*
586 * Unix sockets always reports NULL for host and -1 for
587 * port, so it's possible to tell the difference to
588 * connections we have no permissions to view, or with
589 * errors.
590 */
591 nulls[12] = true;
592 nulls[13] = true;
593 values[14] = Int32GetDatum(-1);
594 }
595 else
596 {
597 /* Unknown address type, should never happen */
598 nulls[12] = true;
599 nulls[13] = true;
600 nulls[14] = true;
601 }
602 }
603 /* Add backend type */
604 if (beentry->st_backendType == B_BG_WORKER)
605 {
606 const char *bgw_type;
607
608 bgw_type = GetBackgroundWorkerTypeByPid(beentry->st_procpid);
609 if (bgw_type)
610 values[17] = CStringGetTextDatum(bgw_type);
611 else
612 nulls[17] = true;
613 }
614 else
615 values[17] =
617
618 /* SSL information */
619 if (beentry->st_ssl)
620 {
621 values[18] = BoolGetDatum(true); /* ssl */
622 values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
623 values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
624 values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
625
626 if (beentry->st_sslstatus->ssl_client_dn[0])
627 values[22] = CStringGetTextDatum(beentry->st_sslstatus->ssl_client_dn);
628 else
629 nulls[22] = true;
630
631 if (beentry->st_sslstatus->ssl_client_serial[0])
633 CStringGetDatum(beentry->st_sslstatus->ssl_client_serial),
635 Int32GetDatum(-1));
636 else
637 nulls[23] = true;
638
639 if (beentry->st_sslstatus->ssl_issuer_dn[0])
640 values[24] = CStringGetTextDatum(beentry->st_sslstatus->ssl_issuer_dn);
641 else
642 nulls[24] = true;
643 }
644 else
645 {
646 values[18] = BoolGetDatum(false); /* ssl */
647 nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = true;
648 }
649
650 /* GSSAPI information */
651 if (beentry->st_gss)
652 {
653 values[25] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */
654 values[26] = CStringGetTextDatum(beentry->st_gssstatus->gss_princ);
655 values[27] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */
656 values[28] = BoolGetDatum(beentry->st_gssstatus->gss_delegation); /* GSS credentials
657 * delegated */
658 }
659 else
660 {
661 values[25] = BoolGetDatum(false); /* gss_auth */
662 nulls[26] = true; /* No GSS principal */
663 values[27] = BoolGetDatum(false); /* GSS Encryption not in
664 * use */
665 values[28] = BoolGetDatum(false); /* GSS credentials not
666 * delegated */
667 }
668 if (beentry->st_query_id == INT64CONST(0))
669 nulls[30] = true;
670 else
671 values[30] = Int64GetDatum(beentry->st_query_id);
672 }
673 else
674 {
675 /* No permissions to view data about this session */
676 values[5] = CStringGetTextDatum("<insufficient privilege>");
677 nulls[4] = true;
678 nulls[6] = true;
679 nulls[7] = true;
680 nulls[8] = true;
681 nulls[9] = true;
682 nulls[10] = true;
683 nulls[11] = true;
684 nulls[12] = true;
685 nulls[13] = true;
686 nulls[14] = true;
687 nulls[17] = true;
688 nulls[18] = true;
689 nulls[19] = true;
690 nulls[20] = true;
691 nulls[21] = true;
692 nulls[22] = true;
693 nulls[23] = true;
694 nulls[24] = true;
695 nulls[25] = true;
696 nulls[26] = true;
697 nulls[27] = true;
698 nulls[28] = true;
699 nulls[29] = true;
700 nulls[30] = true;
701 }
702
703 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
704
705 /* If only a single backend was requested, and we found it, break. */
706 if (pid != -1)
707 break;
708 }
709
710 return (Datum) 0;
711}
712
713
714Datum
719
720
721Datum
723{
724 int32 procNumber = PG_GETARG_INT32(0);
726
727 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
729
730 PG_RETURN_INT32(beentry->st_procpid);
731}
732
733
734Datum
736{
737 int32 procNumber = PG_GETARG_INT32(0);
739
740 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
742
743 PG_RETURN_OID(beentry->st_databaseid);
744}
745
746
747Datum
758
759Datum
761{
762#define PG_STAT_GET_SUBXACT_COLS 2
763 TupleDesc tupdesc;
765 bool nulls[PG_STAT_GET_SUBXACT_COLS] = {0};
766 int32 procNumber = PG_GETARG_INT32(0);
768
769 /* Initialise attributes information in the tuple descriptor */
771 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subxact_count",
772 INT4OID, -1, 0);
773 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "subxact_overflow",
774 BOOLOID, -1, 0);
775
776 TupleDescFinalize(tupdesc);
777 BlessTupleDesc(tupdesc);
778
780 {
781 /* Fill values and NULLs */
782 values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
783 values[1] = BoolGetDatum(local_beentry->backend_subxact_overflowed);
784 }
785 else
786 {
787 nulls[0] = true;
788 nulls[1] = true;
789 }
790
791 /* Returns the record as Datum */
793}
794
795Datum
797{
798 int32 procNumber = PG_GETARG_INT32(0);
800 const char *activity;
801 char *clipped_activity;
802 text *ret;
803
804 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
805 activity = "<backend information not available>";
806 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
807 activity = "<insufficient privilege>";
808 else if (*(beentry->st_activity_raw) == '\0')
809 activity = "<command string not enabled>";
810 else
811 activity = beentry->st_activity_raw;
812
816
817 PG_RETURN_TEXT_P(ret);
818}
819
820Datum
822{
823 int32 procNumber = PG_GETARG_INT32(0);
825 PGPROC *proc;
826 const char *wait_event_type = NULL;
827
828 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
829 wait_event_type = "<backend information not available>";
830 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
831 wait_event_type = "<insufficient privilege>";
832 else
833 {
834 proc = BackendPidGetProc(beentry->st_procpid);
835 if (!proc)
836 proc = AuxiliaryPidGetProc(beentry->st_procpid);
837 if (proc)
839 }
840
841 if (!wait_event_type)
843
845}
846
847Datum
849{
850 int32 procNumber = PG_GETARG_INT32(0);
852 PGPROC *proc;
853 const char *wait_event = NULL;
854
855 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
856 wait_event = "<backend information not available>";
857 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
858 wait_event = "<insufficient privilege>";
859 else
860 {
861 proc = BackendPidGetProc(beentry->st_procpid);
862 if (!proc)
863 proc = AuxiliaryPidGetProc(beentry->st_procpid);
864 if (proc)
866 }
867
868 if (!wait_event)
870
872}
873
874
875Datum
877{
878 int32 procNumber = PG_GETARG_INT32(0);
881
882 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
884
885 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
887
888 result = beentry->st_activity_start_timestamp;
889
890 /*
891 * No time recorded for start of current query -- this is the case if the
892 * user hasn't enabled query-level stats collection.
893 */
894 if (result == 0)
896
898}
899
900
901Datum
903{
904 int32 procNumber = PG_GETARG_INT32(0);
907
908 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
910
911 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
913
914 result = beentry->st_xact_start_timestamp;
915
916 if (result == 0) /* not in a transaction */
918
920}
921
922
923Datum
925{
926 int32 procNumber = PG_GETARG_INT32(0);
929
930 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
932
933 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
935
936 result = beentry->st_proc_start_timestamp;
937
938 if (result == 0) /* probably can't happen? */
940
942}
943
944
945Datum
947{
948 int32 procNumber = PG_GETARG_INT32(0);
950 char remote_host[NI_MAXHOST];
951 int ret;
952
953 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
955
956 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
958
959 /* A zeroed client addr means we don't know */
960 if (pg_memory_is_all_zeros(&beentry->st_clientaddr,
961 sizeof(beentry->st_clientaddr)))
963
964 switch (beentry->st_clientaddr.addr.ss_family)
965 {
966 case AF_INET:
967 case AF_INET6:
968 break;
969 default:
971 }
972
973 remote_host[0] = '\0';
974 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
975 beentry->st_clientaddr.salen,
976 remote_host, sizeof(remote_host),
977 NULL, 0,
979 if (ret != 0)
981
982 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
983
985 CStringGetDatum(remote_host)));
986}
987
988Datum
990{
991 int32 procNumber = PG_GETARG_INT32(0);
993 char remote_port[NI_MAXSERV];
994 int ret;
995
996 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
998
999 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
1001
1002 /* A zeroed client addr means we don't know */
1003 if (pg_memory_is_all_zeros(&beentry->st_clientaddr,
1004 sizeof(beentry->st_clientaddr)))
1006
1007 switch (beentry->st_clientaddr.addr.ss_family)
1008 {
1009 case AF_INET:
1010 case AF_INET6:
1011 break;
1012 case AF_UNIX:
1013 PG_RETURN_INT32(-1);
1014 default:
1016 }
1017
1018 remote_port[0] = '\0';
1019 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
1020 beentry->st_clientaddr.salen,
1021 NULL, 0,
1022 remote_port, sizeof(remote_port),
1024 if (ret != 0)
1026
1028 CStringGetDatum(remote_port)));
1029}
1030
1031
1032Datum
1034{
1035 Oid dbid = PG_GETARG_OID(0);
1036 int32 result;
1038 int idx;
1039
1040 result = 0;
1041 for (idx = 1; idx <= tot_backends; idx++)
1042 {
1044
1045 if (local_beentry->backendStatus.st_databaseid == dbid)
1046 result++;
1047 }
1048
1050}
1051
1052
1053#define PG_STAT_GET_DBENTRY_INT64(stat) \
1054Datum \
1055CppConcat(pg_stat_get_db_,stat)(PG_FUNCTION_ARGS) \
1056{ \
1057 Oid dbid = PG_GETARG_OID(0); \
1058 int64 result; \
1059 PgStat_StatDBEntry *dbentry; \
1060 \
1061 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) \
1062 result = 0; \
1063 else \
1064 result = (int64) (dbentry->stat); \
1065 \
1066 PG_RETURN_INT64(result); \
1067}
1068
1069/* pg_stat_get_db_blocks_fetched */
1070PG_STAT_GET_DBENTRY_INT64(blocks_fetched)
1071
1072/* pg_stat_get_db_blocks_hit */
1073PG_STAT_GET_DBENTRY_INT64(blocks_hit)
1074
1075/* pg_stat_get_db_conflict_bufferpin */
1076PG_STAT_GET_DBENTRY_INT64(conflict_bufferpin)
1077
1078/* pg_stat_get_db_conflict_lock */
1079PG_STAT_GET_DBENTRY_INT64(conflict_lock)
1080
1081/* pg_stat_get_db_conflict_snapshot */
1082PG_STAT_GET_DBENTRY_INT64(conflict_snapshot)
1083
1084/* pg_stat_get_db_conflict_startup_deadlock */
1085PG_STAT_GET_DBENTRY_INT64(conflict_startup_deadlock)
1086
1087/* pg_stat_get_db_conflict_tablespace */
1088PG_STAT_GET_DBENTRY_INT64(conflict_tablespace)
1089
1090/* pg_stat_get_db_deadlocks */
1092
1093/* pg_stat_get_db_sessions */
1095
1096/* pg_stat_get_db_sessions_abandoned */
1097PG_STAT_GET_DBENTRY_INT64(sessions_abandoned)
1098
1099/* pg_stat_get_db_sessions_fatal */
1100PG_STAT_GET_DBENTRY_INT64(sessions_fatal)
1101
1102/* pg_stat_get_db_sessions_killed */
1103PG_STAT_GET_DBENTRY_INT64(sessions_killed)
1104
1105/* pg_stat_get_db_parallel_workers_to_launch */
1106PG_STAT_GET_DBENTRY_INT64(parallel_workers_to_launch)
1107
1108/* pg_stat_get_db_parallel_workers_launched */
1109PG_STAT_GET_DBENTRY_INT64(parallel_workers_launched)
1110
1111/* pg_stat_get_db_temp_bytes */
1112PG_STAT_GET_DBENTRY_INT64(temp_bytes)
1113
1114/* pg_stat_get_db_temp_files */
1115PG_STAT_GET_DBENTRY_INT64(temp_files)
1116
1117/* pg_stat_get_db_tuples_deleted */
1118PG_STAT_GET_DBENTRY_INT64(tuples_deleted)
1119
1120/* pg_stat_get_db_tuples_fetched */
1121PG_STAT_GET_DBENTRY_INT64(tuples_fetched)
1122
1123/* pg_stat_get_db_tuples_inserted */
1124PG_STAT_GET_DBENTRY_INT64(tuples_inserted)
1125
1126/* pg_stat_get_db_tuples_returned */
1127PG_STAT_GET_DBENTRY_INT64(tuples_returned)
1128
1129/* pg_stat_get_db_tuples_updated */
1130PG_STAT_GET_DBENTRY_INT64(tuples_updated)
1131
1132/* pg_stat_get_db_xact_commit */
1133PG_STAT_GET_DBENTRY_INT64(xact_commit)
1134
1135/* pg_stat_get_db_xact_rollback */
1136PG_STAT_GET_DBENTRY_INT64(xact_rollback)
1137
1138/* pg_stat_get_db_conflict_logicalslot */
1139PG_STAT_GET_DBENTRY_INT64(conflict_logicalslot)
1140
1141Datum
1143{
1144 Oid dbid = PG_GETARG_OID(0);
1147
1148 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1149 result = 0;
1150 else
1152
1153 if (result == 0)
1155 else
1157}
1158
1159
1160Datum
1162{
1163 Oid dbid = PG_GETARG_OID(0);
1164 int64 result;
1166
1167 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1168 result = 0;
1169 else
1170 result = (int64) (dbentry->conflict_tablespace +
1171 dbentry->conflict_lock +
1172 dbentry->conflict_snapshot +
1173 dbentry->conflict_logicalslot +
1174 dbentry->conflict_bufferpin +
1175 dbentry->conflict_startup_deadlock);
1176
1178}
1179
1180Datum
1182{
1183 Oid dbid = PG_GETARG_OID(0);
1184 int64 result;
1186
1187 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1188 result = 0;
1189 else
1190 result = (int64) (dbentry->checksum_failures);
1191
1193}
1194
1195Datum
1197{
1198 Oid dbid = PG_GETARG_OID(0);
1201
1202 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1203 result = 0;
1204 else
1206
1207 if (result == 0)
1209 else
1211}
1212
1213/* convert counter from microsec to millisec for display */
1214#define PG_STAT_GET_DBENTRY_FLOAT8_MS(stat) \
1215Datum \
1216CppConcat(pg_stat_get_db_,stat)(PG_FUNCTION_ARGS) \
1217{ \
1218 Oid dbid = PG_GETARG_OID(0); \
1219 double result; \
1220 PgStat_StatDBEntry *dbentry; \
1221 \
1222 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) \
1223 result = 0; \
1224 else \
1225 result = ((double) dbentry->stat) / 1000.0; \
1226 \
1227 PG_RETURN_FLOAT8(result); \
1228}
1229
1230/* pg_stat_get_db_active_time */
1232
1233/* pg_stat_get_db_blk_read_time */
1234PG_STAT_GET_DBENTRY_FLOAT8_MS(blk_read_time)
1235
1236/* pg_stat_get_db_blk_write_time */
1237PG_STAT_GET_DBENTRY_FLOAT8_MS(blk_write_time)
1238
1239/* pg_stat_get_db_idle_in_transaction_time */
1240PG_STAT_GET_DBENTRY_FLOAT8_MS(idle_in_transaction_time)
1241
1242/* pg_stat_get_db_session_time */
1244
1245Datum
1250
1251Datum
1256
1257Datum
1262
1263Datum
1268
1269Datum
1274
1275Datum
1280
1281Datum
1286
1287Datum
1292
1293Datum
1298
1299Datum
1304
1305Datum
1307{
1308 /* time is already in msec, just convert to double for presentation */
1309 PG_RETURN_FLOAT8((double)
1310 pgstat_fetch_stat_checkpointer()->write_time);
1311}
1312
1313Datum
1315{
1316 /* time is already in msec, just convert to double for presentation */
1317 PG_RETURN_FLOAT8((double)
1318 pgstat_fetch_stat_checkpointer()->sync_time);
1319}
1320
1321Datum
1326
1327Datum
1332
1333Datum
1338
1339/*
1340* When adding a new column to the pg_stat_io view and the
1341* pg_stat_get_backend_io() function, add a new enum value here above
1342* IO_NUM_COLUMNS.
1343*/
1369
1370/*
1371 * When adding a new IOOp, add a new io_stat_col and add a case to this
1372 * function returning the corresponding io_stat_col.
1373 */
1374static io_stat_col
1376{
1377 switch (io_op)
1378 {
1379 case IOOP_EVICT:
1380 return IO_COL_EVICTIONS;
1381 case IOOP_EXTEND:
1382 return IO_COL_EXTENDS;
1383 case IOOP_FSYNC:
1384 return IO_COL_FSYNCS;
1385 case IOOP_HIT:
1386 return IO_COL_HITS;
1387 case IOOP_READ:
1388 return IO_COL_READS;
1389 case IOOP_REUSE:
1390 return IO_COL_REUSES;
1391 case IOOP_WRITE:
1392 return IO_COL_WRITES;
1393 case IOOP_WRITEBACK:
1394 return IO_COL_WRITEBACKS;
1395 }
1396
1397 elog(ERROR, "unrecognized IOOp value: %d", io_op);
1399}
1400
1401/*
1402 * Get the number of the column containing IO bytes for the specified IOOp.
1403 * If an IOOp is not tracked in bytes, IO_COL_INVALID is returned.
1404 */
1405static io_stat_col
1407{
1408 switch (io_op)
1409 {
1410 case IOOP_EXTEND:
1411 return IO_COL_EXTEND_BYTES;
1412 case IOOP_READ:
1413 return IO_COL_READ_BYTES;
1414 case IOOP_WRITE:
1415 return IO_COL_WRITE_BYTES;
1416 case IOOP_EVICT:
1417 case IOOP_FSYNC:
1418 case IOOP_HIT:
1419 case IOOP_REUSE:
1420 case IOOP_WRITEBACK:
1421 return IO_COL_INVALID;
1422 }
1423
1424 elog(ERROR, "unrecognized IOOp value: %d", io_op);
1426}
1427
1428/*
1429 * Get the number of the column containing IO times for the specified IOOp.
1430 * If an op has no associated time, IO_COL_INVALID is returned.
1431 */
1432static io_stat_col
1434{
1435 switch (io_op)
1436 {
1437 case IOOP_READ:
1438 return IO_COL_READ_TIME;
1439 case IOOP_WRITE:
1440 return IO_COL_WRITE_TIME;
1441 case IOOP_WRITEBACK:
1442 return IO_COL_WRITEBACK_TIME;
1443 case IOOP_EXTEND:
1444 return IO_COL_EXTEND_TIME;
1445 case IOOP_FSYNC:
1446 return IO_COL_FSYNC_TIME;
1447 case IOOP_EVICT:
1448 case IOOP_HIT:
1449 case IOOP_REUSE:
1450 return IO_COL_INVALID;
1451 }
1452
1453 elog(ERROR, "unrecognized IOOp value: %d", io_op);
1455}
1456
1457static inline double
1459{
1460 return val_ms * (double) 0.001;
1461}
1462
1463/*
1464 * pg_stat_io_build_tuples
1465 *
1466 * Helper routine for pg_stat_get_io() and pg_stat_get_backend_io()
1467 * filling a result tuplestore with one tuple for each object and each
1468 * context supported by the caller, based on the contents of bktype_stats.
1469 */
1470static void
1474 TimestampTz stat_reset_timestamp)
1475{
1477
1478 for (int io_obj = 0; io_obj < IOOBJECT_NUM_TYPES; io_obj++)
1479 {
1481
1483 {
1485
1487 bool nulls[IO_NUM_COLUMNS] = {0};
1488
1489 /*
1490 * Some combinations of BackendType, IOObject, and IOContext are
1491 * not valid for any type of IOOp. In such cases, omit the entire
1492 * row from the view.
1493 */
1495 continue;
1496
1500 if (stat_reset_timestamp != 0)
1501 values[IO_COL_RESET_TIME] = TimestampTzGetDatum(stat_reset_timestamp);
1502 else
1503 nulls[IO_COL_RESET_TIME] = true;
1504
1505 for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
1506 {
1510
1511 /*
1512 * Some combinations of BackendType and IOOp, of IOContext and
1513 * IOOp, and of IOObject and IOOp are not tracked. Set these
1514 * cells in the view NULL.
1515 */
1517 {
1518 PgStat_Counter count =
1520
1521 values[op_idx] = Int64GetDatum(count);
1522 }
1523 else
1524 nulls[op_idx] = true;
1525
1526 if (!nulls[op_idx])
1527 {
1528 /* not every operation is timed */
1529 if (time_idx != IO_COL_INVALID)
1530 {
1531 PgStat_Counter time =
1533
1535 }
1536
1537 /* not every IO is tracked in bytes */
1538 if (byte_idx != IO_COL_INVALID)
1539 {
1540 char buf[256];
1541 PgStat_Counter byte =
1543
1544 /* Convert to numeric */
1545 snprintf(buf, sizeof buf, INT64_FORMAT, byte);
1549 Int32GetDatum(-1));
1550 }
1551 }
1552 else
1553 {
1554 if (time_idx != IO_COL_INVALID)
1555 nulls[time_idx] = true;
1556 if (byte_idx != IO_COL_INVALID)
1557 nulls[byte_idx] = true;
1558 }
1559 }
1560
1561 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
1562 values, nulls);
1563 }
1564 }
1565}
1566
1567Datum
1569{
1572
1573 InitMaterializedSRF(fcinfo, 0);
1574 rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1575
1577
1578 for (int bktype = 0; bktype < BACKEND_NUM_TYPES; bktype++)
1579 {
1581
1582 /*
1583 * In Assert builds, we can afford an extra loop through all of the
1584 * counters (in pg_stat_io_build_tuples()), checking that only
1585 * expected stats are non-zero, since it keeps the non-Assert code
1586 * cleaner.
1587 */
1589
1590 /*
1591 * For those BackendTypes without IO Operation stats, skip
1592 * representing them in the view altogether.
1593 */
1595 continue;
1596
1597 /* save tuples with data from this PgStat_BktypeIO */
1599 backends_io_stats->stat_reset_timestamp);
1600 }
1601
1602 return (Datum) 0;
1603}
1604
1605/*
1606 * Returns I/O statistics for a backend with given PID.
1607 */
1608Datum
1610{
1613 int pid;
1616
1617 InitMaterializedSRF(fcinfo, 0);
1618 rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1619
1620 pid = PG_GETARG_INT32(0);
1622
1623 if (!backend_stats)
1624 return (Datum) 0;
1625
1626 bktype_stats = &backend_stats->io_stats;
1627
1628 /*
1629 * In Assert builds, we can afford an extra loop through all of the
1630 * counters (in pg_stat_io_build_tuples()), checking that only expected
1631 * stats are non-zero, since it keeps the non-Assert code cleaner.
1632 */
1634
1635 /* save tuples with data from this PgStat_BktypeIO */
1637 backend_stats->stat_reset_timestamp);
1638 return (Datum) 0;
1639}
1640
1641/*
1642 * pg_stat_wal_build_tuple
1643 *
1644 * Helper routine for pg_stat_get_wal() and pg_stat_get_backend_wal()
1645 * returning one tuple based on the contents of wal_counters.
1646 */
1647static Datum
1649 TimestampTz stat_reset_timestamp)
1650{
1651#define PG_STAT_WAL_COLS 6
1652 TupleDesc tupdesc;
1654 bool nulls[PG_STAT_WAL_COLS] = {0};
1655 char buf[256];
1656
1657 /* Initialise attributes information in the tuple descriptor */
1659 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "wal_records",
1660 INT8OID, -1, 0);
1661 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "wal_fpi",
1662 INT8OID, -1, 0);
1663 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "wal_bytes",
1664 NUMERICOID, -1, 0);
1665 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_fpi_bytes",
1666 NUMERICOID, -1, 0);
1667 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "wal_buffers_full",
1668 INT8OID, -1, 0);
1669 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "stats_reset",
1670 TIMESTAMPTZOID, -1, 0);
1671
1672 TupleDescFinalize(tupdesc);
1673 BlessTupleDesc(tupdesc);
1674
1675 /* Fill values and NULLs */
1676 values[0] = Int64GetDatum(wal_counters.wal_records);
1677 values[1] = Int64GetDatum(wal_counters.wal_fpi);
1678
1679 /* Convert to numeric. */
1680 snprintf(buf, sizeof buf, UINT64_FORMAT, wal_counters.wal_bytes);
1684 Int32GetDatum(-1));
1685
1686 snprintf(buf, sizeof buf, UINT64_FORMAT, wal_counters.wal_fpi_bytes);
1690 Int32GetDatum(-1));
1691
1692 values[4] = Int64GetDatum(wal_counters.wal_buffers_full);
1693
1694 if (stat_reset_timestamp != 0)
1695 values[5] = TimestampTzGetDatum(stat_reset_timestamp);
1696 else
1697 nulls[5] = true;
1698
1699 /* Returns the record as Datum */
1701}
1702
1703/*
1704 * Returns WAL statistics for a backend with given PID.
1705 */
1706Datum
1708{
1709 int pid;
1712
1713 pid = PG_GETARG_INT32(0);
1715
1716 if (!backend_stats)
1718
1719 bktype_stats = backend_stats->wal_counters;
1720
1721 /* save tuples with data from this PgStat_WalCounters */
1722 return (pg_stat_wal_build_tuple(bktype_stats, backend_stats->stat_reset_timestamp));
1723}
1724
1725/*
1726 * Returns statistics of WAL activity
1727 */
1728Datum
1730{
1732
1733 /* Get statistics about WAL activity */
1735
1736 return (pg_stat_wal_build_tuple(wal_stats->wal_counters,
1737 wal_stats->stat_reset_timestamp));
1738}
1739
1740Datum
1742{
1743#define PG_STAT_LOCK_COLS 5
1746
1747 InitMaterializedSRF(fcinfo, 0);
1748 rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1749
1751
1752 for (int lcktype = 0; lcktype <= LOCKTAG_LAST_TYPE; lcktype++)
1753 {
1754 const char *locktypename;
1756 bool nulls[PG_STAT_LOCK_COLS] = {0};
1758 int i = 0;
1759
1761
1763 values[i++] = Int64GetDatum(lck_stats->waits);
1764 values[i++] = Int64GetDatum(lck_stats->wait_time);
1765 values[i++] = Int64GetDatum(lck_stats->fastpath_exceeded);
1766 values[i] = TimestampTzGetDatum(lock_stats->stat_reset_timestamp);
1767
1768 Assert(i + 1 == PG_STAT_LOCK_COLS);
1769
1770 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
1771 }
1772
1773 return (Datum) 0;
1774}
1775
1776/*
1777 * Returns statistics of SLRU caches.
1778 */
1779Datum
1781{
1782#define PG_STAT_GET_SLRU_COLS 9
1783 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1784 int i;
1785 PgStat_SLRUStats *stats;
1786
1787 InitMaterializedSRF(fcinfo, 0);
1788
1789 /* request SLRU stats from the cumulative stats system */
1790 stats = pgstat_fetch_slru();
1791
1792 for (i = 0;; i++)
1793 {
1794 /* for each row */
1796 bool nulls[PG_STAT_GET_SLRU_COLS] = {0};
1798 const char *name;
1799
1801
1802 if (!name)
1803 break;
1804
1805 stat = stats[i];
1806
1808 values[1] = Int64GetDatum(stat.blocks_zeroed);
1809 values[2] = Int64GetDatum(stat.blocks_hit);
1810 values[3] = Int64GetDatum(stat.blocks_read);
1811 values[4] = Int64GetDatum(stat.blocks_written);
1812 values[5] = Int64GetDatum(stat.blocks_exists);
1813 values[6] = Int64GetDatum(stat.flush);
1814 values[7] = Int64GetDatum(stat.truncate);
1815 values[8] = TimestampTzGetDatum(stat.stat_reset_timestamp);
1816
1817 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
1818 }
1819
1820 return (Datum) 0;
1821}
1822
1823#define PG_STAT_GET_XACT_RELENTRY_INT64(stat) \
1824Datum \
1825CppConcat(pg_stat_get_xact_,stat)(PG_FUNCTION_ARGS) \
1826{ \
1827 Oid relid = PG_GETARG_OID(0); \
1828 int64 result; \
1829 PgStat_TableStatus *tabentry; \
1830 \
1831 if ((tabentry = find_tabstat_entry(relid)) == NULL) \
1832 result = 0; \
1833 else \
1834 result = (int64) (tabentry->counts.stat); \
1835 \
1836 PG_RETURN_INT64(result); \
1837}
1838
1839/* pg_stat_get_xact_numscans */
1841
1842/* pg_stat_get_xact_tuples_returned */
1843PG_STAT_GET_XACT_RELENTRY_INT64(tuples_returned)
1844
1845/* pg_stat_get_xact_tuples_fetched */
1846PG_STAT_GET_XACT_RELENTRY_INT64(tuples_fetched)
1847
1848/* pg_stat_get_xact_tuples_hot_updated */
1849PG_STAT_GET_XACT_RELENTRY_INT64(tuples_hot_updated)
1850
1851/* pg_stat_get_xact_tuples_newpage_updated */
1852PG_STAT_GET_XACT_RELENTRY_INT64(tuples_newpage_updated)
1853
1854/* pg_stat_get_xact_blocks_fetched */
1855PG_STAT_GET_XACT_RELENTRY_INT64(blocks_fetched)
1856
1857/* pg_stat_get_xact_blocks_hit */
1859
1860/* pg_stat_get_xact_tuples_inserted */
1861PG_STAT_GET_XACT_RELENTRY_INT64(tuples_inserted)
1862
1863/* pg_stat_get_xact_tuples_updated */
1864PG_STAT_GET_XACT_RELENTRY_INT64(tuples_updated)
1865
1866/* pg_stat_get_xact_tuples_deleted */
1867PG_STAT_GET_XACT_RELENTRY_INT64(tuples_deleted)
1868
1869Datum
1879
1880#define PG_STAT_GET_XACT_FUNCENTRY_FLOAT8_MS(stat) \
1881Datum \
1882CppConcat(pg_stat_get_xact_function_,stat)(PG_FUNCTION_ARGS) \
1883{ \
1884 Oid funcid = PG_GETARG_OID(0); \
1885 PgStat_FunctionCounts *funcentry; \
1886 \
1887 if ((funcentry = find_funcstat_entry(funcid)) == NULL) \
1888 PG_RETURN_NULL(); \
1889 PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(funcentry->stat)); \
1890}
1891
1892/* pg_stat_get_xact_function_total_time */
1894
1895/* pg_stat_get_xact_function_self_time */
1897
1898/* Get the timestamp of the current statistics snapshot */
1899Datum
1912
1913/* Discard the active statistics snapshot */
1914Datum
1921
1922
1923/* Force statistics to be reported at the next occasion */
1924Datum
1931
1932
1933/* Reset all counters for the current database */
1934Datum
1941
1942/*
1943 * Reset some shared cluster-wide counters
1944 *
1945 * When adding a new reset target, ideally the name should match that in
1946 * pgstat_kind_builtin_infos, if relevant.
1947 */
1948Datum
1950{
1951 char *target = NULL;
1952
1953 if (PG_ARGISNULL(0))
1954 {
1955 /* Reset all the statistics when nothing is specified */
1964
1966 }
1967
1969
1970 if (strcmp(target, "archiver") == 0)
1972 else if (strcmp(target, "bgwriter") == 0)
1974 else if (strcmp(target, "checkpointer") == 0)
1976 else if (strcmp(target, "io") == 0)
1978 else if (strcmp(target, "lock") == 0)
1980 else if (strcmp(target, "recovery_prefetch") == 0)
1982 else if (strcmp(target, "slru") == 0)
1984 else if (strcmp(target, "wal") == 0)
1986 else
1987 ereport(ERROR,
1989 errmsg("unrecognized reset target: \"%s\"", target),
1990 errhint("Target must be \"archiver\", \"bgwriter\", \"checkpointer\", \"io\", \"recovery_prefetch\", \"slru\", or \"wal\".")));
1991
1993}
1994
1995/*
1996 * Reset statistics for a single object, which may be of current
1997 * database or shared across all databases in the cluster.
1998 */
1999Datum
2009
2010Datum
2019
2020/*
2021 * Reset statistics of backend with given PID.
2022 */
2023Datum
2025{
2026 PGPROC *proc;
2028 ProcNumber procNumber;
2029 int backend_pid = PG_GETARG_INT32(0);
2030
2031 proc = BackendPidGetProc(backend_pid);
2032
2033 /* This could be an auxiliary process */
2034 if (!proc)
2035 proc = AuxiliaryPidGetProc(backend_pid);
2036
2037 if (!proc)
2039
2040 procNumber = GetNumberFromPGProc(proc);
2041
2043 if (!beentry)
2045
2046 /* Check if the backend type tracks statistics */
2047 if (!pgstat_tracks_backend_bktype(beentry->st_backendType))
2049
2051
2053}
2054
2055/* Reset SLRU counters (a specific one or all of them). */
2056Datum
2058{
2059 char *target = NULL;
2060
2061 if (PG_ARGISNULL(0))
2063 else
2064 {
2066 pgstat_reset_slru(target);
2067 }
2068
2070}
2071
2072/* Reset replication slots stats (a specific one or all of them). */
2073Datum
2075{
2076 char *target = NULL;
2077
2078 if (PG_ARGISNULL(0))
2080 else
2081 {
2083 pgstat_reset_replslot(target);
2084 }
2085
2087}
2088
2089/* Reset subscription stats (a specific one or all of them) */
2090Datum
2092{
2093 Oid subid;
2094
2095 if (PG_ARGISNULL(0))
2096 {
2097 /* Clear all subscription stats */
2099 }
2100 else
2101 {
2102 subid = PG_GETARG_OID(0);
2103
2104 if (!OidIsValid(subid))
2105 ereport(ERROR,
2107 errmsg("invalid subscription OID %u", subid)));
2109 }
2110
2112}
2113
2114Datum
2116{
2117 TupleDesc tupdesc;
2118 Datum values[7] = {0};
2119 bool nulls[7] = {0};
2121
2122 /* Initialise attributes information in the tuple descriptor */
2123 tupdesc = CreateTemplateTupleDesc(7);
2124 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
2125 INT8OID, -1, 0);
2126 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal",
2127 TEXTOID, -1, 0);
2128 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_archived_time",
2129 TIMESTAMPTZOID, -1, 0);
2130 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "failed_count",
2131 INT8OID, -1, 0);
2132 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_failed_wal",
2133 TEXTOID, -1, 0);
2134 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_failed_time",
2135 TIMESTAMPTZOID, -1, 0);
2136 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stats_reset",
2137 TIMESTAMPTZOID, -1, 0);
2138
2139 TupleDescFinalize(tupdesc);
2140 BlessTupleDesc(tupdesc);
2141
2142 /* Get statistics about the archiver process */
2144
2145 /* Fill values and NULLs */
2146 values[0] = Int64GetDatum(archiver_stats->archived_count);
2147 if (*(archiver_stats->last_archived_wal) == '\0')
2148 nulls[1] = true;
2149 else
2150 values[1] = CStringGetTextDatum(archiver_stats->last_archived_wal);
2151
2152 if (archiver_stats->last_archived_timestamp == 0)
2153 nulls[2] = true;
2154 else
2155 values[2] = TimestampTzGetDatum(archiver_stats->last_archived_timestamp);
2156
2157 values[3] = Int64GetDatum(archiver_stats->failed_count);
2158 if (*(archiver_stats->last_failed_wal) == '\0')
2159 nulls[4] = true;
2160 else
2161 values[4] = CStringGetTextDatum(archiver_stats->last_failed_wal);
2162
2163 if (archiver_stats->last_failed_timestamp == 0)
2164 nulls[5] = true;
2165 else
2166 values[5] = TimestampTzGetDatum(archiver_stats->last_failed_timestamp);
2167
2168 if (archiver_stats->stat_reset_timestamp == 0)
2169 nulls[6] = true;
2170 else
2171 values[6] = TimestampTzGetDatum(archiver_stats->stat_reset_timestamp);
2172
2173 /* Returns the record as Datum */
2175}
2176
2177/*
2178 * Get the statistics for the replication slot. If the slot statistics is not
2179 * available, return all-zeroes stats.
2180 */
2181Datum
2183{
2184#define PG_STAT_GET_REPLICATION_SLOT_COLS 13
2186 NameData slotname;
2187 TupleDesc tupdesc;
2189 bool nulls[PG_STAT_GET_REPLICATION_SLOT_COLS] = {0};
2192
2193 /* Initialise attributes information in the tuple descriptor */
2195 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "slot_name",
2196 TEXTOID, -1, 0);
2197 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "spill_txns",
2198 INT8OID, -1, 0);
2199 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "spill_count",
2200 INT8OID, -1, 0);
2201 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "spill_bytes",
2202 INT8OID, -1, 0);
2203 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "stream_txns",
2204 INT8OID, -1, 0);
2205 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "stream_count",
2206 INT8OID, -1, 0);
2207 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stream_bytes",
2208 INT8OID, -1, 0);
2209 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "mem_exceeded_count",
2210 INT8OID, -1, 0);
2211 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "total_txns",
2212 INT8OID, -1, 0);
2213 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "total_bytes",
2214 INT8OID, -1, 0);
2215 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "slotsync_skip_count",
2216 INT8OID, -1, 0);
2217 TupleDescInitEntry(tupdesc, (AttrNumber) 12, "slotsync_last_skip",
2218 TIMESTAMPTZOID, -1, 0);
2219 TupleDescInitEntry(tupdesc, (AttrNumber) 13, "stats_reset",
2220 TIMESTAMPTZOID, -1, 0);
2221 TupleDescFinalize(tupdesc);
2222 BlessTupleDesc(tupdesc);
2223
2225 slotent = pgstat_fetch_replslot(slotname);
2226 if (!slotent)
2227 {
2228 /*
2229 * If the slot is not found, initialise its stats. This is possible if
2230 * the create slot message is lost.
2231 */
2233 slotent = &allzero;
2234 }
2235
2236 values[0] = CStringGetTextDatum(NameStr(slotname));
2237 values[1] = Int64GetDatum(slotent->spill_txns);
2238 values[2] = Int64GetDatum(slotent->spill_count);
2239 values[3] = Int64GetDatum(slotent->spill_bytes);
2240 values[4] = Int64GetDatum(slotent->stream_txns);
2241 values[5] = Int64GetDatum(slotent->stream_count);
2242 values[6] = Int64GetDatum(slotent->stream_bytes);
2243 values[7] = Int64GetDatum(slotent->mem_exceeded_count);
2244 values[8] = Int64GetDatum(slotent->total_txns);
2245 values[9] = Int64GetDatum(slotent->total_bytes);
2246 values[10] = Int64GetDatum(slotent->slotsync_skip_count);
2247
2248 if (slotent->slotsync_last_skip == 0)
2249 nulls[11] = true;
2250 else
2251 values[11] = TimestampTzGetDatum(slotent->slotsync_last_skip);
2252
2253 if (slotent->stat_reset_timestamp == 0)
2254 nulls[12] = true;
2255 else
2256 values[12] = TimestampTzGetDatum(slotent->stat_reset_timestamp);
2257
2258 /* Returns the record as Datum */
2260}
2261
2262/*
2263 * Get the subscription statistics for the given subscription. If the
2264 * subscription statistics is not available, return all-zeros stats.
2265 */
2266Datum
2268{
2269#define PG_STAT_GET_SUBSCRIPTION_STATS_COLS 13
2270 Oid subid = PG_GETARG_OID(0);
2271 TupleDesc tupdesc;
2273 bool nulls[PG_STAT_GET_SUBSCRIPTION_STATS_COLS] = {0};
2276 int i = 0;
2277
2278 /* Get subscription stats */
2280
2281 /* Initialise attributes information in the tuple descriptor */
2283 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subid",
2284 OIDOID, -1, 0);
2285 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "apply_error_count",
2286 INT8OID, -1, 0);
2287 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "sync_seq_error_count",
2288 INT8OID, -1, 0);
2289 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "sync_table_error_count",
2290 INT8OID, -1, 0);
2291 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "confl_insert_exists",
2292 INT8OID, -1, 0);
2293 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "confl_update_origin_differs",
2294 INT8OID, -1, 0);
2295 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "confl_update_exists",
2296 INT8OID, -1, 0);
2297 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "confl_update_deleted",
2298 INT8OID, -1, 0);
2299 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "confl_update_missing",
2300 INT8OID, -1, 0);
2301 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "confl_delete_origin_differs",
2302 INT8OID, -1, 0);
2303 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "confl_delete_missing",
2304 INT8OID, -1, 0);
2305 TupleDescInitEntry(tupdesc, (AttrNumber) 12, "confl_multiple_unique_conflicts",
2306 INT8OID, -1, 0);
2307 TupleDescInitEntry(tupdesc, (AttrNumber) 13, "stats_reset",
2308 TIMESTAMPTZOID, -1, 0);
2309 TupleDescFinalize(tupdesc);
2310 BlessTupleDesc(tupdesc);
2311
2312 if (!subentry)
2313 {
2314 /* If the subscription is not found, initialise its stats */
2315 memset(&allzero, 0, sizeof(PgStat_StatSubEntry));
2316 subentry = &allzero;
2317 }
2318
2319 /* subid */
2320 values[i++] = ObjectIdGetDatum(subid);
2321
2322 /* apply_error_count */
2323 values[i++] = Int64GetDatum(subentry->apply_error_count);
2324
2325 /* sync_seq_error_count */
2326 values[i++] = Int64GetDatum(subentry->sync_seq_error_count);
2327
2328 /* sync_table_error_count */
2329 values[i++] = Int64GetDatum(subentry->sync_table_error_count);
2330
2331 /* conflict count */
2333 values[i++] = Int64GetDatum(subentry->conflict_count[nconflict]);
2334
2335 /* stats_reset */
2336 if (subentry->stat_reset_timestamp == 0)
2337 nulls[i] = true;
2338 else
2339 values[i] = TimestampTzGetDatum(subentry->stat_reset_timestamp);
2340
2342
2343 /* Returns the record as Datum */
2345}
2346
2347/*
2348 * Checks for presence of stats for object with provided kind, database oid,
2349 * object oid.
2350 *
2351 * This is useful for tests, but not really anything else. Therefore not
2352 * documented.
2353 */
2354Datum
Datum idx(PG_FUNCTION_ARGS)
Definition _int_op.c:262
int16 AttrNumber
Definition attnum.h:21
Datum numeric_in(PG_FUNCTION_ARGS)
Definition numeric.c:626
#define PGSTAT_NUM_PROGRESS_PARAM
ProgressCommandType
@ PROGRESS_COMMAND_ANALYZE
@ PROGRESS_COMMAND_CREATE_INDEX
@ PROGRESS_COMMAND_VACUUM
@ PROGRESS_COMMAND_BASEBACKUP
@ PROGRESS_COMMAND_REPACK
@ PROGRESS_COMMAND_DATACHECKSUMS
@ PROGRESS_COMMAND_COPY
int pgstat_fetch_stat_numbackends(void)
LocalPgBackendStatus * pgstat_get_local_beentry_by_proc_number(ProcNumber procNumber)
char * pgstat_clip_activity(const char *raw_activity)
LocalPgBackendStatus * pgstat_get_local_beentry_by_index(int idx)
PgBackendStatus * pgstat_get_beentry_by_proc_number(ProcNumber procNumber)
@ STATE_UNDEFINED
@ STATE_IDLEINTRANSACTION_ABORTED
@ STATE_STARTING
@ STATE_IDLE
@ STATE_IDLEINTRANSACTION
@ STATE_DISABLED
@ STATE_FASTPATH
@ STATE_RUNNING
const char * GetBackgroundWorkerTypeByPid(pid_t pid)
Definition bgworker.c:1394
static Datum values[MAXATTR]
Definition bootstrap.c:190
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define NameStr(name)
Definition c.h:835
#define INT64CONST(x)
Definition c.h:630
#define INT64_FORMAT
Definition c.h:634
#define Assert(condition)
Definition c.h:943
int64_t int64
Definition c.h:621
#define UINT64_FORMAT
Definition c.h:635
int32_t int32
Definition c.h:620
uint64_t uint64
Definition c.h:625
#define pg_unreachable()
Definition c.h:367
uint32_t uint32
Definition c.h:624
#define OidIsValid(objectId)
Definition c.h:858
bool IsSharedRelation(Oid relationId)
Definition catalog.c:304
uint32 result
#define CONFLICT_NUM_TYPES
Definition conflict.h:64
int64 TimestampTz
Definition timestamp.h:39
int errcode(int sqlerrcode)
Definition elog.c:874
int errhint(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_GETARG_TEXT_PP(n)
Definition fmgr.h:310
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369
#define PG_ARGISNULL(n)
Definition fmgr.h:209
#define PG_RETURN_INT64(x)
Definition fmgr.h:370
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:684
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_GETARG_INT64(n)
Definition fmgr.h:284
#define PG_RETURN_TEXT_P(x)
Definition fmgr.h:374
#define PG_RETURN_INT32(x)
Definition fmgr.h:355
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_RETURN_DATUM(x)
Definition fmgr.h:354
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition fmgr.h:688
#define PG_RETURN_OID(x)
Definition fmgr.h:361
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
#define PG_GETARG_TEXT_P(n)
Definition fmgr.h:337
void InitMaterializedSRF(FunctionCallInfo fcinfo, uint32 flags)
Definition funcapi.c:76
#define SRF_IS_FIRSTCALL()
Definition funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition funcapi.h:308
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition funcapi.h:306
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition funcapi.h:230
#define SRF_RETURN_DONE(_funcctx)
Definition funcapi.h:328
int MyProcPid
Definition globals.c:49
Oid MyDatabaseId
Definition globals.c:96
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1025
Datum int4in(PG_FUNCTION_ARGS)
Definition int.c:316
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition ip.c:117
int i
Definition isn.c:77
pid_t GetLeaderApplyWorkerPid(pid_t pid)
Definition launcher.c:1597
const char *const LockTagTypeNames[]
Definition lockfuncs.c:28
#define LOCKTAG_LAST_TYPE
Definition locktag.h:52
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
void pfree(void *pointer)
Definition mcxt.c:1616
static bool pg_memory_is_all_zeros(const void *ptr, size_t len)
Definition memutils.h:219
#define BACKEND_NUM_TYPES
Definition miscadmin.h:392
BackendType
Definition miscadmin.h:350
@ B_WAL_SENDER
Definition miscadmin.h:359
@ B_BG_WORKER
Definition miscadmin.h:358
@ B_BACKEND
Definition miscadmin.h:354
#define InvalidPid
Definition miscadmin.h:32
const char * GetBackendTypeDesc(BackendType backendType)
Definition miscinit.c:264
void namestrcpy(Name name, const char *str)
Definition name.c:233
void clean_ipv6_addr(int addr_family, char *addr)
Definition network.c:2028
Datum inet_in(PG_FUNCTION_ARGS)
Definition network.c:119
static char * errmsg
static char buf[DEFAULT_XLOG_SEG_SIZE]
void pgstat_reset(PgStat_Kind kind, Oid dboid, uint64 objid)
Definition pgstat.c:882
void pgstat_reset_counters(void)
Definition pgstat.c:863
void pgstat_reset_of_kind(PgStat_Kind kind)
Definition pgstat.c:904
void pgstat_force_next_flush(void)
Definition pgstat.c:842
void pgstat_clear_snapshot(void)
Definition pgstat.c:930
TimestampTz pgstat_get_stat_snapshot_timestamp(bool *have_snapshot)
Definition pgstat.c:1071
bool pgstat_have_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
Definition pgstat.c:1088
PgStat_Kind pgstat_get_kind_from_str(char *kind_str)
Definition pgstat.c:1445
#define IOOP_NUM_TYPES
Definition pgstat.h:323
#define IOCONTEXT_NUM_TYPES
Definition pgstat.h:297
IOOp
Definition pgstat.h:309
@ IOOP_EXTEND
Definition pgstat.h:318
@ IOOP_FSYNC
Definition pgstat.h:312
@ IOOP_READ
Definition pgstat.h:319
@ IOOP_WRITEBACK
Definition pgstat.h:315
@ IOOP_HIT
Definition pgstat.h:313
@ IOOP_EVICT
Definition pgstat.h:311
@ IOOP_REUSE
Definition pgstat.h:314
@ IOOP_WRITE
Definition pgstat.h:320
int64 PgStat_Counter
Definition pgstat.h:71
#define IOOBJECT_NUM_TYPES
Definition pgstat.h:286
PgStat_ArchiverStats * pgstat_fetch_stat_archiver(void)
bool pgstat_tracks_backend_bktype(BackendType bktype)
PgStat_Backend * pgstat_fetch_stat_backend_by_pid(int pid, BackendType *bktype)
PgStat_BgWriterStats * pgstat_fetch_stat_bgwriter(void)
PgStat_CheckpointerStats * pgstat_fetch_stat_checkpointer(void)
PgStat_StatDBEntry * pgstat_fetch_stat_dbentry(Oid dboid)
PgStat_StatFuncEntry * pgstat_fetch_stat_funcentry(Oid func_id)
PgStat_FunctionCounts * find_funcstat_entry(Oid func_id)
PgStat_IO * pgstat_fetch_stat_io(void)
Definition pgstat_io.c:164
const char * pgstat_get_io_context_name(IOContext io_context)
Definition pgstat_io.c:240
bool pgstat_tracks_io_bktype(BackendType bktype)
Definition pgstat_io.c:351
const char * pgstat_get_io_object_name(IOObject io_object)
Definition pgstat_io.c:261
bool pgstat_bktype_io_stats_valid(PgStat_BktypeIO *backend_io, BackendType bktype)
Definition pgstat_io.c:37
bool pgstat_tracks_io_op(BackendType bktype, IOObject io_object, IOContext io_context, IOOp io_op)
Definition pgstat_io.c:479
bool pgstat_tracks_io_object(BackendType bktype, IOObject io_object, IOContext io_context)
Definition pgstat_io.c:395
#define PGSTAT_KIND_ARCHIVER
Definition pgstat_kind.h:35
#define PGSTAT_KIND_WAL
Definition pgstat_kind.h:41
#define PgStat_Kind
Definition pgstat_kind.h:17
#define PGSTAT_KIND_BGWRITER
Definition pgstat_kind.h:36
#define PGSTAT_KIND_REPLSLOT
Definition pgstat_kind.h:30
#define PGSTAT_KIND_FUNCTION
Definition pgstat_kind.h:29
#define PGSTAT_KIND_LOCK
Definition pgstat_kind.h:39
#define PGSTAT_KIND_SLRU
Definition pgstat_kind.h:40
#define PGSTAT_KIND_RELATION
Definition pgstat_kind.h:28
#define PGSTAT_KIND_CHECKPOINTER
Definition pgstat_kind.h:37
#define PGSTAT_KIND_IO
Definition pgstat_kind.h:38
#define PGSTAT_KIND_SUBSCRIPTION
Definition pgstat_kind.h:31
#define PGSTAT_KIND_BACKEND
Definition pgstat_kind.h:32
PgStat_Lock * pgstat_fetch_stat_lock(void)
Definition pgstat_lock.c:26
void pgstat_reset_replslot(const char *name)
PgStat_StatReplSlotEntry * pgstat_fetch_replslot(NameData slotname)
PgStat_SLRUStats * pgstat_fetch_slru(void)
Definition pgstat_slru.c:91
const char * pgstat_get_slru_name(int slru_idx)
void pgstat_reset_slru(const char *name)
Definition pgstat_slru.c:45
PgStat_StatSubEntry * pgstat_fetch_stat_subscription(Oid subid)
PgStat_WalStats * pgstat_fetch_stat_wal(void)
Definition pgstat_wal.c:67
#define PG_STAT_GET_XACT_RELENTRY_INT64(stat)
Datum pg_stat_get_progress_info(PG_FUNCTION_ARGS)
Datum pg_stat_get_checkpointer_num_requested(PG_FUNCTION_ARGS)
Datum pg_stat_get_snapshot_timestamp(PG_FUNCTION_ARGS)
Datum pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
Datum pg_stat_get_db_stat_reset_time(PG_FUNCTION_ARGS)
Datum pg_stat_get_wal(PG_FUNCTION_ARGS)
Datum pg_stat_reset_replication_slot(PG_FUNCTION_ARGS)
Datum pg_stat_get_checkpointer_num_timed(PG_FUNCTION_ARGS)
#define UINT32_ACCESS_ONCE(var)
Definition pgstatfuncs.c:37
Datum pg_stat_get_activity(PG_FUNCTION_ARGS)
Datum pg_stat_get_slru(PG_FUNCTION_ARGS)
static void pg_stat_io_build_tuples(ReturnSetInfo *rsinfo, PgStat_BktypeIO *bktype_stats, BackendType bktype, TimestampTz stat_reset_timestamp)
Datum pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
Datum pg_stat_get_backend_start(PG_FUNCTION_ARGS)
Datum pg_stat_get_db_conflict_all(PG_FUNCTION_ARGS)
Datum pg_stat_get_subscription_stats(PG_FUNCTION_ARGS)
#define PG_STAT_GET_SLRU_COLS
#define PG_STAT_GET_DBENTRY_INT64(stat)
Datum pg_stat_get_checkpointer_buffers_written(PG_FUNCTION_ARGS)
Datum pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
Datum pg_stat_get_checkpointer_sync_time(PG_FUNCTION_ARGS)
static double pg_stat_us_to_ms(PgStat_Counter val_ms)
#define PG_STAT_WAL_COLS
#define PG_STAT_GET_ACTIVITY_COLS
static Datum pg_stat_wal_build_tuple(PgStat_WalCounters wal_counters, TimestampTz stat_reset_timestamp)
static io_stat_col pgstat_get_io_time_index(IOOp io_op)
Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
#define PG_STAT_GET_FUNCENTRY_FLOAT8_MS(stat)
Datum pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
Datum pg_stat_get_db_checksum_failures(PG_FUNCTION_ARGS)
Datum pg_stat_get_function_stat_reset_time(PG_FUNCTION_ARGS)
Datum pg_stat_reset_subscription_stats(PG_FUNCTION_ARGS)
Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS)
Datum pg_stat_reset_slru(PG_FUNCTION_ARGS)
Datum pg_stat_get_checkpointer_restartpoints_requested(PG_FUNCTION_ARGS)
Datum pg_stat_get_checkpointer_num_performed(PG_FUNCTION_ARGS)
#define PG_STAT_LOCK_COLS
Datum pg_stat_get_db_checksum_last_failure(PG_FUNCTION_ARGS)
Datum pg_stat_get_backend_wal(PG_FUNCTION_ARGS)
static io_stat_col pgstat_get_io_op_index(IOOp io_op)
Datum pg_stat_have_stats(PG_FUNCTION_ARGS)
Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
Datum pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
static io_stat_col pgstat_get_io_byte_index(IOOp io_op)
#define PG_STAT_GET_SUBSCRIPTION_STATS_COLS
Datum pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS)
Datum pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
Datum pg_stat_get_io(PG_FUNCTION_ARGS)
Datum pg_stat_get_checkpointer_restartpoints_performed(PG_FUNCTION_ARGS)
#define PG_STAT_GET_DBENTRY_FLOAT8_MS(stat)
Datum pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
Datum pg_stat_reset(PG_FUNCTION_ARGS)
Datum pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
#define PG_STAT_GET_SUBXACT_COLS
#define PG_STAT_GET_XACT_FUNCENTRY_FLOAT8_MS(stat)
#define PG_STAT_GET_RELENTRY_INT64(stat)
Definition pgstatfuncs.c:41
Datum pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
Datum pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)
#define PG_STAT_GET_RELENTRY_TIMESTAMPTZ(stat)
Datum pg_stat_reset_backend_stats(PG_FUNCTION_ARGS)
#define PG_STAT_GET_PROGRESS_COLS
Datum pg_stat_get_checkpointer_write_time(PG_FUNCTION_ARGS)
Datum pg_stat_get_lock(PG_FUNCTION_ARGS)
#define HAS_PGSTAT_PERMISSIONS(role)
Definition pgstatfuncs.c:39
Datum pg_stat_get_backend_io(PG_FUNCTION_ARGS)
Datum pg_stat_get_checkpointer_slru_written(PG_FUNCTION_ARGS)
#define PG_STAT_GET_RELENTRY_FLOAT8(stat)
Datum pg_stat_get_archiver(PG_FUNCTION_ARGS)
Datum pg_stat_get_checkpointer_restartpoints_timed(PG_FUNCTION_ARGS)
Datum pg_stat_reset_shared(PG_FUNCTION_ARGS)
Datum pg_stat_force_next_flush(PG_FUNCTION_ARGS)
Datum pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS)
Datum pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS)
Datum pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
Datum pg_stat_get_checkpointer_stat_reset_time(PG_FUNCTION_ARGS)
Datum pg_stat_get_function_calls(PG_FUNCTION_ARGS)
Datum pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
Datum pg_stat_get_replication_slot(PG_FUNCTION_ARGS)
io_stat_col
@ IO_COL_READS
@ IO_NUM_COLUMNS
@ IO_COL_RESET_TIME
@ IO_COL_WRITE_TIME
@ IO_COL_HITS
@ IO_COL_EXTENDS
@ IO_COL_WRITEBACK_TIME
@ IO_COL_REUSES
@ IO_COL_WRITES
@ IO_COL_OBJECT
@ IO_COL_EVICTIONS
@ IO_COL_WRITEBACKS
@ IO_COL_CONTEXT
@ IO_COL_READ_BYTES
@ IO_COL_EXTEND_BYTES
@ IO_COL_BACKEND_TYPE
@ IO_COL_FSYNC_TIME
@ IO_COL_EXTEND_TIME
@ IO_COL_FSYNCS
@ IO_COL_WRITE_BYTES
@ IO_COL_INVALID
@ IO_COL_READ_TIME
Datum pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
Datum pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS)
Datum pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
Datum pg_backend_pid(PG_FUNCTION_ARGS)
#define PG_STAT_GET_REPLICATION_SLOT_COLS
int pg_strcasecmp(const char *s1, const char *s2)
#define snprintf
Definition port.h:260
static Datum Int64GetDatum(int64 X)
Definition postgres.h:413
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
static Datum TransactionIdGetDatum(TransactionId X)
Definition postgres.h:292
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
static Datum Float8GetDatum(float8 X)
Definition postgres.h:502
static Datum CStringGetDatum(const char *X)
Definition postgres.h:370
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
#define InvalidOid
unsigned int Oid
static int fb(int x)
#define GetNumberFromPGProc(proc)
Definition proc.h:505
PGPROC * BackendPidGetProc(int pid)
Definition procarray.c:3169
int ProcNumber
Definition procnumber.h:24
PGPROC * AuxiliaryPidGetProc(int pid)
Definition proc.c:1097
Definition proc.h:179
uint32 wait_event_info
Definition proc.h:378
int pid
Definition proc.h:197
PGPROC * lockGroupLeader
Definition proc.h:298
TimestampTz stat_reset_timestamp
Definition pgstat.h:402
TimestampTz last_checksum_failure
Definition pgstat.h:389
TimestampTz stat_reset_timestamp
Definition pgstat.h:411
PgStat_Counter wal_fpi
Definition pgstat.h:501
uint64 wal_fpi_bytes
Definition pgstat.h:503
PgStat_Counter wal_buffers_full
Definition pgstat.h:504
PgStat_Counter wal_records
Definition pgstat.h:500
Definition c.h:830
Definition c.h:776
#define TransactionIdIsValid(xid)
Definition transam.h:41
TupleDesc CreateTemplateTupleDesc(int natts)
Definition tupdesc.c:165
void TupleDescFinalize(TupleDesc tupdesc)
Definition tupdesc.c:511
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition tupdesc.c:900
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition tuplestore.c:785
static Datum TimestampTzGetDatum(TimestampTz X)
Definition timestamp.h:52
#define PG_RETURN_TIMESTAMPTZ(x)
Definition timestamp.h:68
text * cstring_to_text(const char *s)
Definition varlena.c:184
char * text_to_cstring(const text *t)
Definition varlena.c:217
const char * pgstat_get_wait_event_type(uint32 wait_event_info)
Definition wait_event.c:359
const char * pgstat_get_wait_event(uint32 wait_event_info)
Definition wait_event.c:417
const char * name
#define stat
Definition win32_port.h:74
void XLogPrefetchResetStats(void)