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
210{
211 Oid funcid = PG_GETARG_OID(0);
212 TimestampTz result;
214
215 if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
216 result = 0;
217 else
219
220 if (result == 0)
222 else
223 PG_RETURN_TIMESTAMPTZ(result);
224}
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
303 errmsg("invalid command name: \"%s\"", cmd)));
304
305 InitMaterializedSRF(fcinfo, 0);
306
307 /* 1-based index */
309 {
313 bool nulls[PG_STAT_GET_PROGRESS_COLS] = {0};
314 int i;
315
317 beentry = &local_beentry->backendStatus;
318
319 /*
320 * Report values for only those backends which are running the given
321 * command.
322 */
323 if (beentry->st_progress_command != cmdtype)
324 continue;
325
326 /* Value available to all callers */
327 values[0] = Int32GetDatum(beentry->st_procpid);
328 values[1] = ObjectIdGetDatum(beentry->st_databaseid);
329
330 /* show rest of the values including relid only to role members */
331 if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
332 {
333 values[2] = ObjectIdGetDatum(beentry->st_progress_command_target);
334 for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
335 values[i + 3] = Int64GetDatum(beentry->st_progress_param[i]);
336 }
337 else
338 {
339 nulls[2] = true;
340 for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
341 nulls[i + 3] = true;
342 }
343
344 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
345 }
346
347 return (Datum) 0;
348}
349
350/*
351 * Returns activity of PG backends.
352 */
353Datum
355{
356#define PG_STAT_GET_ACTIVITY_COLS 31
358 int curr_backend;
359 int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
360 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
361
362 InitMaterializedSRF(fcinfo, 0);
363
364 /* 1-based index */
366 {
367 /* for each row */
369 bool nulls[PG_STAT_GET_ACTIVITY_COLS] = {0};
372 PGPROC *proc;
373 const char *wait_event_type = NULL;
374 const char *wait_event = NULL;
375
376 /* Get the next one in the list */
378 beentry = &local_beentry->backendStatus;
379
380 /* If looking for specific PID, ignore all the others */
381 if (pid != -1 && beentry->st_procpid != pid)
382 continue;
383
384 /* Values available to all callers */
385 if (beentry->st_databaseid != InvalidOid)
386 values[0] = ObjectIdGetDatum(beentry->st_databaseid);
387 else
388 nulls[0] = true;
389
390 values[1] = Int32GetDatum(beentry->st_procpid);
391
392 if (beentry->st_userid != InvalidOid)
393 values[2] = ObjectIdGetDatum(beentry->st_userid);
394 else
395 nulls[2] = true;
396
397 if (beentry->st_appname)
398 values[3] = CStringGetTextDatum(beentry->st_appname);
399 else
400 nulls[3] = true;
401
402 if (TransactionIdIsValid(local_beentry->backend_xid))
403 values[15] = TransactionIdGetDatum(local_beentry->backend_xid);
404 else
405 nulls[15] = true;
406
407 if (TransactionIdIsValid(local_beentry->backend_xmin))
408 values[16] = TransactionIdGetDatum(local_beentry->backend_xmin);
409 else
410 nulls[16] = true;
411
412 /* Values only available to role member or pg_read_all_stats */
413 if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
414 {
415 char *clipped_activity;
416
417 switch (beentry->st_state)
418 {
419 case STATE_STARTING:
420 values[4] = CStringGetTextDatum("starting");
421 break;
422 case STATE_IDLE:
423 values[4] = CStringGetTextDatum("idle");
424 break;
425 case STATE_RUNNING:
426 values[4] = CStringGetTextDatum("active");
427 break;
429 values[4] = CStringGetTextDatum("idle in transaction");
430 break;
431 case STATE_FASTPATH:
432 values[4] = CStringGetTextDatum("fastpath function call");
433 break;
435 values[4] = CStringGetTextDatum("idle in transaction (aborted)");
436 break;
437 case STATE_DISABLED:
438 values[4] = CStringGetTextDatum("disabled");
439 break;
440 case STATE_UNDEFINED:
441 nulls[4] = true;
442 break;
443 }
444
448
449 /* leader_pid */
450 nulls[29] = true;
451
452 proc = BackendPidGetProc(beentry->st_procpid);
453
454 if (proc == NULL && (beentry->st_backendType != B_BACKEND))
455 {
456 /*
457 * For an auxiliary process, retrieve process info from
458 * AuxiliaryProcs stored in shared-memory.
459 */
460 proc = AuxiliaryPidGetProc(beentry->st_procpid);
461 }
462
463 /*
464 * If a PGPROC entry was retrieved, display wait events and lock
465 * group leader or apply leader information if any. To avoid
466 * extra overhead, no extra lock is being held, so there is no
467 * guarantee of consistency across multiple rows.
468 */
469 if (proc != NULL)
470 {
472 PGPROC *leader;
473
477
478 leader = proc->lockGroupLeader;
479
480 /*
481 * Show the leader only for active parallel workers. This
482 * leaves the field as NULL for the leader of a parallel group
483 * or the leader of parallel apply workers.
484 */
485 if (leader && leader->pid != beentry->st_procpid)
486 {
487 values[29] = Int32GetDatum(leader->pid);
488 nulls[29] = false;
489 }
490 else if (beentry->st_backendType == B_BG_WORKER)
491 {
492 int leader_pid = GetLeaderApplyWorkerPid(beentry->st_procpid);
493
494 if (leader_pid != InvalidPid)
495 {
496 values[29] = Int32GetDatum(leader_pid);
497 nulls[29] = false;
498 }
499 }
500 }
501
502 if (wait_event_type)
504 else
505 nulls[6] = true;
506
507 if (wait_event)
509 else
510 nulls[7] = true;
511
512 /*
513 * Don't expose transaction time for walsenders; it confuses
514 * monitoring, particularly because we don't keep the time up-to-
515 * date.
516 */
517 if (beentry->st_xact_start_timestamp != 0 &&
518 beentry->st_backendType != B_WAL_SENDER)
519 values[8] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
520 else
521 nulls[8] = true;
522
523 if (beentry->st_activity_start_timestamp != 0)
524 values[9] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
525 else
526 nulls[9] = true;
527
528 if (beentry->st_proc_start_timestamp != 0)
529 values[10] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
530 else
531 nulls[10] = true;
532
533 if (beentry->st_state_start_timestamp != 0)
534 values[11] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
535 else
536 nulls[11] = true;
537
538 /* A zeroed client addr means we don't know */
539 if (pg_memory_is_all_zeros(&beentry->st_clientaddr,
540 sizeof(beentry->st_clientaddr)))
541 {
542 nulls[12] = true;
543 nulls[13] = true;
544 nulls[14] = true;
545 }
546 else
547 {
548 if (beentry->st_clientaddr.addr.ss_family == AF_INET ||
549 beentry->st_clientaddr.addr.ss_family == AF_INET6)
550 {
551 char remote_host[NI_MAXHOST];
552 char remote_port[NI_MAXSERV];
553 int ret;
554
555 remote_host[0] = '\0';
556 remote_port[0] = '\0';
557 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
558 beentry->st_clientaddr.salen,
559 remote_host, sizeof(remote_host),
560 remote_port, sizeof(remote_port),
562 if (ret == 0)
563 {
564 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
566 CStringGetDatum(remote_host));
567 if (beentry->st_clienthostname &&
568 beentry->st_clienthostname[0])
569 values[13] = CStringGetTextDatum(beentry->st_clienthostname);
570 else
571 nulls[13] = true;
572 values[14] = Int32GetDatum(atoi(remote_port));
573 }
574 else
575 {
576 nulls[12] = true;
577 nulls[13] = true;
578 nulls[14] = true;
579 }
580 }
581 else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
582 {
583 /*
584 * Unix sockets always reports NULL for host and -1 for
585 * port, so it's possible to tell the difference to
586 * connections we have no permissions to view, or with
587 * errors.
588 */
589 nulls[12] = true;
590 nulls[13] = true;
591 values[14] = Int32GetDatum(-1);
592 }
593 else
594 {
595 /* Unknown address type, should never happen */
596 nulls[12] = true;
597 nulls[13] = true;
598 nulls[14] = true;
599 }
600 }
601 /* Add backend type */
602 if (beentry->st_backendType == B_BG_WORKER)
603 {
604 const char *bgw_type;
605
606 bgw_type = GetBackgroundWorkerTypeByPid(beentry->st_procpid);
607 if (bgw_type)
608 values[17] = CStringGetTextDatum(bgw_type);
609 else
610 nulls[17] = true;
611 }
612 else
613 values[17] =
615
616 /* SSL information */
617 if (beentry->st_ssl)
618 {
619 values[18] = BoolGetDatum(true); /* ssl */
620 values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
621 values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
622 values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
623
624 if (beentry->st_sslstatus->ssl_client_dn[0])
625 values[22] = CStringGetTextDatum(beentry->st_sslstatus->ssl_client_dn);
626 else
627 nulls[22] = true;
628
629 if (beentry->st_sslstatus->ssl_client_serial[0])
631 CStringGetDatum(beentry->st_sslstatus->ssl_client_serial),
633 Int32GetDatum(-1));
634 else
635 nulls[23] = true;
636
637 if (beentry->st_sslstatus->ssl_issuer_dn[0])
638 values[24] = CStringGetTextDatum(beentry->st_sslstatus->ssl_issuer_dn);
639 else
640 nulls[24] = true;
641 }
642 else
643 {
644 values[18] = BoolGetDatum(false); /* ssl */
645 nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = true;
646 }
647
648 /* GSSAPI information */
649 if (beentry->st_gss)
650 {
651 values[25] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */
652 values[26] = CStringGetTextDatum(beentry->st_gssstatus->gss_princ);
653 values[27] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */
654 values[28] = BoolGetDatum(beentry->st_gssstatus->gss_delegation); /* GSS credentials
655 * delegated */
656 }
657 else
658 {
659 values[25] = BoolGetDatum(false); /* gss_auth */
660 nulls[26] = true; /* No GSS principal */
661 values[27] = BoolGetDatum(false); /* GSS Encryption not in
662 * use */
663 values[28] = BoolGetDatum(false); /* GSS credentials not
664 * delegated */
665 }
666 if (beentry->st_query_id == INT64CONST(0))
667 nulls[30] = true;
668 else
669 values[30] = Int64GetDatum(beentry->st_query_id);
670 }
671 else
672 {
673 /* No permissions to view data about this session */
674 values[5] = CStringGetTextDatum("<insufficient privilege>");
675 nulls[4] = true;
676 nulls[6] = true;
677 nulls[7] = true;
678 nulls[8] = true;
679 nulls[9] = true;
680 nulls[10] = true;
681 nulls[11] = true;
682 nulls[12] = true;
683 nulls[13] = true;
684 nulls[14] = true;
685 nulls[17] = true;
686 nulls[18] = true;
687 nulls[19] = true;
688 nulls[20] = true;
689 nulls[21] = true;
690 nulls[22] = true;
691 nulls[23] = true;
692 nulls[24] = true;
693 nulls[25] = true;
694 nulls[26] = true;
695 nulls[27] = true;
696 nulls[28] = true;
697 nulls[29] = true;
698 nulls[30] = true;
699 }
700
701 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
702
703 /* If only a single backend was requested, and we found it, break. */
704 if (pid != -1)
705 break;
706 }
707
708 return (Datum) 0;
709}
710
711
712Datum
717
718
719Datum
721{
722 int32 procNumber = PG_GETARG_INT32(0);
724
725 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
727
728 PG_RETURN_INT32(beentry->st_procpid);
729}
730
731
732Datum
734{
735 int32 procNumber = PG_GETARG_INT32(0);
737
738 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
740
741 PG_RETURN_OID(beentry->st_databaseid);
742}
743
744
745Datum
756
757Datum
759{
760#define PG_STAT_GET_SUBXACT_COLS 2
761 TupleDesc tupdesc;
763 bool nulls[PG_STAT_GET_SUBXACT_COLS] = {0};
764 int32 procNumber = PG_GETARG_INT32(0);
766
767 /* Initialise attributes information in the tuple descriptor */
769 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subxact_count",
770 INT4OID, -1, 0);
771 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "subxact_overflow",
772 BOOLOID, -1, 0);
773
774 TupleDescFinalize(tupdesc);
775 BlessTupleDesc(tupdesc);
776
778 {
779 /* Fill values and NULLs */
780 values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
781 values[1] = BoolGetDatum(local_beentry->backend_subxact_overflowed);
782 }
783 else
784 {
785 nulls[0] = true;
786 nulls[1] = true;
787 }
788
789 /* Returns the record as Datum */
791}
792
793Datum
795{
796 int32 procNumber = PG_GETARG_INT32(0);
798 const char *activity;
799 char *clipped_activity;
800 text *ret;
801
802 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
803 activity = "<backend information not available>";
804 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
805 activity = "<insufficient privilege>";
806 else if (*(beentry->st_activity_raw) == '\0')
807 activity = "<command string not enabled>";
808 else
809 activity = beentry->st_activity_raw;
810
814
815 PG_RETURN_TEXT_P(ret);
816}
817
818Datum
820{
821 int32 procNumber = PG_GETARG_INT32(0);
823 PGPROC *proc;
824 const char *wait_event_type = NULL;
825
826 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
827 wait_event_type = "<backend information not available>";
828 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
829 wait_event_type = "<insufficient privilege>";
830 else
831 {
832 proc = BackendPidGetProc(beentry->st_procpid);
833 if (!proc)
834 proc = AuxiliaryPidGetProc(beentry->st_procpid);
835 if (proc)
837 }
838
839 if (!wait_event_type)
841
843}
844
845Datum
847{
848 int32 procNumber = PG_GETARG_INT32(0);
850 PGPROC *proc;
851 const char *wait_event = NULL;
852
853 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
854 wait_event = "<backend information not available>";
855 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
856 wait_event = "<insufficient privilege>";
857 else
858 {
859 proc = BackendPidGetProc(beentry->st_procpid);
860 if (!proc)
861 proc = AuxiliaryPidGetProc(beentry->st_procpid);
862 if (proc)
864 }
865
866 if (!wait_event)
868
870}
871
872
873Datum
875{
876 int32 procNumber = PG_GETARG_INT32(0);
877 TimestampTz result;
879
880 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
882
883 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
885
886 result = beentry->st_activity_start_timestamp;
887
888 /*
889 * No time recorded for start of current query -- this is the case if the
890 * user hasn't enabled query-level stats collection.
891 */
892 if (result == 0)
894
895 PG_RETURN_TIMESTAMPTZ(result);
896}
897
898
899Datum
901{
902 int32 procNumber = PG_GETARG_INT32(0);
903 TimestampTz result;
905
906 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
908
909 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
911
912 result = beentry->st_xact_start_timestamp;
913
914 if (result == 0) /* not in a transaction */
916
917 PG_RETURN_TIMESTAMPTZ(result);
918}
919
920
921Datum
923{
924 int32 procNumber = PG_GETARG_INT32(0);
925 TimestampTz result;
927
928 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
930
931 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
933
934 result = beentry->st_proc_start_timestamp;
935
936 if (result == 0) /* probably can't happen? */
938
939 PG_RETURN_TIMESTAMPTZ(result);
940}
941
942
943Datum
945{
946 int32 procNumber = PG_GETARG_INT32(0);
948 char remote_host[NI_MAXHOST];
949 int ret;
950
951 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
953
954 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
956
957 /* A zeroed client addr means we don't know */
958 if (pg_memory_is_all_zeros(&beentry->st_clientaddr,
959 sizeof(beentry->st_clientaddr)))
961
962 switch (beentry->st_clientaddr.addr.ss_family)
963 {
964 case AF_INET:
965 case AF_INET6:
966 break;
967 default:
969 }
970
971 remote_host[0] = '\0';
972 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
973 beentry->st_clientaddr.salen,
974 remote_host, sizeof(remote_host),
975 NULL, 0,
977 if (ret != 0)
979
980 clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
981
983 CStringGetDatum(remote_host)));
984}
985
986Datum
988{
989 int32 procNumber = PG_GETARG_INT32(0);
991 char remote_port[NI_MAXSERV];
992 int ret;
993
994 if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
996
997 else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
999
1000 /* A zeroed client addr means we don't know */
1001 if (pg_memory_is_all_zeros(&beentry->st_clientaddr,
1002 sizeof(beentry->st_clientaddr)))
1004
1005 switch (beentry->st_clientaddr.addr.ss_family)
1006 {
1007 case AF_INET:
1008 case AF_INET6:
1009 break;
1010 case AF_UNIX:
1011 PG_RETURN_INT32(-1);
1012 default:
1014 }
1015
1016 remote_port[0] = '\0';
1017 ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
1018 beentry->st_clientaddr.salen,
1019 NULL, 0,
1020 remote_port, sizeof(remote_port),
1022 if (ret != 0)
1024
1026 CStringGetDatum(remote_port)));
1027}
1028
1029
1030Datum
1032{
1033 Oid dbid = PG_GETARG_OID(0);
1034 int32 result;
1036 int idx;
1037
1038 result = 0;
1039 for (idx = 1; idx <= tot_backends; idx++)
1040 {
1042
1043 if (local_beentry->backendStatus.st_databaseid == dbid)
1044 result++;
1045 }
1046
1047 PG_RETURN_INT32(result);
1048}
1049
1050
1051#define PG_STAT_GET_DBENTRY_INT64(stat) \
1052Datum \
1053CppConcat(pg_stat_get_db_,stat)(PG_FUNCTION_ARGS) \
1054{ \
1055 Oid dbid = PG_GETARG_OID(0); \
1056 int64 result; \
1057 PgStat_StatDBEntry *dbentry; \
1058 \
1059 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) \
1060 result = 0; \
1061 else \
1062 result = (int64) (dbentry->stat); \
1063 \
1064 PG_RETURN_INT64(result); \
1065}
1066
1067/* pg_stat_get_db_blocks_fetched */
1068PG_STAT_GET_DBENTRY_INT64(blocks_fetched)
1069
1070/* pg_stat_get_db_blocks_hit */
1071PG_STAT_GET_DBENTRY_INT64(blocks_hit)
1072
1073/* pg_stat_get_db_conflict_bufferpin */
1074PG_STAT_GET_DBENTRY_INT64(conflict_bufferpin)
1075
1076/* pg_stat_get_db_conflict_lock */
1077PG_STAT_GET_DBENTRY_INT64(conflict_lock)
1078
1079/* pg_stat_get_db_conflict_snapshot */
1080PG_STAT_GET_DBENTRY_INT64(conflict_snapshot)
1081
1082/* pg_stat_get_db_conflict_startup_deadlock */
1083PG_STAT_GET_DBENTRY_INT64(conflict_startup_deadlock)
1084
1085/* pg_stat_get_db_conflict_tablespace */
1086PG_STAT_GET_DBENTRY_INT64(conflict_tablespace)
1087
1088/* pg_stat_get_db_deadlocks */
1090
1091/* pg_stat_get_db_sessions */
1093
1094/* pg_stat_get_db_sessions_abandoned */
1095PG_STAT_GET_DBENTRY_INT64(sessions_abandoned)
1096
1097/* pg_stat_get_db_sessions_fatal */
1098PG_STAT_GET_DBENTRY_INT64(sessions_fatal)
1099
1100/* pg_stat_get_db_sessions_killed */
1101PG_STAT_GET_DBENTRY_INT64(sessions_killed)
1102
1103/* pg_stat_get_db_parallel_workers_to_launch */
1104PG_STAT_GET_DBENTRY_INT64(parallel_workers_to_launch)
1105
1106/* pg_stat_get_db_parallel_workers_launched */
1107PG_STAT_GET_DBENTRY_INT64(parallel_workers_launched)
1108
1109/* pg_stat_get_db_temp_bytes */
1110PG_STAT_GET_DBENTRY_INT64(temp_bytes)
1111
1112/* pg_stat_get_db_temp_files */
1113PG_STAT_GET_DBENTRY_INT64(temp_files)
1114
1115/* pg_stat_get_db_tuples_deleted */
1116PG_STAT_GET_DBENTRY_INT64(tuples_deleted)
1117
1118/* pg_stat_get_db_tuples_fetched */
1119PG_STAT_GET_DBENTRY_INT64(tuples_fetched)
1120
1121/* pg_stat_get_db_tuples_inserted */
1122PG_STAT_GET_DBENTRY_INT64(tuples_inserted)
1123
1124/* pg_stat_get_db_tuples_returned */
1125PG_STAT_GET_DBENTRY_INT64(tuples_returned)
1126
1127/* pg_stat_get_db_tuples_updated */
1128PG_STAT_GET_DBENTRY_INT64(tuples_updated)
1129
1130/* pg_stat_get_db_xact_commit */
1131PG_STAT_GET_DBENTRY_INT64(xact_commit)
1132
1133/* pg_stat_get_db_xact_rollback */
1134PG_STAT_GET_DBENTRY_INT64(xact_rollback)
1135
1136/* pg_stat_get_db_conflict_logicalslot */
1137PG_STAT_GET_DBENTRY_INT64(conflict_logicalslot)
1138
1139Datum
1141{
1142 Oid dbid = PG_GETARG_OID(0);
1143 TimestampTz result;
1145
1146 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1147 result = 0;
1148 else
1149 result = dbentry->stat_reset_timestamp;
1150
1151 if (result == 0)
1153 else
1154 PG_RETURN_TIMESTAMPTZ(result);
1155}
1156
1157
1158Datum
1160{
1161 Oid dbid = PG_GETARG_OID(0);
1162 int64 result;
1164
1165 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1166 result = 0;
1167 else
1168 result = (int64) (dbentry->conflict_tablespace +
1169 dbentry->conflict_lock +
1170 dbentry->conflict_snapshot +
1171 dbentry->conflict_logicalslot +
1172 dbentry->conflict_bufferpin +
1173 dbentry->conflict_startup_deadlock);
1174
1175 PG_RETURN_INT64(result);
1176}
1177
1178Datum
1180{
1181 Oid dbid = PG_GETARG_OID(0);
1182 int64 result;
1184
1185 if (!DataChecksumsEnabled())
1187
1188 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1189 result = 0;
1190 else
1191 result = (int64) (dbentry->checksum_failures);
1192
1193 PG_RETURN_INT64(result);
1194}
1195
1196Datum
1198{
1199 Oid dbid = PG_GETARG_OID(0);
1200 TimestampTz result;
1202
1203 if (!DataChecksumsEnabled())
1205
1206 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1207 result = 0;
1208 else
1209 result = dbentry->last_checksum_failure;
1210
1211 if (result == 0)
1213 else
1214 PG_RETURN_TIMESTAMPTZ(result);
1215}
1216
1217/* convert counter from microsec to millisec for display */
1218#define PG_STAT_GET_DBENTRY_FLOAT8_MS(stat) \
1219Datum \
1220CppConcat(pg_stat_get_db_,stat)(PG_FUNCTION_ARGS) \
1221{ \
1222 Oid dbid = PG_GETARG_OID(0); \
1223 double result; \
1224 PgStat_StatDBEntry *dbentry; \
1225 \
1226 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) \
1227 result = 0; \
1228 else \
1229 result = ((double) dbentry->stat) / 1000.0; \
1230 \
1231 PG_RETURN_FLOAT8(result); \
1232}
1233
1234/* pg_stat_get_db_active_time */
1236
1237/* pg_stat_get_db_blk_read_time */
1238PG_STAT_GET_DBENTRY_FLOAT8_MS(blk_read_time)
1239
1240/* pg_stat_get_db_blk_write_time */
1241PG_STAT_GET_DBENTRY_FLOAT8_MS(blk_write_time)
1242
1243/* pg_stat_get_db_idle_in_transaction_time */
1244PG_STAT_GET_DBENTRY_FLOAT8_MS(idle_in_transaction_time)
1245
1246/* pg_stat_get_db_session_time */
1248
1249Datum
1254
1255Datum
1260
1261Datum
1266
1267Datum
1272
1273Datum
1278
1279Datum
1284
1285Datum
1290
1291Datum
1296
1297Datum
1302
1303Datum
1308
1309Datum
1311{
1312 /* time is already in msec, just convert to double for presentation */
1313 PG_RETURN_FLOAT8((double)
1314 pgstat_fetch_stat_checkpointer()->write_time);
1315}
1316
1317Datum
1319{
1320 /* time is already in msec, just convert to double for presentation */
1321 PG_RETURN_FLOAT8((double)
1322 pgstat_fetch_stat_checkpointer()->sync_time);
1323}
1324
1325Datum
1330
1331Datum
1336
1337Datum
1342
1343/*
1344* When adding a new column to the pg_stat_io view and the
1345* pg_stat_get_backend_io() function, add a new enum value here above
1346* IO_NUM_COLUMNS.
1347*/
1373
1374/*
1375 * When adding a new IOOp, add a new io_stat_col and add a case to this
1376 * function returning the corresponding io_stat_col.
1377 */
1378static io_stat_col
1380{
1381 switch (io_op)
1382 {
1383 case IOOP_EVICT:
1384 return IO_COL_EVICTIONS;
1385 case IOOP_EXTEND:
1386 return IO_COL_EXTENDS;
1387 case IOOP_FSYNC:
1388 return IO_COL_FSYNCS;
1389 case IOOP_HIT:
1390 return IO_COL_HITS;
1391 case IOOP_READ:
1392 return IO_COL_READS;
1393 case IOOP_REUSE:
1394 return IO_COL_REUSES;
1395 case IOOP_WRITE:
1396 return IO_COL_WRITES;
1397 case IOOP_WRITEBACK:
1398 return IO_COL_WRITEBACKS;
1399 }
1400
1401 elog(ERROR, "unrecognized IOOp value: %d", io_op);
1403}
1404
1405/*
1406 * Get the number of the column containing IO bytes for the specified IOOp.
1407 * If an IOOp is not tracked in bytes, IO_COL_INVALID is returned.
1408 */
1409static io_stat_col
1411{
1412 switch (io_op)
1413 {
1414 case IOOP_EXTEND:
1415 return IO_COL_EXTEND_BYTES;
1416 case IOOP_READ:
1417 return IO_COL_READ_BYTES;
1418 case IOOP_WRITE:
1419 return IO_COL_WRITE_BYTES;
1420 case IOOP_EVICT:
1421 case IOOP_FSYNC:
1422 case IOOP_HIT:
1423 case IOOP_REUSE:
1424 case IOOP_WRITEBACK:
1425 return IO_COL_INVALID;
1426 }
1427
1428 elog(ERROR, "unrecognized IOOp value: %d", io_op);
1430}
1431
1432/*
1433 * Get the number of the column containing IO times for the specified IOOp.
1434 * If an op has no associated time, IO_COL_INVALID is returned.
1435 */
1436static io_stat_col
1438{
1439 switch (io_op)
1440 {
1441 case IOOP_READ:
1442 return IO_COL_READ_TIME;
1443 case IOOP_WRITE:
1444 return IO_COL_WRITE_TIME;
1445 case IOOP_WRITEBACK:
1446 return IO_COL_WRITEBACK_TIME;
1447 case IOOP_EXTEND:
1448 return IO_COL_EXTEND_TIME;
1449 case IOOP_FSYNC:
1450 return IO_COL_FSYNC_TIME;
1451 case IOOP_EVICT:
1452 case IOOP_HIT:
1453 case IOOP_REUSE:
1454 return IO_COL_INVALID;
1455 }
1456
1457 elog(ERROR, "unrecognized IOOp value: %d", io_op);
1459}
1460
1461static inline double
1463{
1464 return val_ms * (double) 0.001;
1465}
1466
1467/*
1468 * pg_stat_io_build_tuples
1469 *
1470 * Helper routine for pg_stat_get_io() and pg_stat_get_backend_io()
1471 * filling a result tuplestore with one tuple for each object and each
1472 * context supported by the caller, based on the contents of bktype_stats.
1473 */
1474static void
1478 TimestampTz stat_reset_timestamp)
1479{
1481
1482 for (int io_obj = 0; io_obj < IOOBJECT_NUM_TYPES; io_obj++)
1483 {
1485
1487 {
1489
1491 bool nulls[IO_NUM_COLUMNS] = {0};
1492
1493 /*
1494 * Some combinations of BackendType, IOObject, and IOContext are
1495 * not valid for any type of IOOp. In such cases, omit the entire
1496 * row from the view.
1497 */
1499 continue;
1500
1504 if (stat_reset_timestamp != 0)
1505 values[IO_COL_RESET_TIME] = TimestampTzGetDatum(stat_reset_timestamp);
1506 else
1507 nulls[IO_COL_RESET_TIME] = true;
1508
1509 for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
1510 {
1514
1515 /*
1516 * Some combinations of BackendType and IOOp, of IOContext and
1517 * IOOp, and of IOObject and IOOp are not tracked. Set these
1518 * cells in the view NULL.
1519 */
1521 {
1522 PgStat_Counter count =
1524
1525 values[op_idx] = Int64GetDatum(count);
1526 }
1527 else
1528 nulls[op_idx] = true;
1529
1530 if (!nulls[op_idx])
1531 {
1532 /* not every operation is timed */
1533 if (time_idx != IO_COL_INVALID)
1534 {
1535 PgStat_Counter time =
1537
1539 }
1540
1541 /* not every IO is tracked in bytes */
1542 if (byte_idx != IO_COL_INVALID)
1543 {
1544 char buf[256];
1545 PgStat_Counter byte =
1547
1548 /* Convert to numeric */
1549 snprintf(buf, sizeof buf, INT64_FORMAT, byte);
1553 Int32GetDatum(-1));
1554 }
1555 }
1556 else
1557 {
1558 if (time_idx != IO_COL_INVALID)
1559 nulls[time_idx] = true;
1560 if (byte_idx != IO_COL_INVALID)
1561 nulls[byte_idx] = true;
1562 }
1563 }
1564
1565 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
1566 values, nulls);
1567 }
1568 }
1569}
1570
1571Datum
1573{
1576
1577 InitMaterializedSRF(fcinfo, 0);
1578 rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1579
1581
1582 for (int bktype = 0; bktype < BACKEND_NUM_TYPES; bktype++)
1583 {
1585
1586 /*
1587 * In Assert builds, we can afford an extra loop through all of the
1588 * counters (in pg_stat_io_build_tuples()), checking that only
1589 * expected stats are non-zero, since it keeps the non-Assert code
1590 * cleaner.
1591 */
1593
1594 /*
1595 * For those BackendTypes without IO Operation stats, skip
1596 * representing them in the view altogether.
1597 */
1599 continue;
1600
1601 /* save tuples with data from this PgStat_BktypeIO */
1603 backends_io_stats->stat_reset_timestamp);
1604 }
1605
1606 return (Datum) 0;
1607}
1608
1609/*
1610 * Returns I/O statistics for a backend with given PID.
1611 */
1612Datum
1614{
1617 int pid;
1620
1621 InitMaterializedSRF(fcinfo, 0);
1622 rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1623
1624 pid = PG_GETARG_INT32(0);
1626
1627 if (!backend_stats)
1628 return (Datum) 0;
1629
1630 bktype_stats = &backend_stats->io_stats;
1631
1632 /*
1633 * In Assert builds, we can afford an extra loop through all of the
1634 * counters (in pg_stat_io_build_tuples()), checking that only expected
1635 * stats are non-zero, since it keeps the non-Assert code cleaner.
1636 */
1638
1639 /* save tuples with data from this PgStat_BktypeIO */
1641 backend_stats->stat_reset_timestamp);
1642 return (Datum) 0;
1643}
1644
1645/*
1646 * pg_stat_wal_build_tuple
1647 *
1648 * Helper routine for pg_stat_get_wal() and pg_stat_get_backend_wal()
1649 * returning one tuple based on the contents of wal_counters.
1650 */
1651static Datum
1653 TimestampTz stat_reset_timestamp)
1654{
1655#define PG_STAT_WAL_COLS 6
1656 TupleDesc tupdesc;
1658 bool nulls[PG_STAT_WAL_COLS] = {0};
1659 char buf[256];
1660
1661 /* Initialise attributes information in the tuple descriptor */
1663 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "wal_records",
1664 INT8OID, -1, 0);
1665 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "wal_fpi",
1666 INT8OID, -1, 0);
1667 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "wal_bytes",
1668 NUMERICOID, -1, 0);
1669 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_fpi_bytes",
1670 NUMERICOID, -1, 0);
1671 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "wal_buffers_full",
1672 INT8OID, -1, 0);
1673 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "stats_reset",
1674 TIMESTAMPTZOID, -1, 0);
1675
1676 TupleDescFinalize(tupdesc);
1677 BlessTupleDesc(tupdesc);
1678
1679 /* Fill values and NULLs */
1680 values[0] = Int64GetDatum(wal_counters.wal_records);
1681 values[1] = Int64GetDatum(wal_counters.wal_fpi);
1682
1683 /* Convert to numeric. */
1684 snprintf(buf, sizeof buf, UINT64_FORMAT, wal_counters.wal_bytes);
1688 Int32GetDatum(-1));
1689
1690 snprintf(buf, sizeof buf, UINT64_FORMAT, wal_counters.wal_fpi_bytes);
1694 Int32GetDatum(-1));
1695
1696 values[4] = Int64GetDatum(wal_counters.wal_buffers_full);
1697
1698 if (stat_reset_timestamp != 0)
1699 values[5] = TimestampTzGetDatum(stat_reset_timestamp);
1700 else
1701 nulls[5] = true;
1702
1703 /* Returns the record as Datum */
1705}
1706
1707/*
1708 * Returns WAL statistics for a backend with given PID.
1709 */
1710Datum
1712{
1713 int pid;
1716
1717 pid = PG_GETARG_INT32(0);
1719
1720 if (!backend_stats)
1722
1723 bktype_stats = backend_stats->wal_counters;
1724
1725 /* save tuples with data from this PgStat_WalCounters */
1726 return (pg_stat_wal_build_tuple(bktype_stats, backend_stats->stat_reset_timestamp));
1727}
1728
1729/*
1730 * Returns statistics of WAL activity
1731 */
1732Datum
1734{
1736
1737 /* Get statistics about WAL activity */
1739
1740 return (pg_stat_wal_build_tuple(wal_stats->wal_counters,
1741 wal_stats->stat_reset_timestamp));
1742}
1743
1744/*
1745 * Returns statistics of SLRU caches.
1746 */
1747Datum
1749{
1750#define PG_STAT_GET_SLRU_COLS 9
1751 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1752 int i;
1753 PgStat_SLRUStats *stats;
1754
1755 InitMaterializedSRF(fcinfo, 0);
1756
1757 /* request SLRU stats from the cumulative stats system */
1758 stats = pgstat_fetch_slru();
1759
1760 for (i = 0;; i++)
1761 {
1762 /* for each row */
1764 bool nulls[PG_STAT_GET_SLRU_COLS] = {0};
1766 const char *name;
1767
1769
1770 if (!name)
1771 break;
1772
1773 stat = stats[i];
1774
1776 values[1] = Int64GetDatum(stat.blocks_zeroed);
1777 values[2] = Int64GetDatum(stat.blocks_hit);
1778 values[3] = Int64GetDatum(stat.blocks_read);
1779 values[4] = Int64GetDatum(stat.blocks_written);
1780 values[5] = Int64GetDatum(stat.blocks_exists);
1781 values[6] = Int64GetDatum(stat.flush);
1782 values[7] = Int64GetDatum(stat.truncate);
1783 values[8] = TimestampTzGetDatum(stat.stat_reset_timestamp);
1784
1785 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
1786 }
1787
1788 return (Datum) 0;
1789}
1790
1791#define PG_STAT_GET_XACT_RELENTRY_INT64(stat) \
1792Datum \
1793CppConcat(pg_stat_get_xact_,stat)(PG_FUNCTION_ARGS) \
1794{ \
1795 Oid relid = PG_GETARG_OID(0); \
1796 int64 result; \
1797 PgStat_TableStatus *tabentry; \
1798 \
1799 if ((tabentry = find_tabstat_entry(relid)) == NULL) \
1800 result = 0; \
1801 else \
1802 result = (int64) (tabentry->counts.stat); \
1803 \
1804 PG_RETURN_INT64(result); \
1805}
1806
1807/* pg_stat_get_xact_numscans */
1809
1810/* pg_stat_get_xact_tuples_returned */
1811PG_STAT_GET_XACT_RELENTRY_INT64(tuples_returned)
1812
1813/* pg_stat_get_xact_tuples_fetched */
1814PG_STAT_GET_XACT_RELENTRY_INT64(tuples_fetched)
1815
1816/* pg_stat_get_xact_tuples_hot_updated */
1817PG_STAT_GET_XACT_RELENTRY_INT64(tuples_hot_updated)
1818
1819/* pg_stat_get_xact_tuples_newpage_updated */
1820PG_STAT_GET_XACT_RELENTRY_INT64(tuples_newpage_updated)
1821
1822/* pg_stat_get_xact_blocks_fetched */
1823PG_STAT_GET_XACT_RELENTRY_INT64(blocks_fetched)
1824
1825/* pg_stat_get_xact_blocks_hit */
1827
1828/* pg_stat_get_xact_tuples_inserted */
1829PG_STAT_GET_XACT_RELENTRY_INT64(tuples_inserted)
1830
1831/* pg_stat_get_xact_tuples_updated */
1832PG_STAT_GET_XACT_RELENTRY_INT64(tuples_updated)
1833
1834/* pg_stat_get_xact_tuples_deleted */
1835PG_STAT_GET_XACT_RELENTRY_INT64(tuples_deleted)
1836
1837Datum
1847
1848#define PG_STAT_GET_XACT_FUNCENTRY_FLOAT8_MS(stat) \
1849Datum \
1850CppConcat(pg_stat_get_xact_function_,stat)(PG_FUNCTION_ARGS) \
1851{ \
1852 Oid funcid = PG_GETARG_OID(0); \
1853 PgStat_FunctionCounts *funcentry; \
1854 \
1855 if ((funcentry = find_funcstat_entry(funcid)) == NULL) \
1856 PG_RETURN_NULL(); \
1857 PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(funcentry->stat)); \
1858}
1859
1860/* pg_stat_get_xact_function_total_time */
1862
1863/* pg_stat_get_xact_function_self_time */
1865
1866/* Get the timestamp of the current statistics snapshot */
1867Datum
1880
1881/* Discard the active statistics snapshot */
1882Datum
1889
1890
1891/* Force statistics to be reported at the next occasion */
1892Datum
1899
1900
1901/* Reset all counters for the current database */
1902Datum
1909
1910/*
1911 * Reset some shared cluster-wide counters
1912 *
1913 * When adding a new reset target, ideally the name should match that in
1914 * pgstat_kind_builtin_infos, if relevant.
1915 */
1916Datum
1918{
1919 char *target = NULL;
1920
1921 if (PG_ARGISNULL(0))
1922 {
1923 /* Reset all the statistics when nothing is specified */
1931
1933 }
1934
1936
1937 if (strcmp(target, "archiver") == 0)
1939 else if (strcmp(target, "bgwriter") == 0)
1941 else if (strcmp(target, "checkpointer") == 0)
1943 else if (strcmp(target, "io") == 0)
1945 else if (strcmp(target, "recovery_prefetch") == 0)
1947 else if (strcmp(target, "slru") == 0)
1949 else if (strcmp(target, "wal") == 0)
1951 else
1952 ereport(ERROR,
1954 errmsg("unrecognized reset target: \"%s\"", target),
1955 errhint("Target must be \"archiver\", \"bgwriter\", \"checkpointer\", \"io\", \"recovery_prefetch\", \"slru\", or \"wal\".")));
1956
1958}
1959
1960/*
1961 * Reset statistics for a single object, which may be of current
1962 * database or shared across all databases in the cluster.
1963 */
1964Datum
1974
1975Datum
1984
1985/*
1986 * Reset statistics of backend with given PID.
1987 */
1988Datum
1990{
1991 PGPROC *proc;
1993 ProcNumber procNumber;
1994 int backend_pid = PG_GETARG_INT32(0);
1995
1996 proc = BackendPidGetProc(backend_pid);
1997
1998 /* This could be an auxiliary process */
1999 if (!proc)
2000 proc = AuxiliaryPidGetProc(backend_pid);
2001
2002 if (!proc)
2004
2005 procNumber = GetNumberFromPGProc(proc);
2006
2008 if (!beentry)
2010
2011 /* Check if the backend type tracks statistics */
2012 if (!pgstat_tracks_backend_bktype(beentry->st_backendType))
2014
2016
2018}
2019
2020/* Reset SLRU counters (a specific one or all of them). */
2021Datum
2023{
2024 char *target = NULL;
2025
2026 if (PG_ARGISNULL(0))
2028 else
2029 {
2031 pgstat_reset_slru(target);
2032 }
2033
2035}
2036
2037/* Reset replication slots stats (a specific one or all of them). */
2038Datum
2040{
2041 char *target = NULL;
2042
2043 if (PG_ARGISNULL(0))
2045 else
2046 {
2048 pgstat_reset_replslot(target);
2049 }
2050
2052}
2053
2054/* Reset subscription stats (a specific one or all of them) */
2055Datum
2057{
2058 Oid subid;
2059
2060 if (PG_ARGISNULL(0))
2061 {
2062 /* Clear all subscription stats */
2064 }
2065 else
2066 {
2067 subid = PG_GETARG_OID(0);
2068
2069 if (!OidIsValid(subid))
2070 ereport(ERROR,
2072 errmsg("invalid subscription OID %u", subid)));
2074 }
2075
2077}
2078
2079Datum
2081{
2082 TupleDesc tupdesc;
2083 Datum values[7] = {0};
2084 bool nulls[7] = {0};
2086
2087 /* Initialise attributes information in the tuple descriptor */
2088 tupdesc = CreateTemplateTupleDesc(7);
2089 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
2090 INT8OID, -1, 0);
2091 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal",
2092 TEXTOID, -1, 0);
2093 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_archived_time",
2094 TIMESTAMPTZOID, -1, 0);
2095 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "failed_count",
2096 INT8OID, -1, 0);
2097 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_failed_wal",
2098 TEXTOID, -1, 0);
2099 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_failed_time",
2100 TIMESTAMPTZOID, -1, 0);
2101 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stats_reset",
2102 TIMESTAMPTZOID, -1, 0);
2103
2104 TupleDescFinalize(tupdesc);
2105 BlessTupleDesc(tupdesc);
2106
2107 /* Get statistics about the archiver process */
2109
2110 /* Fill values and NULLs */
2111 values[0] = Int64GetDatum(archiver_stats->archived_count);
2112 if (*(archiver_stats->last_archived_wal) == '\0')
2113 nulls[1] = true;
2114 else
2115 values[1] = CStringGetTextDatum(archiver_stats->last_archived_wal);
2116
2117 if (archiver_stats->last_archived_timestamp == 0)
2118 nulls[2] = true;
2119 else
2120 values[2] = TimestampTzGetDatum(archiver_stats->last_archived_timestamp);
2121
2122 values[3] = Int64GetDatum(archiver_stats->failed_count);
2123 if (*(archiver_stats->last_failed_wal) == '\0')
2124 nulls[4] = true;
2125 else
2126 values[4] = CStringGetTextDatum(archiver_stats->last_failed_wal);
2127
2128 if (archiver_stats->last_failed_timestamp == 0)
2129 nulls[5] = true;
2130 else
2131 values[5] = TimestampTzGetDatum(archiver_stats->last_failed_timestamp);
2132
2133 if (archiver_stats->stat_reset_timestamp == 0)
2134 nulls[6] = true;
2135 else
2136 values[6] = TimestampTzGetDatum(archiver_stats->stat_reset_timestamp);
2137
2138 /* Returns the record as Datum */
2140}
2141
2142/*
2143 * Get the statistics for the replication slot. If the slot statistics is not
2144 * available, return all-zeroes stats.
2145 */
2146Datum
2148{
2149#define PG_STAT_GET_REPLICATION_SLOT_COLS 13
2151 NameData slotname;
2152 TupleDesc tupdesc;
2154 bool nulls[PG_STAT_GET_REPLICATION_SLOT_COLS] = {0};
2157
2158 /* Initialise attributes information in the tuple descriptor */
2160 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "slot_name",
2161 TEXTOID, -1, 0);
2162 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "spill_txns",
2163 INT8OID, -1, 0);
2164 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "spill_count",
2165 INT8OID, -1, 0);
2166 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "spill_bytes",
2167 INT8OID, -1, 0);
2168 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "stream_txns",
2169 INT8OID, -1, 0);
2170 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "stream_count",
2171 INT8OID, -1, 0);
2172 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stream_bytes",
2173 INT8OID, -1, 0);
2174 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "mem_exceeded_count",
2175 INT8OID, -1, 0);
2176 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "total_txns",
2177 INT8OID, -1, 0);
2178 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "total_bytes",
2179 INT8OID, -1, 0);
2180 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "slotsync_skip_count",
2181 INT8OID, -1, 0);
2182 TupleDescInitEntry(tupdesc, (AttrNumber) 12, "slotsync_last_skip",
2183 TIMESTAMPTZOID, -1, 0);
2184 TupleDescInitEntry(tupdesc, (AttrNumber) 13, "stats_reset",
2185 TIMESTAMPTZOID, -1, 0);
2186 TupleDescFinalize(tupdesc);
2187 BlessTupleDesc(tupdesc);
2188
2190 slotent = pgstat_fetch_replslot(slotname);
2191 if (!slotent)
2192 {
2193 /*
2194 * If the slot is not found, initialise its stats. This is possible if
2195 * the create slot message is lost.
2196 */
2198 slotent = &allzero;
2199 }
2200
2201 values[0] = CStringGetTextDatum(NameStr(slotname));
2202 values[1] = Int64GetDatum(slotent->spill_txns);
2203 values[2] = Int64GetDatum(slotent->spill_count);
2204 values[3] = Int64GetDatum(slotent->spill_bytes);
2205 values[4] = Int64GetDatum(slotent->stream_txns);
2206 values[5] = Int64GetDatum(slotent->stream_count);
2207 values[6] = Int64GetDatum(slotent->stream_bytes);
2208 values[7] = Int64GetDatum(slotent->mem_exceeded_count);
2209 values[8] = Int64GetDatum(slotent->total_txns);
2210 values[9] = Int64GetDatum(slotent->total_bytes);
2211 values[10] = Int64GetDatum(slotent->slotsync_skip_count);
2212
2213 if (slotent->slotsync_last_skip == 0)
2214 nulls[11] = true;
2215 else
2216 values[11] = TimestampTzGetDatum(slotent->slotsync_last_skip);
2217
2218 if (slotent->stat_reset_timestamp == 0)
2219 nulls[12] = true;
2220 else
2221 values[12] = TimestampTzGetDatum(slotent->stat_reset_timestamp);
2222
2223 /* Returns the record as Datum */
2225}
2226
2227/*
2228 * Get the subscription statistics for the given subscription. If the
2229 * subscription statistics is not available, return all-zeros stats.
2230 */
2231Datum
2233{
2234#define PG_STAT_GET_SUBSCRIPTION_STATS_COLS 13
2235 Oid subid = PG_GETARG_OID(0);
2236 TupleDesc tupdesc;
2238 bool nulls[PG_STAT_GET_SUBSCRIPTION_STATS_COLS] = {0};
2241 int i = 0;
2242
2243 /* Get subscription stats */
2245
2246 /* Initialise attributes information in the tuple descriptor */
2248 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subid",
2249 OIDOID, -1, 0);
2250 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "apply_error_count",
2251 INT8OID, -1, 0);
2252 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "sync_seq_error_count",
2253 INT8OID, -1, 0);
2254 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "sync_table_error_count",
2255 INT8OID, -1, 0);
2256 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "confl_insert_exists",
2257 INT8OID, -1, 0);
2258 TupleDescInitEntry(tupdesc, (AttrNumber) 6, "confl_update_origin_differs",
2259 INT8OID, -1, 0);
2260 TupleDescInitEntry(tupdesc, (AttrNumber) 7, "confl_update_exists",
2261 INT8OID, -1, 0);
2262 TupleDescInitEntry(tupdesc, (AttrNumber) 8, "confl_update_deleted",
2263 INT8OID, -1, 0);
2264 TupleDescInitEntry(tupdesc, (AttrNumber) 9, "confl_update_missing",
2265 INT8OID, -1, 0);
2266 TupleDescInitEntry(tupdesc, (AttrNumber) 10, "confl_delete_origin_differs",
2267 INT8OID, -1, 0);
2268 TupleDescInitEntry(tupdesc, (AttrNumber) 11, "confl_delete_missing",
2269 INT8OID, -1, 0);
2270 TupleDescInitEntry(tupdesc, (AttrNumber) 12, "confl_multiple_unique_conflicts",
2271 INT8OID, -1, 0);
2272 TupleDescInitEntry(tupdesc, (AttrNumber) 13, "stats_reset",
2273 TIMESTAMPTZOID, -1, 0);
2274 TupleDescFinalize(tupdesc);
2275 BlessTupleDesc(tupdesc);
2276
2277 if (!subentry)
2278 {
2279 /* If the subscription is not found, initialise its stats */
2280 memset(&allzero, 0, sizeof(PgStat_StatSubEntry));
2281 subentry = &allzero;
2282 }
2283
2284 /* subid */
2285 values[i++] = ObjectIdGetDatum(subid);
2286
2287 /* apply_error_count */
2288 values[i++] = Int64GetDatum(subentry->apply_error_count);
2289
2290 /* sync_seq_error_count */
2291 values[i++] = Int64GetDatum(subentry->sync_seq_error_count);
2292
2293 /* sync_table_error_count */
2294 values[i++] = Int64GetDatum(subentry->sync_table_error_count);
2295
2296 /* conflict count */
2298 values[i++] = Int64GetDatum(subentry->conflict_count[nconflict]);
2299
2300 /* stats_reset */
2301 if (subentry->stat_reset_timestamp == 0)
2302 nulls[i] = true;
2303 else
2304 values[i] = TimestampTzGetDatum(subentry->stat_reset_timestamp);
2305
2307
2308 /* Returns the record as Datum */
2310}
2311
2312/*
2313 * Checks for presence of stats for object with provided kind, database oid,
2314 * object oid.
2315 *
2316 * This is useful for tests, but not really anything else. Therefore not
2317 * documented.
2318 */
2319Datum
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_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:1379
static Datum values[MAXATTR]
Definition bootstrap.c:188
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define NameStr(name)
Definition c.h:837
#define INT64CONST(x)
Definition c.h:632
#define INT64_FORMAT
Definition c.h:636
#define Assert(condition)
Definition c.h:945
int64_t int64
Definition c.h:615
#define UINT64_FORMAT
Definition c.h:637
int32_t int32
Definition c.h:614
uint64_t uint64
Definition c.h:619
#define pg_unreachable()
Definition c.h:361
uint32_t uint32
Definition c.h:618
#define OidIsValid(objectId)
Definition c.h:860
bool IsSharedRelation(Oid relationId)
Definition catalog.c:304
#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:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
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, bits32 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:47
Oid MyDatabaseId
Definition globals.c:94
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1037
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
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:377
BackendType
Definition miscadmin.h:338
@ B_WAL_SENDER
Definition miscadmin.h:347
@ B_BG_WORKER
Definition miscadmin.h:346
@ B_BACKEND
Definition miscadmin.h:342
#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:864
void pgstat_reset_counters(void)
Definition pgstat.c:845
void pgstat_reset_of_kind(PgStat_Kind kind)
Definition pgstat.c:886
void pgstat_force_next_flush(void)
Definition pgstat.c:824
void pgstat_clear_snapshot(void)
Definition pgstat.c:912
TimestampTz pgstat_get_stat_snapshot_timestamp(bool *have_snapshot)
Definition pgstat.c:1037
bool pgstat_have_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
Definition pgstat.c:1054
PgStat_Kind pgstat_get_kind_from_str(char *kind_str)
Definition pgstat.c:1411
#define IOOP_NUM_TYPES
Definition pgstat.h:322
#define IOCONTEXT_NUM_TYPES
Definition pgstat.h:296
IOOp
Definition pgstat.h:308
@ IOOP_EXTEND
Definition pgstat.h:317
@ IOOP_FSYNC
Definition pgstat.h:311
@ IOOP_READ
Definition pgstat.h:318
@ IOOP_WRITEBACK
Definition pgstat.h:314
@ IOOP_HIT
Definition pgstat.h:312
@ IOOP_EVICT
Definition pgstat.h:310
@ IOOP_REUSE
Definition pgstat.h:313
@ IOOP_WRITE
Definition pgstat.h:319
int64 PgStat_Counter
Definition pgstat.h:70
#define IOOBJECT_NUM_TYPES
Definition pgstat.h:285
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:477
bool pgstat_tracks_io_object(BackendType bktype, IOObject io_object, IOContext io_context)
Definition pgstat_io.c:393
#define PGSTAT_KIND_ARCHIVER
Definition pgstat_kind.h:35
#define PGSTAT_KIND_WAL
Definition pgstat_kind.h:40
#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_SLRU
Definition pgstat_kind.h:39
#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
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)
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)
#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:502
PGPROC * BackendPidGetProc(int pid)
Definition procarray.c:3156
int ProcNumber
Definition procnumber.h:24
PGPROC * AuxiliaryPidGetProc(int pid)
Definition proc.c:1085
Definition proc.h:176
uint32 wait_event_info
Definition proc.h:375
int pid
Definition proc.h:194
PGPROC * lockGroupLeader
Definition proc.h:295
TimestampTz stat_reset_timestamp
Definition pgstat.h:383
TimestampTz stat_reset_timestamp
Definition pgstat.h:392
PgStat_Counter wal_fpi
Definition pgstat.h:482
uint64 wal_fpi_bytes
Definition pgstat.h:484
PgStat_Counter wal_buffers_full
Definition pgstat.h:485
PgStat_Counter wal_records
Definition pgstat.h:481
Definition c.h:832
Definition c.h:778
#define TransactionIdIsValid(xid)
Definition transam.h:41
TupleDesc CreateTemplateTupleDesc(int natts)
Definition tupdesc.c:165
void TupleDescFinalize(TupleDesc tupdesc)
Definition tupdesc.c:508
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition tupdesc.c:897
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:373
const char * pgstat_get_wait_event(uint32 wait_event_info)
Definition wait_event.c:431
const char * name
#define stat
Definition win32_port.h:74
bool DataChecksumsEnabled(void)
Definition xlog.c:4631
void XLogPrefetchResetStats(void)