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 {
1197  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->restartpoints_timed);
1198 }
1199 
1200 Datum
1202 {
1203  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->restartpoints_requested);
1204 }
1205 
1206 Datum
1208 {
1209  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->restartpoints_performed);
1210 }
1211 
1212 Datum
1214 {
1215  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->buffers_written);
1216 }
1217 
1218 Datum
1220 {
1221  PG_RETURN_INT64(pgstat_fetch_stat_bgwriter()->buf_written_clean);
1222 }
1223 
1224 Datum
1226 {
1227  PG_RETURN_INT64(pgstat_fetch_stat_bgwriter()->maxwritten_clean);
1228 }
1229 
1230 Datum
1232 {
1233  /* time is already in msec, just convert to double for presentation */
1234  PG_RETURN_FLOAT8((double)
1235  pgstat_fetch_stat_checkpointer()->write_time);
1236 }
1237 
1238 Datum
1240 {
1241  /* time is already in msec, just convert to double for presentation */
1242  PG_RETURN_FLOAT8((double)
1243  pgstat_fetch_stat_checkpointer()->sync_time);
1244 }
1245 
1246 Datum
1248 {
1249  PG_RETURN_TIMESTAMPTZ(pgstat_fetch_stat_checkpointer()->stat_reset_timestamp);
1250 }
1251 
1252 Datum
1254 {
1255  PG_RETURN_TIMESTAMPTZ(pgstat_fetch_stat_bgwriter()->stat_reset_timestamp);
1256 }
1257 
1258 Datum
1260 {
1262 }
1263 
1264 /*
1265 * When adding a new column to the pg_stat_io view, add a new enum value
1266 * here above IO_NUM_COLUMNS.
1267 */
1268 typedef enum io_stat_col
1269 {
1291 
1292 /*
1293  * When adding a new IOOp, add a new io_stat_col and add a case to this
1294  * function returning the corresponding io_stat_col.
1295  */
1296 static io_stat_col
1298 {
1299  switch (io_op)
1300  {
1301  case IOOP_EVICT:
1302  return IO_COL_EVICTIONS;
1303  case IOOP_EXTEND:
1304  return IO_COL_EXTENDS;
1305  case IOOP_FSYNC:
1306  return IO_COL_FSYNCS;
1307  case IOOP_HIT:
1308  return IO_COL_HITS;
1309  case IOOP_READ:
1310  return IO_COL_READS;
1311  case IOOP_REUSE:
1312  return IO_COL_REUSES;
1313  case IOOP_WRITE:
1314  return IO_COL_WRITES;
1315  case IOOP_WRITEBACK:
1316  return IO_COL_WRITEBACKS;
1317  }
1318 
1319  elog(ERROR, "unrecognized IOOp value: %d", io_op);
1320  pg_unreachable();
1321 }
1322 
1323 /*
1324  * Get the number of the column containing IO times for the specified IOOp.
1325  * This function encodes our assumption that IO time for an IOOp is displayed
1326  * in the view in the column directly after the IOOp counts. If an op has no
1327  * associated time, IO_COL_INVALID is returned.
1328  */
1329 static io_stat_col
1331 {
1332  switch (io_op)
1333  {
1334  case IOOP_READ:
1335  case IOOP_WRITE:
1336  case IOOP_WRITEBACK:
1337  case IOOP_EXTEND:
1338  case IOOP_FSYNC:
1339  return pgstat_get_io_op_index(io_op) + 1;
1340  case IOOP_EVICT:
1341  case IOOP_HIT:
1342  case IOOP_REUSE:
1343  return IO_COL_INVALID;
1344  }
1345 
1346  elog(ERROR, "unrecognized IOOp value: %d", io_op);
1347  pg_unreachable();
1348 }
1349 
1350 static inline double
1352 {
1353  return val_ms * (double) 0.001;
1354 }
1355 
1356 Datum
1358 {
1359  ReturnSetInfo *rsinfo;
1360  PgStat_IO *backends_io_stats;
1361  Datum reset_time;
1362 
1363  InitMaterializedSRF(fcinfo, 0);
1364  rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1365 
1366  backends_io_stats = pgstat_fetch_stat_io();
1367 
1368  reset_time = TimestampTzGetDatum(backends_io_stats->stat_reset_timestamp);
1369 
1370  for (int bktype = 0; bktype < BACKEND_NUM_TYPES; bktype++)
1371  {
1372  Datum bktype_desc = CStringGetTextDatum(GetBackendTypeDesc(bktype));
1373  PgStat_BktypeIO *bktype_stats = &backends_io_stats->stats[bktype];
1374 
1375  /*
1376  * In Assert builds, we can afford an extra loop through all of the
1377  * counters checking that only expected stats are non-zero, since it
1378  * keeps the non-Assert code cleaner.
1379  */
1380  Assert(pgstat_bktype_io_stats_valid(bktype_stats, bktype));
1381 
1382  /*
1383  * For those BackendTypes without IO Operation stats, skip
1384  * representing them in the view altogether.
1385  */
1386  if (!pgstat_tracks_io_bktype(bktype))
1387  continue;
1388 
1389  for (int io_obj = 0; io_obj < IOOBJECT_NUM_TYPES; io_obj++)
1390  {
1391  const char *obj_name = pgstat_get_io_object_name(io_obj);
1392 
1393  for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++)
1394  {
1395  const char *context_name = pgstat_get_io_context_name(io_context);
1396 
1397  Datum values[IO_NUM_COLUMNS] = {0};
1398  bool nulls[IO_NUM_COLUMNS] = {0};
1399 
1400  /*
1401  * Some combinations of BackendType, IOObject, and IOContext
1402  * are not valid for any type of IOOp. In such cases, omit the
1403  * entire row from the view.
1404  */
1405  if (!pgstat_tracks_io_object(bktype, io_obj, io_context))
1406  continue;
1407 
1408  values[IO_COL_BACKEND_TYPE] = bktype_desc;
1409  values[IO_COL_CONTEXT] = CStringGetTextDatum(context_name);
1412 
1413  /*
1414  * Hard-code this to the value of BLCKSZ for now. Future
1415  * values could include XLOG_BLCKSZ, once WAL IO is tracked,
1416  * and constant multipliers, once non-block-oriented IO (e.g.
1417  * temporary file IO) is tracked.
1418  */
1420 
1421  for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
1422  {
1423  int op_idx = pgstat_get_io_op_index(io_op);
1424  int time_idx = pgstat_get_io_time_index(io_op);
1425 
1426  /*
1427  * Some combinations of BackendType and IOOp, of IOContext
1428  * and IOOp, and of IOObject and IOOp are not tracked. Set
1429  * these cells in the view NULL.
1430  */
1431  if (pgstat_tracks_io_op(bktype, io_obj, io_context, io_op))
1432  {
1433  PgStat_Counter count =
1434  bktype_stats->counts[io_obj][io_context][io_op];
1435 
1436  values[op_idx] = Int64GetDatum(count);
1437  }
1438  else
1439  nulls[op_idx] = true;
1440 
1441  /* not every operation is timed */
1442  if (time_idx == IO_COL_INVALID)
1443  continue;
1444 
1445  if (!nulls[op_idx])
1446  {
1447  PgStat_Counter time =
1448  bktype_stats->times[io_obj][io_context][io_op];
1449 
1450  values[time_idx] = Float8GetDatum(pg_stat_us_to_ms(time));
1451  }
1452  else
1453  nulls[time_idx] = true;
1454  }
1455 
1456  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
1457  values, nulls);
1458  }
1459  }
1460  }
1461 
1462  return (Datum) 0;
1463 }
1464 
1465 /*
1466  * Returns statistics of WAL activity
1467  */
1468 Datum
1470 {
1471 #define PG_STAT_GET_WAL_COLS 9
1472  TupleDesc tupdesc;
1474  bool nulls[PG_STAT_GET_WAL_COLS] = {0};
1475  char buf[256];
1476  PgStat_WalStats *wal_stats;
1477 
1478  /* Initialise attributes information in the tuple descriptor */
1480  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "wal_records",
1481  INT8OID, -1, 0);
1482  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "wal_fpi",
1483  INT8OID, -1, 0);
1484  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "wal_bytes",
1485  NUMERICOID, -1, 0);
1486  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_buffers_full",
1487  INT8OID, -1, 0);
1488  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "wal_write",
1489  INT8OID, -1, 0);
1490  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "wal_sync",
1491  INT8OID, -1, 0);
1492  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "wal_write_time",
1493  FLOAT8OID, -1, 0);
1494  TupleDescInitEntry(tupdesc, (AttrNumber) 8, "wal_sync_time",
1495  FLOAT8OID, -1, 0);
1496  TupleDescInitEntry(tupdesc, (AttrNumber) 9, "stats_reset",
1497  TIMESTAMPTZOID, -1, 0);
1498 
1499  BlessTupleDesc(tupdesc);
1500 
1501  /* Get statistics about WAL activity */
1502  wal_stats = pgstat_fetch_stat_wal();
1503 
1504  /* Fill values and NULLs */
1505  values[0] = Int64GetDatum(wal_stats->wal_records);
1506  values[1] = Int64GetDatum(wal_stats->wal_fpi);
1507 
1508  /* Convert to numeric. */
1509  snprintf(buf, sizeof buf, UINT64_FORMAT, wal_stats->wal_bytes);
1512  ObjectIdGetDatum(0),
1513  Int32GetDatum(-1));
1514 
1515  values[3] = Int64GetDatum(wal_stats->wal_buffers_full);
1516  values[4] = Int64GetDatum(wal_stats->wal_write);
1517  values[5] = Int64GetDatum(wal_stats->wal_sync);
1518 
1519  /* Convert counters from microsec to millisec for display */
1520  values[6] = Float8GetDatum(((double) wal_stats->wal_write_time) / 1000.0);
1521  values[7] = Float8GetDatum(((double) wal_stats->wal_sync_time) / 1000.0);
1522 
1524 
1525  /* Returns the record as Datum */
1527 }
1528 
1529 /*
1530  * Returns statistics of SLRU caches.
1531  */
1532 Datum
1534 {
1535 #define PG_STAT_GET_SLRU_COLS 9
1536  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1537  int i;
1538  PgStat_SLRUStats *stats;
1539 
1540  InitMaterializedSRF(fcinfo, 0);
1541 
1542  /* request SLRU stats from the cumulative stats system */
1543  stats = pgstat_fetch_slru();
1544 
1545  for (i = 0;; i++)
1546  {
1547  /* for each row */
1549  bool nulls[PG_STAT_GET_SLRU_COLS] = {0};
1551  const char *name;
1552 
1554 
1555  if (!name)
1556  break;
1557 
1558  stat = stats[i];
1559 
1561  values[1] = Int64GetDatum(stat.blocks_zeroed);
1562  values[2] = Int64GetDatum(stat.blocks_hit);
1563  values[3] = Int64GetDatum(stat.blocks_read);
1564  values[4] = Int64GetDatum(stat.blocks_written);
1565  values[5] = Int64GetDatum(stat.blocks_exists);
1566  values[6] = Int64GetDatum(stat.flush);
1567  values[7] = Int64GetDatum(stat.truncate);
1568  values[8] = TimestampTzGetDatum(stat.stat_reset_timestamp);
1569 
1570  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
1571  }
1572 
1573  return (Datum) 0;
1574 }
1575 
1576 #define PG_STAT_GET_XACT_RELENTRY_INT64(stat) \
1577 Datum \
1578 CppConcat(pg_stat_get_xact_,stat)(PG_FUNCTION_ARGS) \
1579 { \
1580  Oid relid = PG_GETARG_OID(0); \
1581  int64 result; \
1582  PgStat_TableStatus *tabentry; \
1583  \
1584  if ((tabentry = find_tabstat_entry(relid)) == NULL) \
1585  result = 0; \
1586  else \
1587  result = (int64) (tabentry->counts.stat); \
1588  \
1589  PG_RETURN_INT64(result); \
1590 }
1591 
1592 /* pg_stat_get_xact_numscans */
1594 
1595 /* pg_stat_get_xact_tuples_returned */
1596 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_returned)
1597 
1598 /* pg_stat_get_xact_tuples_fetched */
1599 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_fetched)
1600 
1601 /* pg_stat_get_xact_tuples_hot_updated */
1602 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_hot_updated)
1603 
1604 /* pg_stat_get_xact_tuples_newpage_updated */
1605 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_newpage_updated)
1606 
1607 /* pg_stat_get_xact_blocks_fetched */
1608 PG_STAT_GET_XACT_RELENTRY_INT64(blocks_fetched)
1609 
1610 /* pg_stat_get_xact_blocks_hit */
1612 
1613 /* pg_stat_get_xact_tuples_inserted */
1614 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_inserted)
1615 
1616 /* pg_stat_get_xact_tuples_updated */
1617 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_updated)
1618 
1619 /* pg_stat_get_xact_tuples_deleted */
1620 PG_STAT_GET_XACT_RELENTRY_INT64(tuples_deleted)
1621 
1622 Datum
1624 {
1625  Oid funcid = PG_GETARG_OID(0);
1626  PgStat_FunctionCounts *funcentry;
1627 
1628  if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1629  PG_RETURN_NULL();
1630  PG_RETURN_INT64(funcentry->numcalls);
1631 }
1632 
1633 #define PG_STAT_GET_XACT_FUNCENTRY_FLOAT8_MS(stat) \
1634 Datum \
1635 CppConcat(pg_stat_get_xact_function_,stat)(PG_FUNCTION_ARGS) \
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_FLOAT8(INSTR_TIME_GET_MILLISEC(funcentry->stat)); \
1643 }
1644 
1645 /* pg_stat_get_xact_function_total_time */
1647 
1648 /* pg_stat_get_xact_function_self_time */
1650 
1651 /* Get the timestamp of the current statistics snapshot */
1652 Datum
1654 {
1655  bool have_snapshot;
1656  TimestampTz ts;
1657 
1658  ts = pgstat_get_stat_snapshot_timestamp(&have_snapshot);
1659 
1660  if (!have_snapshot)
1661  PG_RETURN_NULL();
1662 
1664 }
1665 
1666 /* Discard the active statistics snapshot */
1667 Datum
1669 {
1671 
1672  PG_RETURN_VOID();
1673 }
1674 
1675 
1676 /* Force statistics to be reported at the next occasion */
1677 Datum
1679 {
1681 
1682  PG_RETURN_VOID();
1683 }
1684 
1685 
1686 /* Reset all counters for the current database */
1687 Datum
1689 {
1691 
1692  PG_RETURN_VOID();
1693 }
1694 
1695 /*
1696  * Reset some shared cluster-wide counters
1697  *
1698  * When adding a new reset target, ideally the name should match that in
1699  * pgstat_kind_infos, if relevant.
1700  */
1701 Datum
1703 {
1704  char *target = NULL;
1705 
1706  if (PG_ARGISNULL(0))
1707  {
1708  /* Reset all the statistics when nothing is specified */
1716 
1717  PG_RETURN_VOID();
1718  }
1719 
1720  target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1721 
1722  if (strcmp(target, "archiver") == 0)
1724  else if (strcmp(target, "bgwriter") == 0)
1726  else if (strcmp(target, "checkpointer") == 0)
1728  else if (strcmp(target, "io") == 0)
1730  else if (strcmp(target, "recovery_prefetch") == 0)
1732  else if (strcmp(target, "slru") == 0)
1734  else if (strcmp(target, "wal") == 0)
1736  else
1737  ereport(ERROR,
1738  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1739  errmsg("unrecognized reset target: \"%s\"", target),
1740  errhint("Target must be \"archiver\", \"bgwriter\", \"checkpointer\", \"io\", \"recovery_prefetch\", \"slru\", or \"wal\".")));
1741 
1742  PG_RETURN_VOID();
1743 }
1744 
1745 /*
1746  * Reset a statistics for a single object, which may be of current
1747  * database or shared across all databases in the cluster.
1748  */
1749 Datum
1751 {
1752  Oid taboid = PG_GETARG_OID(0);
1753  Oid dboid = (IsSharedRelation(taboid) ? InvalidOid : MyDatabaseId);
1754 
1755  pgstat_reset(PGSTAT_KIND_RELATION, dboid, taboid);
1756 
1757  PG_RETURN_VOID();
1758 }
1759 
1760 Datum
1762 {
1763  Oid funcoid = PG_GETARG_OID(0);
1764 
1766 
1767  PG_RETURN_VOID();
1768 }
1769 
1770 /* Reset SLRU counters (a specific one or all of them). */
1771 Datum
1773 {
1774  char *target = NULL;
1775 
1776  if (PG_ARGISNULL(0))
1778  else
1779  {
1780  target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1781  pgstat_reset_slru(target);
1782  }
1783 
1784  PG_RETURN_VOID();
1785 }
1786 
1787 /* Reset replication slots stats (a specific one or all of them). */
1788 Datum
1790 {
1791  char *target = NULL;
1792 
1793  if (PG_ARGISNULL(0))
1795  else
1796  {
1797  target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1798  pgstat_reset_replslot(target);
1799  }
1800 
1801  PG_RETURN_VOID();
1802 }
1803 
1804 /* Reset subscription stats (a specific one or all of them) */
1805 Datum
1807 {
1808  Oid subid;
1809 
1810  if (PG_ARGISNULL(0))
1811  {
1812  /* Clear all subscription stats */
1814  }
1815  else
1816  {
1817  subid = PG_GETARG_OID(0);
1818 
1819  if (!OidIsValid(subid))
1820  ereport(ERROR,
1821  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1822  errmsg("invalid subscription OID %u", subid)));
1824  }
1825 
1826  PG_RETURN_VOID();
1827 }
1828 
1829 Datum
1831 {
1832  TupleDesc tupdesc;
1833  Datum values[7] = {0};
1834  bool nulls[7] = {0};
1835  PgStat_ArchiverStats *archiver_stats;
1836 
1837  /* Initialise attributes information in the tuple descriptor */
1838  tupdesc = CreateTemplateTupleDesc(7);
1839  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
1840  INT8OID, -1, 0);
1841  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal",
1842  TEXTOID, -1, 0);
1843  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_archived_time",
1844  TIMESTAMPTZOID, -1, 0);
1845  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "failed_count",
1846  INT8OID, -1, 0);
1847  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_failed_wal",
1848  TEXTOID, -1, 0);
1849  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_failed_time",
1850  TIMESTAMPTZOID, -1, 0);
1851  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stats_reset",
1852  TIMESTAMPTZOID, -1, 0);
1853 
1854  BlessTupleDesc(tupdesc);
1855 
1856  /* Get statistics about the archiver process */
1857  archiver_stats = pgstat_fetch_stat_archiver();
1858 
1859  /* Fill values and NULLs */
1860  values[0] = Int64GetDatum(archiver_stats->archived_count);
1861  if (*(archiver_stats->last_archived_wal) == '\0')
1862  nulls[1] = true;
1863  else
1864  values[1] = CStringGetTextDatum(archiver_stats->last_archived_wal);
1865 
1866  if (archiver_stats->last_archived_timestamp == 0)
1867  nulls[2] = true;
1868  else
1869  values[2] = TimestampTzGetDatum(archiver_stats->last_archived_timestamp);
1870 
1871  values[3] = Int64GetDatum(archiver_stats->failed_count);
1872  if (*(archiver_stats->last_failed_wal) == '\0')
1873  nulls[4] = true;
1874  else
1875  values[4] = CStringGetTextDatum(archiver_stats->last_failed_wal);
1876 
1877  if (archiver_stats->last_failed_timestamp == 0)
1878  nulls[5] = true;
1879  else
1880  values[5] = TimestampTzGetDatum(archiver_stats->last_failed_timestamp);
1881 
1882  if (archiver_stats->stat_reset_timestamp == 0)
1883  nulls[6] = true;
1884  else
1885  values[6] = TimestampTzGetDatum(archiver_stats->stat_reset_timestamp);
1886 
1887  /* Returns the record as Datum */
1889 }
1890 
1891 /*
1892  * Get the statistics for the replication slot. If the slot statistics is not
1893  * available, return all-zeroes stats.
1894  */
1895 Datum
1897 {
1898 #define PG_STAT_GET_REPLICATION_SLOT_COLS 10
1899  text *slotname_text = PG_GETARG_TEXT_P(0);
1900  NameData slotname;
1901  TupleDesc tupdesc;
1903  bool nulls[PG_STAT_GET_REPLICATION_SLOT_COLS] = {0};
1904  PgStat_StatReplSlotEntry *slotent;
1905  PgStat_StatReplSlotEntry allzero;
1906 
1907  /* Initialise attributes information in the tuple descriptor */
1909  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "slot_name",
1910  TEXTOID, -1, 0);
1911  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "spill_txns",
1912  INT8OID, -1, 0);
1913  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "spill_count",
1914  INT8OID, -1, 0);
1915  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "spill_bytes",
1916  INT8OID, -1, 0);
1917  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "stream_txns",
1918  INT8OID, -1, 0);
1919  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "stream_count",
1920  INT8OID, -1, 0);
1921  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stream_bytes",
1922  INT8OID, -1, 0);
1923  TupleDescInitEntry(tupdesc, (AttrNumber) 8, "total_txns",
1924  INT8OID, -1, 0);
1925  TupleDescInitEntry(tupdesc, (AttrNumber) 9, "total_bytes",
1926  INT8OID, -1, 0);
1927  TupleDescInitEntry(tupdesc, (AttrNumber) 10, "stats_reset",
1928  TIMESTAMPTZOID, -1, 0);
1929  BlessTupleDesc(tupdesc);
1930 
1931  namestrcpy(&slotname, text_to_cstring(slotname_text));
1932  slotent = pgstat_fetch_replslot(slotname);
1933  if (!slotent)
1934  {
1935  /*
1936  * If the slot is not found, initialise its stats. This is possible if
1937  * the create slot message is lost.
1938  */
1939  memset(&allzero, 0, sizeof(PgStat_StatReplSlotEntry));
1940  slotent = &allzero;
1941  }
1942 
1943  values[0] = CStringGetTextDatum(NameStr(slotname));
1944  values[1] = Int64GetDatum(slotent->spill_txns);
1945  values[2] = Int64GetDatum(slotent->spill_count);
1946  values[3] = Int64GetDatum(slotent->spill_bytes);
1947  values[4] = Int64GetDatum(slotent->stream_txns);
1948  values[5] = Int64GetDatum(slotent->stream_count);
1949  values[6] = Int64GetDatum(slotent->stream_bytes);
1950  values[7] = Int64GetDatum(slotent->total_txns);
1951  values[8] = Int64GetDatum(slotent->total_bytes);
1952 
1953  if (slotent->stat_reset_timestamp == 0)
1954  nulls[9] = true;
1955  else
1957 
1958  /* Returns the record as Datum */
1960 }
1961 
1962 /*
1963  * Get the subscription statistics for the given subscription. If the
1964  * subscription statistics is not available, return all-zeros stats.
1965  */
1966 Datum
1968 {
1969 #define PG_STAT_GET_SUBSCRIPTION_STATS_COLS 4
1970  Oid subid = PG_GETARG_OID(0);
1971  TupleDesc tupdesc;
1973  bool nulls[PG_STAT_GET_SUBSCRIPTION_STATS_COLS] = {0};
1974  PgStat_StatSubEntry *subentry;
1975  PgStat_StatSubEntry allzero;
1976 
1977  /* Get subscription stats */
1978  subentry = pgstat_fetch_stat_subscription(subid);
1979 
1980  /* Initialise attributes information in the tuple descriptor */
1982  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subid",
1983  OIDOID, -1, 0);
1984  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "apply_error_count",
1985  INT8OID, -1, 0);
1986  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "sync_error_count",
1987  INT8OID, -1, 0);
1988  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "stats_reset",
1989  TIMESTAMPTZOID, -1, 0);
1990  BlessTupleDesc(tupdesc);
1991 
1992  if (!subentry)
1993  {
1994  /* If the subscription is not found, initialise its stats */
1995  memset(&allzero, 0, sizeof(PgStat_StatSubEntry));
1996  subentry = &allzero;
1997  }
1998 
1999  /* subid */
2000  values[0] = ObjectIdGetDatum(subid);
2001 
2002  /* apply_error_count */
2003  values[1] = Int64GetDatum(subentry->apply_error_count);
2004 
2005  /* sync_error_count */
2006  values[2] = Int64GetDatum(subentry->sync_error_count);
2007 
2008  /* stats_reset */
2009  if (subentry->stat_reset_timestamp == 0)
2010  nulls[3] = true;
2011  else
2013 
2014  /* Returns the record as Datum */
2016 }
2017 
2018 /*
2019  * Checks for presence of stats for object with provided kind, database oid,
2020  * object oid.
2021  *
2022  * This is useful for tests, but not really anything else. Therefore not
2023  * documented.
2024  */
2025 Datum
2027 {
2028  char *stats_type = text_to_cstring(PG_GETARG_TEXT_P(0));
2029  Oid dboid = PG_GETARG_OID(1);
2030  Oid objoid = PG_GETARG_OID(2);
2031  PgStat_Kind kind = pgstat_get_kind_from_str(stats_type);
2032 
2033  PG_RETURN_BOOL(pgstat_have_entry(kind, dboid, objoid));
2034 }
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:637
#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:1379
static Datum values[MAXATTR]
Definition: bootstrap.c:152
#define CStringGetTextDatum(s)
Definition: builtins.h:97
#define NameStr(name)
Definition: c.h:746
unsigned int uint32
Definition: c.h:506
signed int int32
Definition: c.h:494
#define Assert(condition)
Definition: c.h:858
#define UINT64_FORMAT
Definition: c.h:549
#define pg_unreachable()
Definition: c.h:296
#define OidIsValid(objectId)
Definition: c.h:775
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:264
int64 TimestampTz
Definition: timestamp.h:39
int errhint(const char *fmt,...)
Definition: elog.c:1315
int errcode(int sqlerrcode)
Definition: elog.c:855
int errmsg(const char *fmt,...)
Definition: elog.c:1068
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#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:642
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#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:646
#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:92
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:1253
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:370
@ B_WAL_SENDER
Definition: miscadmin.h:342
@ B_BG_WORKER
Definition: miscadmin.h:341
@ B_BACKEND
Definition: miscadmin.h:338
#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:2095
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, Oid objoid)
Definition: pgstat.c:777
void pgstat_reset_counters(void)
Definition: pgstat.c:758
bool pgstat_have_entry(PgStat_Kind kind, Oid dboid, Oid objoid)
Definition: pgstat.c:965
void pgstat_reset_of_kind(PgStat_Kind kind)
Definition: pgstat.c:799
void pgstat_force_next_flush(void)
Definition: pgstat.c:737
void pgstat_clear_snapshot(void)
Definition: pgstat.c:825
TimestampTz pgstat_get_stat_snapshot_timestamp(bool *have_snapshot)
Definition: pgstat.c:948
PgStat_Kind pgstat_get_kind_from_str(char *kind_str)
Definition: pgstat.c:1285
PgStat_Kind
Definition: pgstat.h:36
@ PGSTAT_KIND_REPLSLOT
Definition: pgstat.h:44
@ PGSTAT_KIND_ARCHIVER
Definition: pgstat.h:48
@ PGSTAT_KIND_SLRU
Definition: pgstat.h:52
@ PGSTAT_KIND_IO
Definition: pgstat.h:51
@ PGSTAT_KIND_BGWRITER
Definition: pgstat.h:49
@ PGSTAT_KIND_SUBSCRIPTION
Definition: pgstat.h:45
@ PGSTAT_KIND_CHECKPOINTER
Definition: pgstat.h:50
@ PGSTAT_KIND_FUNCTION
Definition: pgstat.h:43
@ PGSTAT_KIND_WAL
Definition: pgstat.h:53
@ PGSTAT_KIND_RELATION
Definition: pgstat.h:42
#define IOOP_NUM_TYPES
Definition: pgstat.h:308
#define IOCONTEXT_NUM_TYPES
Definition: pgstat.h:294
IOOp
Definition: pgstat.h:297
@ IOOP_EXTEND
Definition: pgstat.h:299
@ IOOP_FSYNC
Definition: pgstat.h:300
@ IOOP_READ
Definition: pgstat.h:302
@ IOOP_WRITEBACK
Definition: pgstat.h:305
@ IOOP_HIT
Definition: pgstat.h:301
@ IOOP_EVICT
Definition: pgstat.h:298
@ IOOP_REUSE
Definition: pgstat.h:303
@ IOOP_WRITE
Definition: pgstat.h:304
int64 PgStat_Counter
Definition: pgstat.h:89
#define IOOBJECT_NUM_TYPES
Definition: pgstat.h:284
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:328
const char * pgstat_get_io_object_name(IOObject io_object)
Definition: pgstat_io.c:240
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:433
const char * pgstat_get_io_context_name(IOContext io_context)
Definition: pgstat_io.c:221
bool pgstat_tracks_io_object(BackendType bktype, IOObject io_object, IOContext io_context)
Definition: pgstat_io.c:368
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:1576
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:1653
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:1469
Datum pg_stat_reset_replication_slot(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1789
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:1533
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:1967
#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:1213
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:1239
static double pg_stat_us_to_ms(PgStat_Counter val_ms)
Definition: pgstatfuncs.c:1351
#define PG_STAT_GET_ACTIVITY_COLS
static io_stat_col pgstat_get_io_time_index(IOOp io_op)
Definition: pgstatfuncs.c:1330
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:1806
Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1668
Datum pg_stat_reset_slru(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1772
Datum pg_stat_get_checkpointer_restartpoints_requested(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1201
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:1297
Datum pg_stat_have_stats(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:2026
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:1225
Datum pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1219
Datum pg_stat_get_io(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1357
Datum pg_stat_get_checkpointer_restartpoints_performed(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1207
#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:1688
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:1633
#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:1623
#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:1231
#define HAS_PGSTAT_PERMISSIONS(role)
Definition: pgstatfuncs.c:37
Datum pg_stat_get_archiver(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1830
Datum pg_stat_get_checkpointer_restartpoints_timed(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1195
Datum pg_stat_reset_shared(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1702
Datum pg_stat_force_next_flush(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1678
Datum pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1750
Datum pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1253
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:1247
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:1896
io_stat_col
Definition: pgstatfuncs.c:1269
@ IO_COL_READS
Definition: pgstatfuncs.c:1274
@ IO_NUM_COLUMNS
Definition: pgstatfuncs.c:1289
@ IO_COL_RESET_TIME
Definition: pgstatfuncs.c:1288
@ IO_COL_WRITE_TIME
Definition: pgstatfuncs.c:1277
@ IO_COL_HITS
Definition: pgstatfuncs.c:1283
@ IO_COL_EXTENDS
Definition: pgstatfuncs.c:1280
@ IO_COL_WRITEBACK_TIME
Definition: pgstatfuncs.c:1279
@ IO_COL_REUSES
Definition: pgstatfuncs.c:1285
@ IO_COL_WRITES
Definition: pgstatfuncs.c:1276
@ IO_COL_OBJECT
Definition: pgstatfuncs.c:1272
@ IO_COL_EVICTIONS
Definition: pgstatfuncs.c:1284
@ IO_COL_CONVERSION
Definition: pgstatfuncs.c:1282
@ IO_COL_WRITEBACKS
Definition: pgstatfuncs.c:1278
@ IO_COL_CONTEXT
Definition: pgstatfuncs.c:1273
@ IO_COL_BACKEND_TYPE
Definition: pgstatfuncs.c:1271
@ IO_COL_FSYNC_TIME
Definition: pgstatfuncs.c:1287
@ IO_COL_EXTEND_TIME
Definition: pgstatfuncs.c:1281
@ IO_COL_FSYNCS
Definition: pgstatfuncs.c:1286
@ IO_COL_INVALID
Definition: pgstatfuncs.c:1270
@ IO_COL_READ_TIME
Definition: pgstatfuncs.c:1275
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:1761
Datum pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1259
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:1018
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:157
uint32 wait_event_info
Definition: proc.h:274
int pid
Definition: proc.h:177
PGPROC * lockGroupLeader
Definition: proc.h:299
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:249
TimestampTz stat_reset_timestamp
Definition: pgstat.h:250
TimestampTz last_archived_timestamp
Definition: pgstat.h:245
char last_failed_wal[MAX_XFN_CHARS+1]
Definition: pgstat.h:247
PgStat_Counter failed_count
Definition: pgstat.h:246
PgStat_Counter archived_count
Definition: pgstat.h:242
char last_archived_wal[MAX_XFN_CHARS+1]
Definition: pgstat.h:243
PgStat_Counter times[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition: pgstat.h:313
PgStat_Counter counts[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition: pgstat.h:312
PgStat_Counter numcalls
Definition: pgstat.h:109
PgStat_BktypeIO stats[BACKEND_NUM_TYPES]
Definition: pgstat.h:319
TimestampTz stat_reset_timestamp
Definition: pgstat.h:318
PgStat_Counter conflict_startup_deadlock
Definition: pgstat.h:340
PgStat_Counter conflict_lock
Definition: pgstat.h:336
TimestampTz stat_reset_timestamp
Definition: pgstat.h:356
PgStat_Counter conflict_snapshot
Definition: pgstat.h:337
TimestampTz last_checksum_failure
Definition: pgstat.h:345
PgStat_Counter conflict_bufferpin
Definition: pgstat.h:339
PgStat_Counter conflict_logicalslot
Definition: pgstat.h:338
PgStat_Counter checksum_failures
Definition: pgstat.h:344
PgStat_Counter conflict_tablespace
Definition: pgstat.h:335
PgStat_Counter numcalls
Definition: pgstat.h:361
TimestampTz stat_reset_timestamp
Definition: pgstat.h:377
PgStat_Counter stream_count
Definition: pgstat.h:373
PgStat_Counter total_txns
Definition: pgstat.h:375
PgStat_Counter total_bytes
Definition: pgstat.h:376
PgStat_Counter spill_txns
Definition: pgstat.h:369
PgStat_Counter stream_txns
Definition: pgstat.h:372
PgStat_Counter spill_count
Definition: pgstat.h:370
PgStat_Counter stream_bytes
Definition: pgstat.h:374
PgStat_Counter spill_bytes
Definition: pgstat.h:371
PgStat_Counter apply_error_count
Definition: pgstat.h:394
PgStat_Counter sync_error_count
Definition: pgstat.h:395
TimestampTz stat_reset_timestamp
Definition: pgstat.h:396
PgStat_Counter wal_write
Definition: pgstat.h:437
PgStat_Counter wal_buffers_full
Definition: pgstat.h:436
PgStat_Counter wal_write_time
Definition: pgstat.h:439
TimestampTz stat_reset_timestamp
Definition: pgstat.h:441
uint64 wal_bytes
Definition: pgstat.h:435
PgStat_Counter wal_sync_time
Definition: pgstat.h:440
PgStat_Counter wal_fpi
Definition: pgstat.h:434
PgStat_Counter wal_sync
Definition: pgstat.h:438
PgStat_Counter wal_records
Definition: pgstat.h:433
TupleDesc setDesc
Definition: execnodes.h:340
Tuplestorestate * setResult
Definition: execnodes.h:339
struct sockaddr_storage addr
Definition: pqcomm.h:32
socklen_t salen
Definition: pqcomm.h:33
Definition: c.h:741
Definition: c.h:687
#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:782
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:4555
void XLogPrefetchResetStats(void)