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