PostgreSQL Source Code  git master
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-2024, 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"
19 #include "access/xlogprefetcher.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 
35 #define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
36 
37 #define HAS_PGSTAT_PERMISSIONS(role) (has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS) || has_privs_of_role(GetUserId(), role))
38 
39 #define PG_STAT_GET_RELENTRY_INT64(stat) \
40 Datum \
41 CppConcat(pg_stat_get_,stat)(PG_FUNCTION_ARGS) \
42 { \
43  Oid relid = PG_GETARG_OID(0); \
44  int64 result; \
45  PgStat_StatTabEntry *tabentry; \
46  \
47  if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL) \
48  result = 0; \
49  else \
50  result = (int64) (tabentry->stat); \
51  \
52  PG_RETURN_INT64(result); \
53 }
54 
55 /* pg_stat_get_analyze_count */
56 PG_STAT_GET_RELENTRY_INT64(analyze_count)
57 
58 /* pg_stat_get_autoanalyze_count */
59 PG_STAT_GET_RELENTRY_INT64(autoanalyze_count)
60 
61 /* pg_stat_get_autovacuum_count */
62 PG_STAT_GET_RELENTRY_INT64(autovacuum_count)
63 
64 /* pg_stat_get_blocks_fetched */
65 PG_STAT_GET_RELENTRY_INT64(blocks_fetched)
66 
67 /* pg_stat_get_blocks_hit */
69 
70 /* pg_stat_get_dead_tuples */
71 PG_STAT_GET_RELENTRY_INT64(dead_tuples)
72 
73 /* pg_stat_get_ins_since_vacuum */
74 PG_STAT_GET_RELENTRY_INT64(ins_since_vacuum)
75 
76 /* pg_stat_get_live_tuples */
77 PG_STAT_GET_RELENTRY_INT64(live_tuples)
78 
79 /* pg_stat_get_mod_since_analyze */
80 PG_STAT_GET_RELENTRY_INT64(mod_since_analyze)
81 
82 /* pg_stat_get_numscans */
84 
85 /* pg_stat_get_tuples_deleted */
86 PG_STAT_GET_RELENTRY_INT64(tuples_deleted)
87 
88 /* pg_stat_get_tuples_fetched */
89 PG_STAT_GET_RELENTRY_INT64(tuples_fetched)
90 
91 /* pg_stat_get_tuples_hot_updated */
92 PG_STAT_GET_RELENTRY_INT64(tuples_hot_updated)
93 
94 /* pg_stat_get_tuples_newpage_updated */
95 PG_STAT_GET_RELENTRY_INT64(tuples_newpage_updated)
96 
97 /* pg_stat_get_tuples_inserted */
98 PG_STAT_GET_RELENTRY_INT64(tuples_inserted)
99 
100 /* pg_stat_get_tuples_returned */
101 PG_STAT_GET_RELENTRY_INT64(tuples_returned)
102 
103 /* pg_stat_get_tuples_updated */
104 PG_STAT_GET_RELENTRY_INT64(tuples_updated)
105 
106 /* pg_stat_get_vacuum_count */
107 PG_STAT_GET_RELENTRY_INT64(vacuum_count)
108 
109 #define PG_STAT_GET_RELENTRY_TIMESTAMPTZ(stat) \
110 Datum \
111 CppConcat(pg_stat_get_,stat)(PG_FUNCTION_ARGS) \
112 { \
113  Oid relid = PG_GETARG_OID(0); \
114  TimestampTz result; \
115  PgStat_StatTabEntry *tabentry; \
116  \
117  if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL) \
118  result = 0; \
119  else \
120  result = tabentry->stat; \
121  \
122  if (result == 0) \
123  PG_RETURN_NULL(); \
124  else \
125  PG_RETURN_TIMESTAMPTZ(result); \
126 }
127 
128 /* pg_stat_get_last_analyze_time */
129 PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_analyze_time)
130 
131 /* pg_stat_get_last_autoanalyze_time */
132 PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_autoanalyze_time)
133 
134 /* pg_stat_get_last_autovacuum_time */
135 PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_autovacuum_time)
136 
137 /* pg_stat_get_last_vacuum_time */
138 PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_vacuum_time)
139 
140 /* pg_stat_get_lastscan */
142 
143 Datum
145 {
146  Oid funcid = PG_GETARG_OID(0);
147  PgStat_StatFuncEntry *funcentry;
148 
149  if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
150  PG_RETURN_NULL();
151  PG_RETURN_INT64(funcentry->numcalls);
152 }
153 
154 /* convert counter from microsec to millisec for display */
155 #define PG_STAT_GET_FUNCENTRY_FLOAT8_MS(stat) \
156 Datum \
157 CppConcat(pg_stat_get_function_,stat)(PG_FUNCTION_ARGS) \
158 { \
159  Oid funcid = PG_GETARG_OID(0); \
160  double result; \
161  PgStat_StatFuncEntry *funcentry; \
162  \
163  if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL) \
164  PG_RETURN_NULL(); \
165  result = ((double) funcentry->stat) / 1000.0; \
166  PG_RETURN_FLOAT8(result); \
167 }
168 
169 /* pg_stat_get_function_total_time */
171 
172 /* pg_stat_get_function_self_time */
174 
175 Datum
177 {
178  FuncCallContext *funcctx;
179  int *fctx;
180 
181  /* stuff done only on the first call of the function */
182  if (SRF_IS_FIRSTCALL())
183  {
184  /* create a function context for cross-call persistence */
185  funcctx = SRF_FIRSTCALL_INIT();
186 
188  sizeof(int));
189  funcctx->user_fctx = fctx;
190 
191  fctx[0] = 0;
192  }
193 
194  /* stuff done on every call of the function */
195  funcctx = SRF_PERCALL_SETUP();
196  fctx = funcctx->user_fctx;
197 
198  fctx[0] += 1;
199 
200  /*
201  * We recheck pgstat_fetch_stat_numbackends() each time through, just in
202  * case the local status data has been refreshed since we started. It's
203  * plenty cheap enough if not. If a refresh does happen, we'll likely
204  * miss or duplicate some backend IDs, but we're content not to crash.
205  * (Refreshing midway through such a query would be problematic usage
206  * anyway, since the backend IDs we've already returned might no longer
207  * refer to extant sessions.)
208  */
209  if (fctx[0] <= pgstat_fetch_stat_numbackends())
210  {
211  /* do when there is more left to send */
213 
214  SRF_RETURN_NEXT(funcctx, Int32GetDatum(local_beentry->proc_number));
215  }
216  else
217  {
218  /* do when there is no more left */
219  SRF_RETURN_DONE(funcctx);
220  }
221 }
222 
223 /*
224  * Returns command progress information for the named command.
225  */
226 Datum
228 {
229 #define PG_STAT_GET_PROGRESS_COLS PGSTAT_NUM_PROGRESS_PARAM + 3
230  int num_backends = pgstat_fetch_stat_numbackends();
231  int curr_backend;
232  char *cmd = text_to_cstring(PG_GETARG_TEXT_PP(0));
233  ProgressCommandType cmdtype;
234  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
235 
236  /* Translate command name into command type code. */
237  if (pg_strcasecmp(cmd, "VACUUM") == 0)
238  cmdtype = PROGRESS_COMMAND_VACUUM;
239  else if (pg_strcasecmp(cmd, "ANALYZE") == 0)
240  cmdtype = PROGRESS_COMMAND_ANALYZE;
241  else if (pg_strcasecmp(cmd, "CLUSTER") == 0)
242  cmdtype = PROGRESS_COMMAND_CLUSTER;
243  else if (pg_strcasecmp(cmd, "CREATE INDEX") == 0)
245  else if (pg_strcasecmp(cmd, "BASEBACKUP") == 0)
246  cmdtype = PROGRESS_COMMAND_BASEBACKUP;
247  else if (pg_strcasecmp(cmd, "COPY") == 0)
248  cmdtype = PROGRESS_COMMAND_COPY;
249  else
250  ereport(ERROR,
251  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
252  errmsg("invalid command name: \"%s\"", cmd)));
253 
254  InitMaterializedSRF(fcinfo, 0);
255 
256  /* 1-based index */
257  for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
258  {
259  LocalPgBackendStatus *local_beentry;
260  PgBackendStatus *beentry;
262  bool nulls[PG_STAT_GET_PROGRESS_COLS] = {0};
263  int i;
264 
265  local_beentry = pgstat_get_local_beentry_by_index(curr_backend);
266  beentry = &local_beentry->backendStatus;
267 
268  /*
269  * Report values for only those backends which are running the given
270  * command.
271  */
272  if (beentry->st_progress_command != cmdtype)
273  continue;
274 
275  /* Value available to all callers */
276  values[0] = Int32GetDatum(beentry->st_procpid);
277  values[1] = ObjectIdGetDatum(beentry->st_databaseid);
278 
279  /* show rest of the values including relid only to role members */
280  if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
281  {
283  for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
284  values[i + 3] = Int64GetDatum(beentry->st_progress_param[i]);
285  }
286  else
287  {
288  nulls[2] = true;
289  for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
290  nulls[i + 3] = true;
291  }
292 
293  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
294  }
295 
296  return (Datum) 0;
297 }
298 
299 /*
300  * Returns activity of PG backends.
301  */
302 Datum
304 {
305 #define PG_STAT_GET_ACTIVITY_COLS 31
306  int num_backends = pgstat_fetch_stat_numbackends();
307  int curr_backend;
308  int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
309  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
310 
311  InitMaterializedSRF(fcinfo, 0);
312 
313  /* 1-based index */
314  for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
315  {
316  /* for each row */
318  bool nulls[PG_STAT_GET_ACTIVITY_COLS] = {0};
319  LocalPgBackendStatus *local_beentry;
320  PgBackendStatus *beentry;
321  PGPROC *proc;
322  const char *wait_event_type = NULL;
323  const char *wait_event = NULL;
324 
325  /* Get the next one in the list */
326  local_beentry = pgstat_get_local_beentry_by_index(curr_backend);
327  beentry = &local_beentry->backendStatus;
328 
329  /* If looking for specific PID, ignore all the others */
330  if (pid != -1 && beentry->st_procpid != pid)
331  continue;
332 
333  /* Values available to all callers */
334  if (beentry->st_databaseid != InvalidOid)
335  values[0] = ObjectIdGetDatum(beentry->st_databaseid);
336  else
337  nulls[0] = true;
338 
339  values[1] = Int32GetDatum(beentry->st_procpid);
340 
341  if (beentry->st_userid != InvalidOid)
342  values[2] = ObjectIdGetDatum(beentry->st_userid);
343  else
344  nulls[2] = true;
345 
346  if (beentry->st_appname)
347  values[3] = CStringGetTextDatum(beentry->st_appname);
348  else
349  nulls[3] = true;
350 
351  if (TransactionIdIsValid(local_beentry->backend_xid))
352  values[15] = TransactionIdGetDatum(local_beentry->backend_xid);
353  else
354  nulls[15] = true;
355 
356  if (TransactionIdIsValid(local_beentry->backend_xmin))
357  values[16] = TransactionIdGetDatum(local_beentry->backend_xmin);
358  else
359  nulls[16] = true;
360 
361  /* Values only available to role member or pg_read_all_stats */
362  if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
363  {
364  SockAddr zero_clientaddr;
365  char *clipped_activity;
366 
367  switch (beentry->st_state)
368  {
369  case STATE_IDLE:
370  values[4] = CStringGetTextDatum("idle");
371  break;
372  case STATE_RUNNING:
373  values[4] = CStringGetTextDatum("active");
374  break;
376  values[4] = CStringGetTextDatum("idle in transaction");
377  break;
378  case STATE_FASTPATH:
379  values[4] = CStringGetTextDatum("fastpath function call");
380  break;
382  values[4] = CStringGetTextDatum("idle in transaction (aborted)");
383  break;
384  case STATE_DISABLED:
385  values[4] = CStringGetTextDatum("disabled");
386  break;
387  case STATE_UNDEFINED:
388  nulls[4] = true;
389  break;
390  }
391 
392  clipped_activity = pgstat_clip_activity(beentry->st_activity_raw);
393  values[5] = CStringGetTextDatum(clipped_activity);
394  pfree(clipped_activity);
395 
396  /* leader_pid */
397  nulls[29] = true;
398 
399  proc = BackendPidGetProc(beentry->st_procpid);
400 
401  if (proc == NULL && (beentry->st_backendType != B_BACKEND))
402  {
403  /*
404  * For an auxiliary process, retrieve process info from
405  * AuxiliaryProcs stored in shared-memory.
406  */
407  proc = AuxiliaryPidGetProc(beentry->st_procpid);
408  }
409 
410  /*
411  * If a PGPROC entry was retrieved, display wait events and lock
412  * group leader or apply leader information if any. To avoid
413  * extra overhead, no extra lock is being held, so there is no
414  * guarantee of consistency across multiple rows.
415  */
416  if (proc != NULL)
417  {
418  uint32 raw_wait_event;
419  PGPROC *leader;
420 
421  raw_wait_event = UINT32_ACCESS_ONCE(proc->wait_event_info);
422  wait_event_type = pgstat_get_wait_event_type(raw_wait_event);
423  wait_event = pgstat_get_wait_event(raw_wait_event);
424 
425  leader = proc->lockGroupLeader;
426 
427  /*
428  * Show the leader only for active parallel workers. This
429  * leaves the field as NULL for the leader of a parallel group
430  * or the leader of parallel apply workers.
431  */
432  if (leader && leader->pid != beentry->st_procpid)
433  {
434  values[29] = Int32GetDatum(leader->pid);
435  nulls[29] = false;
436  }
437  else if (beentry->st_backendType == B_BG_WORKER)
438  {
439  int leader_pid = GetLeaderApplyWorkerPid(beentry->st_procpid);
440 
441  if (leader_pid != InvalidPid)
442  {
443  values[29] = Int32GetDatum(leader_pid);
444  nulls[29] = false;
445  }
446  }
447  }
448 
449  if (wait_event_type)
450  values[6] = CStringGetTextDatum(wait_event_type);
451  else
452  nulls[6] = true;
453 
454  if (wait_event)
455  values[7] = CStringGetTextDatum(wait_event);
456  else
457  nulls[7] = true;
458 
459  /*
460  * Don't expose transaction time for walsenders; it confuses
461  * monitoring, particularly because we don't keep the time up-to-
462  * date.
463  */
464  if (beentry->st_xact_start_timestamp != 0 &&
465  beentry->st_backendType != B_WAL_SENDER)
467  else
468  nulls[8] = true;
469 
470  if (beentry->st_activity_start_timestamp != 0)
472  else
473  nulls[9] = true;
474 
475  if (beentry->st_proc_start_timestamp != 0)
477  else
478  nulls[10] = true;
479 
480  if (beentry->st_state_start_timestamp != 0)
482  else
483  nulls[11] = true;
484 
485  /* A zeroed client addr means we don't know */
486  memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
487  if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
488  sizeof(zero_clientaddr)) == 0)
489  {
490  nulls[12] = true;
491  nulls[13] = true;
492  nulls[14] = true;
493  }
494  else
495  {
496  if (beentry->st_clientaddr.addr.ss_family == AF_INET ||
497  beentry->st_clientaddr.addr.ss_family == AF_INET6)
498  {
499  char remote_host[NI_MAXHOST];
500  char remote_port[NI_MAXSERV];
501  int ret;
502 
503  remote_host[0] = '\0';
504  remote_port[0] = '\0';
505  ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
506  beentry->st_clientaddr.salen,
507  remote_host, sizeof(remote_host),
508  remote_port, sizeof(remote_port),
509  NI_NUMERICHOST | NI_NUMERICSERV);
510  if (ret == 0)
511  {
512  clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
514  CStringGetDatum(remote_host));
515  if (beentry->st_clienthostname &&
516  beentry->st_clienthostname[0])
518  else
519  nulls[13] = true;
520  values[14] = Int32GetDatum(atoi(remote_port));
521  }
522  else
523  {
524  nulls[12] = true;
525  nulls[13] = true;
526  nulls[14] = true;
527  }
528  }
529  else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
530  {
531  /*
532  * Unix sockets always reports NULL for host and -1 for
533  * port, so it's possible to tell the difference to
534  * connections we have no permissions to view, or with
535  * errors.
536  */
537  nulls[12] = true;
538  nulls[13] = true;
539  values[14] = Int32GetDatum(-1);
540  }
541  else
542  {
543  /* Unknown address type, should never happen */
544  nulls[12] = true;
545  nulls[13] = true;
546  nulls[14] = true;
547  }
548  }
549  /* Add backend type */
550  if (beentry->st_backendType == B_BG_WORKER)
551  {
552  const char *bgw_type;
553 
554  bgw_type = GetBackgroundWorkerTypeByPid(beentry->st_procpid);
555  if (bgw_type)
556  values[17] = CStringGetTextDatum(bgw_type);
557  else
558  nulls[17] = true;
559  }
560  else
561  values[17] =
563 
564  /* SSL information */
565  if (beentry->st_ssl)
566  {
567  values[18] = BoolGetDatum(true); /* ssl */
570  values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
571 
572  if (beentry->st_sslstatus->ssl_client_dn[0])
574  else
575  nulls[22] = true;
576 
577  if (beentry->st_sslstatus->ssl_client_serial[0])
581  Int32GetDatum(-1));
582  else
583  nulls[23] = true;
584 
585  if (beentry->st_sslstatus->ssl_issuer_dn[0])
587  else
588  nulls[24] = true;
589  }
590  else
591  {
592  values[18] = BoolGetDatum(false); /* ssl */
593  nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = true;
594  }
595 
596  /* GSSAPI information */
597  if (beentry->st_gss)
598  {
599  values[25] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */
601  values[27] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */
602  values[28] = BoolGetDatum(beentry->st_gssstatus->gss_delegation); /* GSS credentials
603  * delegated */
604  }
605  else
606  {
607  values[25] = BoolGetDatum(false); /* gss_auth */
608  nulls[26] = true; /* No GSS principal */
609  values[27] = BoolGetDatum(false); /* GSS Encryption not in
610  * use */
611  values[28] = BoolGetDatum(false); /* GSS credentials not
612  * delegated */
613  }
614  if (beentry->st_query_id == 0)
615  nulls[30] = true;
616  else
617  values[30] = UInt64GetDatum(beentry->st_query_id);
618  }
619  else
620  {
621  /* No permissions to view data about this session */
622  values[5] = CStringGetTextDatum("<insufficient privilege>");
623  nulls[4] = true;
624  nulls[6] = true;
625  nulls[7] = true;
626  nulls[8] = true;
627  nulls[9] = true;
628  nulls[10] = true;
629  nulls[11] = true;
630  nulls[12] = true;
631  nulls[13] = true;
632  nulls[14] = true;
633  nulls[17] = true;
634  nulls[18] = true;
635  nulls[19] = true;
636  nulls[20] = true;
637  nulls[21] = true;
638  nulls[22] = true;
639  nulls[23] = true;
640  nulls[24] = true;
641  nulls[25] = true;
642  nulls[26] = true;
643  nulls[27] = true;
644  nulls[28] = true;
645  nulls[29] = true;
646  nulls[30] = true;
647  }
648 
649  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
650 
651  /* If only a single backend was requested, and we found it, break. */
652  if (pid != -1)
653  break;
654  }
655 
656  return (Datum) 0;
657 }
658 
659 
660 Datum
662 {
664 }
665 
666 
667 Datum
669 {
670  int32 procNumber = PG_GETARG_INT32(0);
671  PgBackendStatus *beentry;
672 
673  if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
674  PG_RETURN_NULL();
675 
676  PG_RETURN_INT32(beentry->st_procpid);
677 }
678 
679 
680 Datum
682 {
683  int32 procNumber = PG_GETARG_INT32(0);
684  PgBackendStatus *beentry;
685 
686  if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
687  PG_RETURN_NULL();
688 
689  PG_RETURN_OID(beentry->st_databaseid);
690 }
691 
692 
693 Datum
695 {
696  int32 procNumber = PG_GETARG_INT32(0);
697  PgBackendStatus *beentry;
698 
699  if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
700  PG_RETURN_NULL();
701 
702  PG_RETURN_OID(beentry->st_userid);
703 }
704 
705 Datum
707 {
708 #define PG_STAT_GET_SUBXACT_COLS 2
709  TupleDesc tupdesc;
711  bool nulls[PG_STAT_GET_SUBXACT_COLS] = {0};
712  int32 procNumber = PG_GETARG_INT32(0);
713  LocalPgBackendStatus *local_beentry;
714 
715  /* Initialise attributes information in the tuple descriptor */
717  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subxact_count",
718  INT4OID, -1, 0);
719  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "subxact_overflow",
720  BOOLOID, -1, 0);
721 
722  BlessTupleDesc(tupdesc);
723 
724  if ((local_beentry = pgstat_get_local_beentry_by_proc_number(procNumber)) != NULL)
725  {
726  /* Fill values and NULLs */
727  values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
728  values[1] = BoolGetDatum(local_beentry->backend_subxact_overflowed);
729  }
730  else
731  {
732  nulls[0] = true;
733  nulls[1] = true;
734  }
735 
736  /* Returns the record as Datum */
738 }
739 
740 Datum
742 {
743  int32 procNumber = PG_GETARG_INT32(0);
744  PgBackendStatus *beentry;
745  const char *activity;
746  char *clipped_activity;
747  text *ret;
748 
749  if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
750  activity = "<backend information not available>";
751  else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
752  activity = "<insufficient privilege>";
753  else if (*(beentry->st_activity_raw) == '\0')
754  activity = "<command string not enabled>";
755  else
756  activity = beentry->st_activity_raw;
757 
758  clipped_activity = pgstat_clip_activity(activity);
759  ret = cstring_to_text(activity);
760  pfree(clipped_activity);
761 
762  PG_RETURN_TEXT_P(ret);
763 }
764 
765 Datum
767 {
768  int32 procNumber = PG_GETARG_INT32(0);
769  PgBackendStatus *beentry;
770  PGPROC *proc;
771  const char *wait_event_type = NULL;
772 
773  if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
774  wait_event_type = "<backend information not available>";
775  else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
776  wait_event_type = "<insufficient privilege>";
777  else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
778  wait_event_type = pgstat_get_wait_event_type(proc->wait_event_info);
779 
780  if (!wait_event_type)
781  PG_RETURN_NULL();
782 
783  PG_RETURN_TEXT_P(cstring_to_text(wait_event_type));
784 }
785 
786 Datum
788 {
789  int32 procNumber = PG_GETARG_INT32(0);
790  PgBackendStatus *beentry;
791  PGPROC *proc;
792  const char *wait_event = NULL;
793 
794  if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
795  wait_event = "<backend information not available>";
796  else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
797  wait_event = "<insufficient privilege>";
798  else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
799  wait_event = pgstat_get_wait_event(proc->wait_event_info);
800 
801  if (!wait_event)
802  PG_RETURN_NULL();
803 
804  PG_RETURN_TEXT_P(cstring_to_text(wait_event));
805 }
806 
807 
808 Datum
810 {
811  int32 procNumber = PG_GETARG_INT32(0);
812  TimestampTz result;
813  PgBackendStatus *beentry;
814 
815  if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
816  PG_RETURN_NULL();
817 
818  else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
819  PG_RETURN_NULL();
820 
821  result = beentry->st_activity_start_timestamp;
822 
823  /*
824  * No time recorded for start of current query -- this is the case if the
825  * user hasn't enabled query-level stats collection.
826  */
827  if (result == 0)
828  PG_RETURN_NULL();
829 
830  PG_RETURN_TIMESTAMPTZ(result);
831 }
832 
833 
834 Datum
836 {
837  int32 procNumber = PG_GETARG_INT32(0);
838  TimestampTz result;
839  PgBackendStatus *beentry;
840 
841  if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
842  PG_RETURN_NULL();
843 
844  else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
845  PG_RETURN_NULL();
846 
847  result = beentry->st_xact_start_timestamp;
848 
849  if (result == 0) /* not in a transaction */
850  PG_RETURN_NULL();
851 
852  PG_RETURN_TIMESTAMPTZ(result);
853 }
854 
855 
856 Datum
858 {
859  int32 procNumber = PG_GETARG_INT32(0);
860  TimestampTz result;
861  PgBackendStatus *beentry;
862 
863  if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
864  PG_RETURN_NULL();
865 
866  else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
867  PG_RETURN_NULL();
868 
869  result = beentry->st_proc_start_timestamp;
870 
871  if (result == 0) /* probably can't happen? */
872  PG_RETURN_NULL();
873 
874  PG_RETURN_TIMESTAMPTZ(result);
875 }
876 
877 
878 Datum
880 {
881  int32 procNumber = PG_GETARG_INT32(0);
882  PgBackendStatus *beentry;
883  SockAddr zero_clientaddr;
884  char remote_host[NI_MAXHOST];
885  int ret;
886 
887  if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
888  PG_RETURN_NULL();
889 
890  else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
891  PG_RETURN_NULL();
892 
893  /* A zeroed client addr means we don't know */
894  memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
895  if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
896  sizeof(zero_clientaddr)) == 0)
897  PG_RETURN_NULL();
898 
899  switch (beentry->st_clientaddr.addr.ss_family)
900  {
901  case AF_INET:
902  case AF_INET6:
903  break;
904  default:
905  PG_RETURN_NULL();
906  }
907 
908  remote_host[0] = '\0';
909  ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
910  beentry->st_clientaddr.salen,
911  remote_host, sizeof(remote_host),
912  NULL, 0,
913  NI_NUMERICHOST | NI_NUMERICSERV);
914  if (ret != 0)
915  PG_RETURN_NULL();
916 
917  clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
918 
920  CStringGetDatum(remote_host)));
921 }
922 
923 Datum
925 {
926  int32 procNumber = PG_GETARG_INT32(0);
927  PgBackendStatus *beentry;
928  SockAddr zero_clientaddr;
929  char remote_port[NI_MAXSERV];
930  int ret;
931 
932  if ((beentry = pgstat_get_beentry_by_proc_number(procNumber)) == NULL)
933  PG_RETURN_NULL();
934 
935  else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
936  PG_RETURN_NULL();
937 
938  /* A zeroed client addr means we don't know */
939  memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
940  if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
941  sizeof(zero_clientaddr)) == 0)
942  PG_RETURN_NULL();
943 
944  switch (beentry->st_clientaddr.addr.ss_family)
945  {
946  case AF_INET:
947  case AF_INET6:
948  break;
949  case AF_UNIX:
950  PG_RETURN_INT32(-1);
951  default:
952  PG_RETURN_NULL();
953  }
954 
955  remote_port[0] = '\0';
956  ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
957  beentry->st_clientaddr.salen,
958  NULL, 0,
959  remote_port, sizeof(remote_port),
960  NI_NUMERICHOST | NI_NUMERICSERV);
961  if (ret != 0)
962  PG_RETURN_NULL();
963 
965  CStringGetDatum(remote_port)));
966 }
967 
968 
969 Datum
971 {
972  Oid dbid = PG_GETARG_OID(0);
973  int32 result;
974  int tot_backends = pgstat_fetch_stat_numbackends();
975  int idx;
976 
977  result = 0;
978  for (idx = 1; idx <= tot_backends; idx++)
979  {
981 
982  if (local_beentry->backendStatus.st_databaseid == dbid)
983  result++;
984  }
985 
986  PG_RETURN_INT32(result);
987 }
988 
989 
990 #define PG_STAT_GET_DBENTRY_INT64(stat) \
991 Datum \
992 CppConcat(pg_stat_get_db_,stat)(PG_FUNCTION_ARGS) \
993 { \
994  Oid dbid = PG_GETARG_OID(0); \
995  int64 result; \
996  PgStat_StatDBEntry *dbentry; \
997  \
998  if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) \
999  result = 0; \
1000  else \
1001  result = (int64) (dbentry->stat); \
1002  \
1003  PG_RETURN_INT64(result); \
1004 }
1005 
1006 /* pg_stat_get_db_blocks_fetched */
1007 PG_STAT_GET_DBENTRY_INT64(blocks_fetched)
1008 
1009 /* pg_stat_get_db_blocks_hit */
1010 PG_STAT_GET_DBENTRY_INT64(blocks_hit)
1011 
1012 /* pg_stat_get_db_conflict_bufferpin */
1013 PG_STAT_GET_DBENTRY_INT64(conflict_bufferpin)
1014 
1015 /* pg_stat_get_db_conflict_lock */
1016 PG_STAT_GET_DBENTRY_INT64(conflict_lock)
1017 
1018 /* pg_stat_get_db_conflict_snapshot */
1019 PG_STAT_GET_DBENTRY_INT64(conflict_snapshot)
1020 
1021 /* pg_stat_get_db_conflict_startup_deadlock */
1022 PG_STAT_GET_DBENTRY_INT64(conflict_startup_deadlock)
1023 
1024 /* pg_stat_get_db_conflict_tablespace */
1025 PG_STAT_GET_DBENTRY_INT64(conflict_tablespace)
1026 
1027 /* pg_stat_get_db_deadlocks */
1028 PG_STAT_GET_DBENTRY_INT64(deadlocks)
1029 
1030 /* pg_stat_get_db_sessions */
1031 PG_STAT_GET_DBENTRY_INT64(sessions)
1032 
1033 /* pg_stat_get_db_sessions_abandoned */
1034 PG_STAT_GET_DBENTRY_INT64(sessions_abandoned)
1035 
1036 /* pg_stat_get_db_sessions_fatal */
1037 PG_STAT_GET_DBENTRY_INT64(sessions_fatal)
1038 
1039 /* pg_stat_get_db_sessions_killed */
1040 PG_STAT_GET_DBENTRY_INT64(sessions_killed)
1041 
1042 /* pg_stat_get_db_temp_bytes */
1043 PG_STAT_GET_DBENTRY_INT64(temp_bytes)
1044 
1045 /* pg_stat_get_db_temp_files */
1046 PG_STAT_GET_DBENTRY_INT64(temp_files)
1047 
1048 /* pg_stat_get_db_tuples_deleted */
1049 PG_STAT_GET_DBENTRY_INT64(tuples_deleted)
1050 
1051 /* pg_stat_get_db_tuples_fetched */
1052 PG_STAT_GET_DBENTRY_INT64(tuples_fetched)
1053 
1054 /* pg_stat_get_db_tuples_inserted */
1055 PG_STAT_GET_DBENTRY_INT64(tuples_inserted)
1056 
1057 /* pg_stat_get_db_tuples_returned */
1058 PG_STAT_GET_DBENTRY_INT64(tuples_returned)
1059 
1060 /* pg_stat_get_db_tuples_updated */
1061 PG_STAT_GET_DBENTRY_INT64(tuples_updated)
1062 
1063 /* pg_stat_get_db_xact_commit */
1064 PG_STAT_GET_DBENTRY_INT64(xact_commit)
1065 
1066 /* pg_stat_get_db_xact_rollback */
1067 PG_STAT_GET_DBENTRY_INT64(xact_rollback)
1068 
1069 /* pg_stat_get_db_conflict_logicalslot */
1070 PG_STAT_GET_DBENTRY_INT64(conflict_logicalslot)
1071 
1072 Datum
1074 {
1075  Oid dbid = PG_GETARG_OID(0);
1076  TimestampTz result;
1077  PgStat_StatDBEntry *dbentry;
1078 
1079  if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1080  result = 0;
1081  else
1082  result = dbentry->stat_reset_timestamp;
1083 
1084  if (result == 0)
1085  PG_RETURN_NULL();
1086  else
1087  PG_RETURN_TIMESTAMPTZ(result);
1088 }
1089 
1090 
1091 Datum
1093 {
1094  Oid dbid = PG_GETARG_OID(0);
1095  int64 result;
1096  PgStat_StatDBEntry *dbentry;
1097 
1098  if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1099  result = 0;
1100  else
1101  result = (int64) (dbentry->conflict_tablespace +
1102  dbentry->conflict_lock +
1103  dbentry->conflict_snapshot +
1104  dbentry->conflict_logicalslot +
1105  dbentry->conflict_bufferpin +
1106  dbentry->conflict_startup_deadlock);
1107 
1108  PG_RETURN_INT64(result);
1109 }
1110 
1111 Datum
1113 {
1114  Oid dbid = PG_GETARG_OID(0);
1115  int64 result;
1116  PgStat_StatDBEntry *dbentry;
1117 
1118  if (!DataChecksumsEnabled())
1119  PG_RETURN_NULL();
1120 
1121  if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1122  result = 0;
1123  else
1124  result = (int64) (dbentry->checksum_failures);
1125 
1126  PG_RETURN_INT64(result);
1127 }
1128 
1129 Datum
1131 {
1132  Oid dbid = PG_GETARG_OID(0);
1133  TimestampTz result;
1134  PgStat_StatDBEntry *dbentry;
1135 
1136  if (!DataChecksumsEnabled())
1137  PG_RETURN_NULL();
1138 
1139  if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1140  result = 0;
1141  else
1142  result = dbentry->last_checksum_failure;
1143 
1144  if (result == 0)
1145  PG_RETURN_NULL();
1146  else
1147  PG_RETURN_TIMESTAMPTZ(result);
1148 }
1149 
1150 /* convert counter from microsec to millisec for display */
1151 #define PG_STAT_GET_DBENTRY_FLOAT8_MS(stat) \
1152 Datum \
1153 CppConcat(pg_stat_get_db_,stat)(PG_FUNCTION_ARGS) \
1154 { \
1155  Oid dbid = PG_GETARG_OID(0); \
1156  double result; \
1157  PgStat_StatDBEntry *dbentry; \
1158  \
1159  if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) \
1160  result = 0; \
1161  else \
1162  result = ((double) dbentry->stat) / 1000.0; \
1163  \
1164  PG_RETURN_FLOAT8(result); \
1165 }
1166 
1167 /* pg_stat_get_db_active_time */
1168 PG_STAT_GET_DBENTRY_FLOAT8_MS(active_time)
1169 
1170 /* pg_stat_get_db_blk_read_time */
1171 PG_STAT_GET_DBENTRY_FLOAT8_MS(blk_read_time)
1172 
1173 /* pg_stat_get_db_blk_write_time */
1174 PG_STAT_GET_DBENTRY_FLOAT8_MS(blk_write_time)
1175 
1176 /* pg_stat_get_db_idle_in_transaction_time */
1177 PG_STAT_GET_DBENTRY_FLOAT8_MS(idle_in_transaction_time)
1178 
1179 /* pg_stat_get_db_session_time */
1180 PG_STAT_GET_DBENTRY_FLOAT8_MS(session_time)
1181 
1182 Datum
1184 {
1186 }
1187 
1188 Datum
1190 {
1192 }
1193 
1194 Datum
1196 {
1198 }
1199 
1200 Datum
1202 {
1203  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->restartpoints_timed);
1204 }
1205 
1206 Datum
1208 {
1209  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->restartpoints_requested);
1210 }
1211 
1212 Datum
1214 {
1215  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->restartpoints_performed);
1216 }
1217 
1218 Datum
1220 {
1221  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->buffers_written);
1222 }
1223 
1224 Datum
1226 {
1228 }
1229 
1230 Datum
1232 {
1233  PG_RETURN_INT64(pgstat_fetch_stat_bgwriter()->buf_written_clean);
1234 }
1235 
1236 Datum
1238 {
1239  PG_RETURN_INT64(pgstat_fetch_stat_bgwriter()->maxwritten_clean);
1240 }
1241 
1242 Datum
1244 {
1245  /* time is already in msec, just convert to double for presentation */
1246  PG_RETURN_FLOAT8((double)
1247  pgstat_fetch_stat_checkpointer()->write_time);
1248 }
1249 
1250 Datum
1252 {
1253  /* time is already in msec, just convert to double for presentation */
1254  PG_RETURN_FLOAT8((double)
1255  pgstat_fetch_stat_checkpointer()->sync_time);
1256 }
1257 
1258 Datum
1260 {
1261  PG_RETURN_TIMESTAMPTZ(pgstat_fetch_stat_checkpointer()->stat_reset_timestamp);
1262 }
1263 
1264 Datum
1266 {
1267  PG_RETURN_TIMESTAMPTZ(pgstat_fetch_stat_bgwriter()->stat_reset_timestamp);
1268 }
1269 
1270 Datum
1272 {
1274 }
1275 
1276 /*
1277 * When adding a new column to the pg_stat_io view, add a new enum value
1278 * here above IO_NUM_COLUMNS.
1279 */
1280 typedef enum io_stat_col
1281 {
1303 
1304 /*
1305  * When adding a new IOOp, add a new io_stat_col and add a case to this
1306  * function returning the corresponding io_stat_col.
1307  */
1308 static io_stat_col
1310 {
1311  switch (io_op)
1312  {
1313  case IOOP_EVICT:
1314  return IO_COL_EVICTIONS;
1315  case IOOP_EXTEND:
1316  return IO_COL_EXTENDS;
1317  case IOOP_FSYNC:
1318  return IO_COL_FSYNCS;
1319  case IOOP_HIT:
1320  return IO_COL_HITS;
1321  case IOOP_READ:
1322  return IO_COL_READS;
1323  case IOOP_REUSE:
1324  return IO_COL_REUSES;
1325  case IOOP_WRITE:
1326  return IO_COL_WRITES;
1327  case IOOP_WRITEBACK:
1328  return IO_COL_WRITEBACKS;
1329  }
1330 
1331  elog(ERROR, "unrecognized IOOp value: %d", io_op);
1332  pg_unreachable();
1333 }
1334 
1335 /*
1336  * Get the number of the column containing IO times for the specified IOOp.
1337  * This function encodes our assumption that IO time for an IOOp is displayed
1338  * in the view in the column directly after the IOOp counts. If an op has no
1339  * associated time, IO_COL_INVALID is returned.
1340  */
1341 static io_stat_col
1343 {
1344  switch (io_op)
1345  {
1346  case IOOP_READ:
1347  case IOOP_WRITE:
1348  case IOOP_WRITEBACK:
1349  case IOOP_EXTEND:
1350  case IOOP_FSYNC:
1351  return pgstat_get_io_op_index(io_op) + 1;
1352  case IOOP_EVICT:
1353  case IOOP_HIT:
1354  case IOOP_REUSE:
1355  return IO_COL_INVALID;
1356  }
1357 
1358  elog(ERROR, "unrecognized IOOp value: %d", io_op);
1359  pg_unreachable();
1360 }
1361 
1362 static inline double
1364 {
1365  return val_ms * (double) 0.001;
1366 }
1367 
1368 Datum
1370 {
1371  ReturnSetInfo *rsinfo;
1372  PgStat_IO *backends_io_stats;
1373  Datum reset_time;
1374 
1375  InitMaterializedSRF(fcinfo, 0);
1376  rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1377 
1378  backends_io_stats = pgstat_fetch_stat_io();
1379 
1380  reset_time = TimestampTzGetDatum(backends_io_stats->stat_reset_timestamp);
1381 
1382  for (int bktype = 0; bktype < BACKEND_NUM_TYPES; bktype++)
1383  {
1384  Datum bktype_desc = CStringGetTextDatum(GetBackendTypeDesc(bktype));
1385  PgStat_BktypeIO *bktype_stats = &backends_io_stats->stats[bktype];
1386 
1387  /*
1388  * In Assert builds, we can afford an extra loop through all of the
1389  * counters checking that only expected stats are non-zero, since it
1390  * keeps the non-Assert code cleaner.
1391  */
1392  Assert(pgstat_bktype_io_stats_valid(bktype_stats, bktype));
1393 
1394  /*
1395  * For those BackendTypes without IO Operation stats, skip
1396  * representing them in the view altogether.
1397  */
1398  if (!pgstat_tracks_io_bktype(bktype))
1399  continue;
1400 
1401  for (int io_obj = 0; io_obj < IOOBJECT_NUM_TYPES; io_obj++)
1402  {
1403  const char *obj_name = pgstat_get_io_object_name(io_obj);
1404 
1405  for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++)
1406  {
1407  const char *context_name = pgstat_get_io_context_name(io_context);
1408 
1409  Datum values[IO_NUM_COLUMNS] = {0};
1410  bool nulls[IO_NUM_COLUMNS] = {0};
1411 
1412  /*
1413  * Some combinations of BackendType, IOObject, and IOContext
1414  * are not valid for any type of IOOp. In such cases, omit the
1415  * entire row from the view.
1416  */
1417  if (!pgstat_tracks_io_object(bktype, io_obj, io_context))
1418  continue;
1419 
1420  values[IO_COL_BACKEND_TYPE] = bktype_desc;
1421  values[IO_COL_CONTEXT] = CStringGetTextDatum(context_name);
1423  values[IO_COL_RESET_TIME] = reset_time;
1424 
1425  /*
1426  * Hard-code this to the value of BLCKSZ for now. Future
1427  * values could include XLOG_BLCKSZ, once WAL IO is tracked,
1428  * and constant multipliers, once non-block-oriented IO (e.g.
1429  * temporary file IO) is tracked.
1430  */
1432 
1433  for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
1434  {
1435  int op_idx = pgstat_get_io_op_index(io_op);
1436  int time_idx = pgstat_get_io_time_index(io_op);
1437 
1438  /*
1439  * Some combinations of BackendType and IOOp, of IOContext
1440  * and IOOp, and of IOObject and IOOp are not tracked. Set
1441  * these cells in the view NULL.
1442  */
1443  if (pgstat_tracks_io_op(bktype, io_obj, io_context, io_op))
1444  {
1445  PgStat_Counter count =
1446  bktype_stats->counts[io_obj][io_context][io_op];
1447 
1448  values[op_idx] = Int64GetDatum(count);
1449  }
1450  else
1451  nulls[op_idx] = true;
1452 
1453  /* not every operation is timed */
1454  if (time_idx == IO_COL_INVALID)
1455  continue;
1456 
1457  if (!nulls[op_idx])
1458  {
1459  PgStat_Counter time =
1460  bktype_stats->times[io_obj][io_context][io_op];
1461 
1462  values[time_idx] = Float8GetDatum(pg_stat_us_to_ms(time));
1463  }
1464  else
1465  nulls[time_idx] = true;
1466  }
1467 
1468  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
1469  values, nulls);
1470  }
1471  }
1472  }
1473 
1474  return (Datum) 0;
1475 }
1476 
1477 /*
1478  * Returns statistics of WAL activity
1479  */
1480 Datum
1482 {
1483 #define PG_STAT_GET_WAL_COLS 9
1484  TupleDesc tupdesc;
1486  bool nulls[PG_STAT_GET_WAL_COLS] = {0};
1487  char buf[256];
1488  PgStat_WalStats *wal_stats;
1489 
1490  /* Initialise attributes information in the tuple descriptor */
1492  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "wal_records",
1493  INT8OID, -1, 0);
1494  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "wal_fpi",
1495  INT8OID, -1, 0);
1496  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "wal_bytes",
1497  NUMERICOID, -1, 0);
1498  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_buffers_full",
1499  INT8OID, -1, 0);
1500  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "wal_write",
1501  INT8OID, -1, 0);
1502  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "wal_sync",
1503  INT8OID, -1, 0);
1504  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "wal_write_time",
1505  FLOAT8OID, -1, 0);
1506  TupleDescInitEntry(tupdesc, (AttrNumber) 8, "wal_sync_time",
1507  FLOAT8OID, -1, 0);
1508  TupleDescInitEntry(tupdesc, (AttrNumber) 9, "stats_reset",
1509  TIMESTAMPTZOID, -1, 0);
1510 
1511  BlessTupleDesc(tupdesc);
1512 
1513  /* Get statistics about WAL activity */
1514  wal_stats = pgstat_fetch_stat_wal();
1515 
1516  /* Fill values and NULLs */
1517  values[0] = Int64GetDatum(wal_stats->wal_records);
1518  values[1] = Int64GetDatum(wal_stats->wal_fpi);
1519 
1520  /* Convert to numeric. */
1521  snprintf(buf, sizeof buf, UINT64_FORMAT, wal_stats->wal_bytes);
1524  ObjectIdGetDatum(0),
1525  Int32GetDatum(-1));
1526 
1527  values[3] = Int64GetDatum(wal_stats->wal_buffers_full);
1528  values[4] = Int64GetDatum(wal_stats->wal_write);
1529  values[5] = Int64GetDatum(wal_stats->wal_sync);
1530 
1531  /* Convert counters from microsec to millisec for display */
1532  values[6] = Float8GetDatum(((double) wal_stats->wal_write_time) / 1000.0);
1533  values[7] = Float8GetDatum(((double) wal_stats->wal_sync_time) / 1000.0);
1534 
1536 
1537  /* Returns the record as Datum */
1539 }
1540 
1541 /*
1542  * Returns statistics of SLRU caches.
1543  */
1544 Datum
1546 {
1547 #define PG_STAT_GET_SLRU_COLS 9
1548  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1549  int i;
1550  PgStat_SLRUStats *stats;
1551 
1552  InitMaterializedSRF(fcinfo, 0);
1553 
1554  /* request SLRU stats from the cumulative stats system */
1555  stats = pgstat_fetch_slru();
1556 
1557  for (i = 0;; i++)
1558  {
1559  /* for each row */
1561  bool nulls[PG_STAT_GET_SLRU_COLS] = {0};
1563  const char *name;
1564 
1566 
1567  if (!name)
1568  break;
1569 
1570  stat = stats[i];
1571 
1573  values[1] = Int64GetDatum(stat.blocks_zeroed);
1574  values[2] = Int64GetDatum(stat.blocks_hit);
1575  values[3] = Int64GetDatum(stat.blocks_read);
1576  values[4] = Int64GetDatum(stat.blocks_written);
1577  values[5] = Int64GetDatum(stat.blocks_exists);
1578  values[6] = Int64GetDatum(stat.flush);
1579  values[7] = Int64GetDatum(stat.truncate);
1580  values[8] = TimestampTzGetDatum(stat.stat_reset_timestamp);
1581 
1582  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
1583  }
1584 
1585  return (Datum) 0;
1586 }
1587 
1588 #define PG_STAT_GET_XACT_RELENTRY_INT64(stat) \
1589 Datum \
1590 CppConcat(pg_stat_get_xact_,stat)(PG_FUNCTION_ARGS) \
1591 { \
1592  Oid relid = PG_GETARG_OID(0); \
1593  int64 result; \
1594  PgStat_TableStatus *tabentry; \
1595  \
1596  if ((tabentry = find_tabstat_entry(relid)) == NULL) \
1597  result = 0; \
1598  else \
1599  result = (int64) (tabentry->counts.stat); \
1600  \
1601  PG_RETURN_INT64(result); \
1602 }
1603 
1604 /* pg_stat_get_xact_numscans */
1606 
1607 /* pg_stat_get_xact_tuples_returned */
1608 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_returned)
1609 
1610 /* pg_stat_get_xact_tuples_fetched */
1611 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_fetched)
1612 
1613 /* pg_stat_get_xact_tuples_hot_updated */
1614 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_hot_updated)
1615 
1616 /* pg_stat_get_xact_tuples_newpage_updated */
1617 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_newpage_updated)
1618 
1619 /* pg_stat_get_xact_blocks_fetched */
1620 PG_STAT_GET_XACT_RELENTRY_INT64(blocks_fetched)
1621 
1622 /* pg_stat_get_xact_blocks_hit */
1624 
1625 /* pg_stat_get_xact_tuples_inserted */
1626 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_inserted)
1627 
1628 /* pg_stat_get_xact_tuples_updated */
1629 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_updated)
1630 
1631 /* pg_stat_get_xact_tuples_deleted */
1632 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_deleted)
1633 
1634 Datum
1636 {
1637  Oid funcid = PG_GETARG_OID(0);
1638  PgStat_FunctionCounts *funcentry;
1639 
1640  if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1641  PG_RETURN_NULL();
1642  PG_RETURN_INT64(funcentry->numcalls);
1643 }
1644 
1645 #define PG_STAT_GET_XACT_FUNCENTRY_FLOAT8_MS(stat) \
1646 Datum \
1647 CppConcat(pg_stat_get_xact_function_,stat)(PG_FUNCTION_ARGS) \
1648 { \
1649  Oid funcid = PG_GETARG_OID(0); \
1650  PgStat_FunctionCounts *funcentry; \
1651  \
1652  if ((funcentry = find_funcstat_entry(funcid)) == NULL) \
1653  PG_RETURN_NULL(); \
1654  PG_RETURN_FLOAT8(INSTR_TIME_GET_MILLISEC(funcentry->stat)); \
1655 }
1656 
1657 /* pg_stat_get_xact_function_total_time */
1659 
1660 /* pg_stat_get_xact_function_self_time */
1662 
1663 /* Get the timestamp of the current statistics snapshot */
1664 Datum
1666 {
1667  bool have_snapshot;
1668  TimestampTz ts;
1669 
1670  ts = pgstat_get_stat_snapshot_timestamp(&have_snapshot);
1671 
1672  if (!have_snapshot)
1673  PG_RETURN_NULL();
1674 
1676 }
1677 
1678 /* Discard the active statistics snapshot */
1679 Datum
1681 {
1683 
1684  PG_RETURN_VOID();
1685 }
1686 
1687 
1688 /* Force statistics to be reported at the next occasion */
1689 Datum
1691 {
1693 
1694  PG_RETURN_VOID();
1695 }
1696 
1697 
1698 /* Reset all counters for the current database */
1699 Datum
1701 {
1703 
1704  PG_RETURN_VOID();
1705 }
1706 
1707 /*
1708  * Reset some shared cluster-wide counters
1709  *
1710  * When adding a new reset target, ideally the name should match that in
1711  * pgstat_kind_builtin_infos, if relevant.
1712  */
1713 Datum
1715 {
1716  char *target = NULL;
1717 
1718  if (PG_ARGISNULL(0))
1719  {
1720  /* Reset all the statistics when nothing is specified */
1728 
1729  PG_RETURN_VOID();
1730  }
1731 
1732  target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1733 
1734  if (strcmp(target, "archiver") == 0)
1736  else if (strcmp(target, "bgwriter") == 0)
1738  else if (strcmp(target, "checkpointer") == 0)
1740  else if (strcmp(target, "io") == 0)
1742  else if (strcmp(target, "recovery_prefetch") == 0)
1744  else if (strcmp(target, "slru") == 0)
1746  else if (strcmp(target, "wal") == 0)
1748  else
1749  ereport(ERROR,
1750  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1751  errmsg("unrecognized reset target: \"%s\"", target),
1752  errhint("Target must be \"archiver\", \"bgwriter\", \"checkpointer\", \"io\", \"recovery_prefetch\", \"slru\", or \"wal\".")));
1753 
1754  PG_RETURN_VOID();
1755 }
1756 
1757 /*
1758  * Reset a statistics for a single object, which may be of current
1759  * database or shared across all databases in the cluster.
1760  */
1761 Datum
1763 {
1764  Oid taboid = PG_GETARG_OID(0);
1765  Oid dboid = (IsSharedRelation(taboid) ? InvalidOid : MyDatabaseId);
1766 
1767  pgstat_reset(PGSTAT_KIND_RELATION, dboid, taboid);
1768 
1769  PG_RETURN_VOID();
1770 }
1771 
1772 Datum
1774 {
1775  Oid funcoid = PG_GETARG_OID(0);
1776 
1778 
1779  PG_RETURN_VOID();
1780 }
1781 
1782 /* Reset SLRU counters (a specific one or all of them). */
1783 Datum
1785 {
1786  char *target = NULL;
1787 
1788  if (PG_ARGISNULL(0))
1790  else
1791  {
1792  target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1793  pgstat_reset_slru(target);
1794  }
1795 
1796  PG_RETURN_VOID();
1797 }
1798 
1799 /* Reset replication slots stats (a specific one or all of them). */
1800 Datum
1802 {
1803  char *target = NULL;
1804 
1805  if (PG_ARGISNULL(0))
1807  else
1808  {
1809  target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1810  pgstat_reset_replslot(target);
1811  }
1812 
1813  PG_RETURN_VOID();
1814 }
1815 
1816 /* Reset subscription stats (a specific one or all of them) */
1817 Datum
1819 {
1820  Oid subid;
1821 
1822  if (PG_ARGISNULL(0))
1823  {
1824  /* Clear all subscription stats */
1826  }
1827  else
1828  {
1829  subid = PG_GETARG_OID(0);
1830 
1831  if (!OidIsValid(subid))
1832  ereport(ERROR,
1833  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1834  errmsg("invalid subscription OID %u", subid)));
1836  }
1837 
1838  PG_RETURN_VOID();
1839 }
1840 
1841 Datum
1843 {
1844  TupleDesc tupdesc;
1845  Datum values[7] = {0};
1846  bool nulls[7] = {0};
1847  PgStat_ArchiverStats *archiver_stats;
1848 
1849  /* Initialise attributes information in the tuple descriptor */
1850  tupdesc = CreateTemplateTupleDesc(7);
1851  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
1852  INT8OID, -1, 0);
1853  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal",
1854  TEXTOID, -1, 0);
1855  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_archived_time",
1856  TIMESTAMPTZOID, -1, 0);
1857  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "failed_count",
1858  INT8OID, -1, 0);
1859  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_failed_wal",
1860  TEXTOID, -1, 0);
1861  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_failed_time",
1862  TIMESTAMPTZOID, -1, 0);
1863  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stats_reset",
1864  TIMESTAMPTZOID, -1, 0);
1865 
1866  BlessTupleDesc(tupdesc);
1867 
1868  /* Get statistics about the archiver process */
1869  archiver_stats = pgstat_fetch_stat_archiver();
1870 
1871  /* Fill values and NULLs */
1872  values[0] = Int64GetDatum(archiver_stats->archived_count);
1873  if (*(archiver_stats->last_archived_wal) == '\0')
1874  nulls[1] = true;
1875  else
1876  values[1] = CStringGetTextDatum(archiver_stats->last_archived_wal);
1877 
1878  if (archiver_stats->last_archived_timestamp == 0)
1879  nulls[2] = true;
1880  else
1881  values[2] = TimestampTzGetDatum(archiver_stats->last_archived_timestamp);
1882 
1883  values[3] = Int64GetDatum(archiver_stats->failed_count);
1884  if (*(archiver_stats->last_failed_wal) == '\0')
1885  nulls[4] = true;
1886  else
1887  values[4] = CStringGetTextDatum(archiver_stats->last_failed_wal);
1888 
1889  if (archiver_stats->last_failed_timestamp == 0)
1890  nulls[5] = true;
1891  else
1892  values[5] = TimestampTzGetDatum(archiver_stats->last_failed_timestamp);
1893 
1894  if (archiver_stats->stat_reset_timestamp == 0)
1895  nulls[6] = true;
1896  else
1897  values[6] = TimestampTzGetDatum(archiver_stats->stat_reset_timestamp);
1898 
1899  /* Returns the record as Datum */
1901 }
1902 
1903 /*
1904  * Get the statistics for the replication slot. If the slot statistics is not
1905  * available, return all-zeroes stats.
1906  */
1907 Datum
1909 {
1910 #define PG_STAT_GET_REPLICATION_SLOT_COLS 10
1911  text *slotname_text = PG_GETARG_TEXT_P(0);
1912  NameData slotname;
1913  TupleDesc tupdesc;
1915  bool nulls[PG_STAT_GET_REPLICATION_SLOT_COLS] = {0};
1916  PgStat_StatReplSlotEntry *slotent;
1917  PgStat_StatReplSlotEntry allzero;
1918 
1919  /* Initialise attributes information in the tuple descriptor */
1921  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "slot_name",
1922  TEXTOID, -1, 0);
1923  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "spill_txns",
1924  INT8OID, -1, 0);
1925  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "spill_count",
1926  INT8OID, -1, 0);
1927  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "spill_bytes",
1928  INT8OID, -1, 0);
1929  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "stream_txns",
1930  INT8OID, -1, 0);
1931  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "stream_count",
1932  INT8OID, -1, 0);
1933  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stream_bytes",
1934  INT8OID, -1, 0);
1935  TupleDescInitEntry(tupdesc, (AttrNumber) 8, "total_txns",
1936  INT8OID, -1, 0);
1937  TupleDescInitEntry(tupdesc, (AttrNumber) 9, "total_bytes",
1938  INT8OID, -1, 0);
1939  TupleDescInitEntry(tupdesc, (AttrNumber) 10, "stats_reset",
1940  TIMESTAMPTZOID, -1, 0);
1941  BlessTupleDesc(tupdesc);
1942 
1943  namestrcpy(&slotname, text_to_cstring(slotname_text));
1944  slotent = pgstat_fetch_replslot(slotname);
1945  if (!slotent)
1946  {
1947  /*
1948  * If the slot is not found, initialise its stats. This is possible if
1949  * the create slot message is lost.
1950  */
1951  memset(&allzero, 0, sizeof(PgStat_StatReplSlotEntry));
1952  slotent = &allzero;
1953  }
1954 
1955  values[0] = CStringGetTextDatum(NameStr(slotname));
1956  values[1] = Int64GetDatum(slotent->spill_txns);
1957  values[2] = Int64GetDatum(slotent->spill_count);
1958  values[3] = Int64GetDatum(slotent->spill_bytes);
1959  values[4] = Int64GetDatum(slotent->stream_txns);
1960  values[5] = Int64GetDatum(slotent->stream_count);
1961  values[6] = Int64GetDatum(slotent->stream_bytes);
1962  values[7] = Int64GetDatum(slotent->total_txns);
1963  values[8] = Int64GetDatum(slotent->total_bytes);
1964 
1965  if (slotent->stat_reset_timestamp == 0)
1966  nulls[9] = true;
1967  else
1969 
1970  /* Returns the record as Datum */
1972 }
1973 
1974 /*
1975  * Get the subscription statistics for the given subscription. If the
1976  * subscription statistics is not available, return all-zeros stats.
1977  */
1978 Datum
1980 {
1981 #define PG_STAT_GET_SUBSCRIPTION_STATS_COLS 10
1982  Oid subid = PG_GETARG_OID(0);
1983  TupleDesc tupdesc;
1985  bool nulls[PG_STAT_GET_SUBSCRIPTION_STATS_COLS] = {0};
1986  PgStat_StatSubEntry *subentry;
1987  PgStat_StatSubEntry allzero;
1988  int i = 0;
1989 
1990  /* Get subscription stats */
1991  subentry = pgstat_fetch_stat_subscription(subid);
1992 
1993  /* Initialise attributes information in the tuple descriptor */
1995  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subid",
1996  OIDOID, -1, 0);
1997  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "apply_error_count",
1998  INT8OID, -1, 0);
1999  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "sync_error_count",
2000  INT8OID, -1, 0);
2001  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "confl_insert_exists",
2002  INT8OID, -1, 0);
2003  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "confl_update_origin_differs",
2004  INT8OID, -1, 0);
2005  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "confl_update_exists",
2006  INT8OID, -1, 0);
2007  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "confl_update_missing",
2008  INT8OID, -1, 0);
2009  TupleDescInitEntry(tupdesc, (AttrNumber) 8, "confl_delete_origin_differs",
2010  INT8OID, -1, 0);
2011  TupleDescInitEntry(tupdesc, (AttrNumber) 9, "confl_delete_missing",
2012  INT8OID, -1, 0);
2013  TupleDescInitEntry(tupdesc, (AttrNumber) 10, "stats_reset",
2014  TIMESTAMPTZOID, -1, 0);
2015  BlessTupleDesc(tupdesc);
2016 
2017  if (!subentry)
2018  {
2019  /* If the subscription is not found, initialise its stats */
2020  memset(&allzero, 0, sizeof(PgStat_StatSubEntry));
2021  subentry = &allzero;
2022  }
2023 
2024  /* subid */
2025  values[i++] = ObjectIdGetDatum(subid);
2026 
2027  /* apply_error_count */
2028  values[i++] = Int64GetDatum(subentry->apply_error_count);
2029 
2030  /* sync_error_count */
2031  values[i++] = Int64GetDatum(subentry->sync_error_count);
2032 
2033  /* conflict count */
2034  for (int nconflict = 0; nconflict < CONFLICT_NUM_TYPES; nconflict++)
2035  values[i++] = Int64GetDatum(subentry->conflict_count[nconflict]);
2036 
2037  /* stats_reset */
2038  if (subentry->stat_reset_timestamp == 0)
2039  nulls[i] = true;
2040  else
2042 
2044 
2045  /* Returns the record as Datum */
2047 }
2048 
2049 /*
2050  * Checks for presence of stats for object with provided kind, database oid,
2051  * object oid.
2052  *
2053  * This is useful for tests, but not really anything else. Therefore not
2054  * documented.
2055  */
2056 Datum
2058 {
2059  char *stats_type = text_to_cstring(PG_GETARG_TEXT_P(0));
2060  Oid dboid = PG_GETARG_OID(1);
2061  uint64 objid = PG_GETARG_INT64(2);
2062  PgStat_Kind kind = pgstat_get_kind_from_str(stats_type);
2063 
2064  PG_RETURN_BOOL(pgstat_have_entry(kind, dboid, objid));
2065 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
int16 AttrNumber
Definition: attnum.h:21
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:636
#define PGSTAT_NUM_PROGRESS_PARAM
ProgressCommandType
@ PROGRESS_COMMAND_ANALYZE
@ PROGRESS_COMMAND_CLUSTER
@ PROGRESS_COMMAND_CREATE_INDEX
@ PROGRESS_COMMAND_VACUUM
@ PROGRESS_COMMAND_BASEBACKUP
@ PROGRESS_COMMAND_COPY
int pgstat_fetch_stat_numbackends(void)
PgBackendStatus * pgstat_get_beentry_by_proc_number(ProcNumber procNumber)
LocalPgBackendStatus * pgstat_get_local_beentry_by_index(int idx)
LocalPgBackendStatus * pgstat_get_local_beentry_by_proc_number(ProcNumber procNumber)
char * pgstat_clip_activity(const char *raw_activity)
@ STATE_UNDEFINED
@ STATE_IDLEINTRANSACTION_ABORTED
@ STATE_IDLE
@ STATE_IDLEINTRANSACTION
@ STATE_DISABLED
@ STATE_FASTPATH
@ STATE_RUNNING
const char * GetBackgroundWorkerTypeByPid(pid_t pid)
Definition: bgworker.c:1371
static Datum values[MAXATTR]
Definition: bootstrap.c:150
#define CStringGetTextDatum(s)
Definition: builtins.h:97
#define NameStr(name)
Definition: c.h:737
unsigned int uint32
Definition: c.h:506
signed int int32
Definition: c.h:496
#define Assert(condition)
Definition: c.h:849
#define UINT64_FORMAT
Definition: c.h:540
#define pg_unreachable()
Definition: c.h:299
#define OidIsValid(objectId)
Definition: c.h:766
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:273
#define CONFLICT_NUM_TYPES
Definition: conflict.h:51
int64 TimestampTz
Definition: timestamp.h:39
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2158
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1807
Datum Float8GetDatum(float8 X)
Definition: fmgr.c:1816
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_INT64(x)
Definition: fmgr.h:368
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:641
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:645
#define PG_RETURN_OID(x)
Definition: fmgr.h:360
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:336
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:46
Oid MyDatabaseId
Definition: globals.c:93
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1116
Datum int4in(PG_FUNCTION_ARGS)
Definition: int.c:287
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:114
int i
Definition: isn.c:73
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
pid_t GetLeaderApplyWorkerPid(pid_t pid)
Definition: launcher.c:1259
void pfree(void *pointer)
Definition: mcxt.c:1521
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1181
#define BACKEND_NUM_TYPES
Definition: miscadmin.h:367
@ B_WAL_SENDER
Definition: miscadmin.h:339
@ B_BG_WORKER
Definition: miscadmin.h:338
@ B_BACKEND
Definition: miscadmin.h:335
#define InvalidPid
Definition: miscadmin.h:32
const char * GetBackendTypeDesc(BackendType backendType)
Definition: miscinit.c:263
void namestrcpy(Name name, const char *str)
Definition: name.c:233
void clean_ipv6_addr(int addr_family, char *addr)
Definition: network.c:2089
Datum inet_in(PG_FUNCTION_ARGS)
Definition: network.c:121
static char * buf
Definition: pg_test_fsync.c:73
void pgstat_reset(PgStat_Kind kind, Oid dboid, uint64 objid)
Definition: pgstat.c:848
void pgstat_reset_counters(void)
Definition: pgstat.c:829
void pgstat_reset_of_kind(PgStat_Kind kind)
Definition: pgstat.c:870
void pgstat_force_next_flush(void)
Definition: pgstat.c:808
void pgstat_clear_snapshot(void)
Definition: pgstat.c:896
TimestampTz pgstat_get_stat_snapshot_timestamp(bool *have_snapshot)
Definition: pgstat.c:1021
bool pgstat_have_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
Definition: pgstat.c:1038
PgStat_Kind pgstat_get_kind_from_str(char *kind_str)
Definition: pgstat.c:1396
#define PGSTAT_KIND_ARCHIVER
Definition: pgstat.h:54
#define PGSTAT_KIND_WAL
Definition: pgstat.h:59
#define PgStat_Kind
Definition: pgstat.h:37
#define IOOP_NUM_TYPES
Definition: pgstat.h:342
#define IOCONTEXT_NUM_TYPES
Definition: pgstat.h:328
#define PGSTAT_KIND_BGWRITER
Definition: pgstat.h:55
#define PGSTAT_KIND_REPLSLOT
Definition: pgstat.h:50
#define PGSTAT_KIND_FUNCTION
Definition: pgstat.h:49
IOOp
Definition: pgstat.h:331
@ IOOP_EXTEND
Definition: pgstat.h:333
@ IOOP_FSYNC
Definition: pgstat.h:334
@ IOOP_READ
Definition: pgstat.h:336
@ IOOP_WRITEBACK
Definition: pgstat.h:339
@ IOOP_HIT
Definition: pgstat.h:335
@ IOOP_EVICT
Definition: pgstat.h:332
@ IOOP_REUSE
Definition: pgstat.h:337
@ IOOP_WRITE
Definition: pgstat.h:338
#define PGSTAT_KIND_SLRU
Definition: pgstat.h:58
#define PGSTAT_KIND_RELATION
Definition: pgstat.h:48
#define PGSTAT_KIND_CHECKPOINTER
Definition: pgstat.h:56
#define PGSTAT_KIND_IO
Definition: pgstat.h:57
#define PGSTAT_KIND_SUBSCRIPTION
Definition: pgstat.h:51
int64 PgStat_Counter
Definition: pgstat.h:120
#define IOOBJECT_NUM_TYPES
Definition: pgstat.h:318
PgStat_ArchiverStats * pgstat_fetch_stat_archiver(void)
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)
bool pgstat_tracks_io_bktype(BackendType bktype)
Definition: pgstat_io.c:346
const char * pgstat_get_io_object_name(IOObject io_object)
Definition: pgstat_io.c:258
bool pgstat_bktype_io_stats_valid(PgStat_BktypeIO *backend_io, BackendType bktype)
Definition: pgstat_io.c:46
PgStat_IO * pgstat_fetch_stat_io(void)
Definition: pgstat_io.c:157
bool pgstat_tracks_io_op(BackendType bktype, IOObject io_object, IOContext io_context, IOOp io_op)
Definition: pgstat_io.c:451
const char * pgstat_get_io_context_name(IOContext io_context)
Definition: pgstat_io.c:239
bool pgstat_tracks_io_object(BackendType bktype, IOObject io_object, IOContext io_context)
Definition: pgstat_io.c:386
void pgstat_reset_replslot(const char *name)
PgStat_StatReplSlotEntry * pgstat_fetch_replslot(NameData slotname)
void pgstat_reset_slru(const char *name)
Definition: pgstat_slru.c:45
PgStat_SLRUStats * pgstat_fetch_slru(void)
Definition: pgstat_slru.c:105
const char * pgstat_get_slru_name(int slru_idx)
Definition: pgstat_slru.c:118
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)
Definition: pgstatfuncs.c:1588
Datum pg_stat_get_progress_info(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:227
Datum pg_stat_get_checkpointer_num_requested(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1189
Datum pg_stat_get_snapshot_timestamp(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1665
Datum pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:879
Datum pg_stat_get_db_stat_reset_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1073
#define PG_STAT_GET_WAL_COLS
Datum pg_stat_get_wal(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1481
Datum pg_stat_reset_replication_slot(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1801
Datum pg_stat_get_checkpointer_num_timed(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1183
#define UINT32_ACCESS_ONCE(var)
Definition: pgstatfuncs.c:35
Datum pg_stat_get_activity(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:303
Datum pg_stat_get_slru(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1545
Datum pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:924
Datum pg_stat_get_backend_start(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:857
Datum pg_stat_get_db_conflict_all(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1092
Datum pg_stat_get_subscription_stats(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1979
#define PG_STAT_GET_SLRU_COLS
#define PG_STAT_GET_DBENTRY_INT64(stat)
Definition: pgstatfuncs.c:990
Datum pg_stat_get_checkpointer_buffers_written(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1219
Datum pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:668
Datum pg_stat_get_checkpointer_sync_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1251
static double pg_stat_us_to_ms(PgStat_Counter val_ms)
Definition: pgstatfuncs.c:1363
#define PG_STAT_GET_ACTIVITY_COLS
static io_stat_col pgstat_get_io_time_index(IOOp io_op)
Definition: pgstatfuncs.c:1342
Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:741
#define PG_STAT_GET_FUNCENTRY_FLOAT8_MS(stat)
Definition: pgstatfuncs.c:155
Datum pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:970
Datum pg_stat_get_db_checksum_failures(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1112
Datum pg_stat_reset_subscription_stats(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1818
Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1680
Datum pg_stat_reset_slru(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1784
Datum pg_stat_get_checkpointer_restartpoints_requested(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1207
Datum pg_stat_get_checkpointer_num_performed(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1195
Datum pg_stat_get_db_checksum_last_failure(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1130
static io_stat_col pgstat_get_io_op_index(IOOp io_op)
Definition: pgstatfuncs.c:1309
Datum pg_stat_have_stats(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:2057
Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:176
Datum pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:766
#define PG_STAT_GET_SUBSCRIPTION_STATS_COLS
Datum pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1237
Datum pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1231
Datum pg_stat_get_io(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1369
Datum pg_stat_get_checkpointer_restartpoints_performed(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1213
#define PG_STAT_GET_DBENTRY_FLOAT8_MS(stat)
Definition: pgstatfuncs.c:1151
Datum pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:694
Datum pg_stat_reset(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1700
Datum pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:787
#define PG_STAT_GET_SUBXACT_COLS
#define PG_STAT_GET_XACT_FUNCENTRY_FLOAT8_MS(stat)
Definition: pgstatfuncs.c:1645
#define PG_STAT_GET_RELENTRY_INT64(stat)
Definition: pgstatfuncs.c:39
Datum pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:681
Datum pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1635
#define PG_STAT_GET_RELENTRY_TIMESTAMPTZ(stat)
Definition: pgstatfuncs.c:109
#define PG_STAT_GET_PROGRESS_COLS
Datum pg_stat_get_checkpointer_write_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1243
#define HAS_PGSTAT_PERMISSIONS(role)
Definition: pgstatfuncs.c:37
Datum pg_stat_get_checkpointer_slru_written(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1225
Datum pg_stat_get_archiver(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1842
Datum pg_stat_get_checkpointer_restartpoints_timed(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1201
Datum pg_stat_reset_shared(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1714
Datum pg_stat_force_next_flush(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1690
Datum pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1762
Datum pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1265
Datum pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:835
Datum pg_stat_get_checkpointer_stat_reset_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1259
Datum pg_stat_get_function_calls(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:144
Datum pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:706
Datum pg_stat_get_replication_slot(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1908
io_stat_col
Definition: pgstatfuncs.c:1281
@ IO_COL_READS
Definition: pgstatfuncs.c:1286
@ IO_NUM_COLUMNS
Definition: pgstatfuncs.c:1301
@ IO_COL_RESET_TIME
Definition: pgstatfuncs.c:1300
@ IO_COL_WRITE_TIME
Definition: pgstatfuncs.c:1289
@ IO_COL_HITS
Definition: pgstatfuncs.c:1295
@ IO_COL_EXTENDS
Definition: pgstatfuncs.c:1292
@ IO_COL_WRITEBACK_TIME
Definition: pgstatfuncs.c:1291
@ IO_COL_REUSES
Definition: pgstatfuncs.c:1297
@ IO_COL_WRITES
Definition: pgstatfuncs.c:1288
@ IO_COL_OBJECT
Definition: pgstatfuncs.c:1284
@ IO_COL_EVICTIONS
Definition: pgstatfuncs.c:1296
@ IO_COL_CONVERSION
Definition: pgstatfuncs.c:1294
@ IO_COL_WRITEBACKS
Definition: pgstatfuncs.c:1290
@ IO_COL_CONTEXT
Definition: pgstatfuncs.c:1285
@ IO_COL_BACKEND_TYPE
Definition: pgstatfuncs.c:1283
@ IO_COL_FSYNC_TIME
Definition: pgstatfuncs.c:1299
@ IO_COL_EXTEND_TIME
Definition: pgstatfuncs.c:1293
@ IO_COL_FSYNCS
Definition: pgstatfuncs.c:1298
@ IO_COL_INVALID
Definition: pgstatfuncs.c:1282
@ IO_COL_READ_TIME
Definition: pgstatfuncs.c:1287
Datum pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:809
Datum pg_stat_reset_single_function_counters(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1773
Datum pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1271
Datum pg_backend_pid(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:661
#define PG_STAT_GET_REPLICATION_SLOT_COLS
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define snprintf
Definition: port.h:238
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static Datum TransactionIdGetDatum(TransactionId X)
Definition: postgres.h:272
uintptr_t Datum
Definition: postgres.h:64
static Datum UInt64GetDatum(uint64 X)
Definition: postgres.h:436
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
PGPROC * BackendPidGetProc(int pid)
Definition: procarray.c:3200
PGPROC * AuxiliaryPidGetProc(int pid)
Definition: proc.c:1058
void * user_fctx
Definition: funcapi.h:82
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
TransactionId backend_xid
PgBackendStatus backendStatus
TransactionId backend_xmin
Definition: proc.h:162
uint32 wait_event_info
Definition: proc.h:279
int pid
Definition: proc.h:182
PGPROC * lockGroupLeader
Definition: proc.h:304
char gss_princ[NAMEDATALEN]
char ssl_version[NAMEDATALEN]
char ssl_cipher[NAMEDATALEN]
char ssl_client_dn[NAMEDATALEN]
char ssl_client_serial[NAMEDATALEN]
char ssl_issuer_dn[NAMEDATALEN]
BackendType st_backendType
TimestampTz st_state_start_timestamp
TimestampTz st_proc_start_timestamp
PgBackendGSSStatus * st_gssstatus
BackendState st_state
TimestampTz st_activity_start_timestamp
ProgressCommandType st_progress_command
SockAddr st_clientaddr
int64 st_progress_param[PGSTAT_NUM_PROGRESS_PARAM]
PgBackendSSLStatus * st_sslstatus
TimestampTz st_xact_start_timestamp
char * st_clienthostname
Oid st_progress_command_target
TimestampTz last_failed_timestamp
Definition: pgstat.h:281
TimestampTz stat_reset_timestamp
Definition: pgstat.h:282
TimestampTz last_archived_timestamp
Definition: pgstat.h:277
char last_failed_wal[MAX_XFN_CHARS+1]
Definition: pgstat.h:279
PgStat_Counter failed_count
Definition: pgstat.h:278
PgStat_Counter archived_count
Definition: pgstat.h:274
char last_archived_wal[MAX_XFN_CHARS+1]
Definition: pgstat.h:275
PgStat_Counter times[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition: pgstat.h:347
PgStat_Counter counts[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition: pgstat.h:346
PgStat_Counter numcalls
Definition: pgstat.h:140
PgStat_BktypeIO stats[BACKEND_NUM_TYPES]
Definition: pgstat.h:353
TimestampTz stat_reset_timestamp
Definition: pgstat.h:352
PgStat_Counter conflict_startup_deadlock
Definition: pgstat.h:374
PgStat_Counter conflict_lock
Definition: pgstat.h:370
TimestampTz stat_reset_timestamp
Definition: pgstat.h:390
PgStat_Counter conflict_snapshot
Definition: pgstat.h:371
TimestampTz last_checksum_failure
Definition: pgstat.h:379
PgStat_Counter conflict_bufferpin
Definition: pgstat.h:373
PgStat_Counter conflict_logicalslot
Definition: pgstat.h:372
PgStat_Counter checksum_failures
Definition: pgstat.h:378
PgStat_Counter conflict_tablespace
Definition: pgstat.h:369
PgStat_Counter numcalls
Definition: pgstat.h:395
TimestampTz stat_reset_timestamp
Definition: pgstat.h:411
PgStat_Counter stream_count
Definition: pgstat.h:407
PgStat_Counter total_txns
Definition: pgstat.h:409
PgStat_Counter total_bytes
Definition: pgstat.h:410
PgStat_Counter spill_txns
Definition: pgstat.h:403
PgStat_Counter stream_txns
Definition: pgstat.h:406
PgStat_Counter spill_count
Definition: pgstat.h:404
PgStat_Counter stream_bytes
Definition: pgstat.h:408
PgStat_Counter spill_bytes
Definition: pgstat.h:405
PgStat_Counter apply_error_count
Definition: pgstat.h:428
PgStat_Counter sync_error_count
Definition: pgstat.h:429
PgStat_Counter conflict_count[CONFLICT_NUM_TYPES]
Definition: pgstat.h:430
TimestampTz stat_reset_timestamp
Definition: pgstat.h:431
PgStat_Counter wal_write
Definition: pgstat.h:472
PgStat_Counter wal_buffers_full
Definition: pgstat.h:471
PgStat_Counter wal_write_time
Definition: pgstat.h:474
TimestampTz stat_reset_timestamp
Definition: pgstat.h:476
uint64 wal_bytes
Definition: pgstat.h:470
PgStat_Counter wal_sync_time
Definition: pgstat.h:475
PgStat_Counter wal_fpi
Definition: pgstat.h:469
PgStat_Counter wal_sync
Definition: pgstat.h:473
PgStat_Counter wal_records
Definition: pgstat.h:468
TupleDesc setDesc
Definition: execnodes.h:343
Tuplestorestate * setResult
Definition: execnodes.h:342
struct sockaddr_storage addr
Definition: pqcomm.h:32
socklen_t salen
Definition: pqcomm.h:33
Definition: c.h:732
Definition: c.h:678
#define TransactionIdIsValid(xid)
Definition: transam.h:41
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:67
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:651
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition: tuplestore.c:784
static Datum TimestampTzGetDatum(TimestampTz X)
Definition: timestamp.h:52
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:68
char * text_to_cstring(const text *t)
Definition: varlena.c:217
text * cstring_to_text(const char *s)
Definition: varlena.c:184
const char * pgstat_get_wait_event(uint32 wait_event_info)
Definition: wait_event.c:432
const char * pgstat_get_wait_event_type(uint32 wait_event_info)
Definition: wait_event.c:374
const char * name
#define stat
Definition: win32_port.h:284
bool DataChecksumsEnabled(void)
Definition: xlog.c:4581
void XLogPrefetchResetStats(void)