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-2023, 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/pg_authid.h"
21 #include "catalog/pg_type.h"
22 #include "common/ip.h"
23 #include "funcapi.h"
24 #include "miscadmin.h"
25 #include "pgstat.h"
27 #include "postmaster/postmaster.h"
29 #include "storage/proc.h"
30 #include "storage/procarray.h"
31 #include "utils/acl.h"
32 #include "utils/builtins.h"
33 #include "utils/inet.h"
34 #include "utils/timestamp.h"
35 
36 #define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
37 
38 #define HAS_PGSTAT_PERMISSIONS(role) (has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS) || has_privs_of_role(GetUserId(), role))
39 
40 #define PG_STAT_GET_RELENTRY_INT64(stat) \
41 Datum \
42 CppConcat(pg_stat_get_,stat)(PG_FUNCTION_ARGS) \
43 { \
44  Oid relid = PG_GETARG_OID(0); \
45  int64 result; \
46  PgStat_StatTabEntry *tabentry; \
47  \
48  if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL) \
49  result = 0; \
50  else \
51  result = (int64) (tabentry->stat); \
52  \
53  PG_RETURN_INT64(result); \
54 }
55 
56 /* pg_stat_get_analyze_count */
57 PG_STAT_GET_RELENTRY_INT64(analyze_count)
58 
59 /* pg_stat_get_autoanalyze_count */
60 PG_STAT_GET_RELENTRY_INT64(autoanalyze_count)
61 
62 /* pg_stat_get_autovacuum_count */
63 PG_STAT_GET_RELENTRY_INT64(autovacuum_count)
64 
65 /* pg_stat_get_blocks_fetched */
66 PG_STAT_GET_RELENTRY_INT64(blocks_fetched)
67 
68 /* pg_stat_get_blocks_hit */
70 
71 /* pg_stat_get_dead_tuples */
72 PG_STAT_GET_RELENTRY_INT64(dead_tuples)
73 
74 /* pg_stat_get_ins_since_vacuum */
75 PG_STAT_GET_RELENTRY_INT64(ins_since_vacuum)
76 
77 /* pg_stat_get_live_tuples */
78 PG_STAT_GET_RELENTRY_INT64(live_tuples)
79 
80 /* pg_stat_get_mods_since_analyze */
81 PG_STAT_GET_RELENTRY_INT64(mod_since_analyze)
82 
83 /* pg_stat_get_numscans */
85 
86 /* pg_stat_get_tuples_deleted */
87 PG_STAT_GET_RELENTRY_INT64(tuples_deleted)
88 
89 /* pg_stat_get_tuples_fetched */
90 PG_STAT_GET_RELENTRY_INT64(tuples_fetched)
91 
92 /* pg_stat_get_tuples_hot_updated */
93 PG_STAT_GET_RELENTRY_INT64(tuples_hot_updated)
94 
95 /* pg_stat_get_tuples_inserted */
96 PG_STAT_GET_RELENTRY_INT64(tuples_inserted)
97 
98 /* pg_stat_get_tuples_returned */
99 PG_STAT_GET_RELENTRY_INT64(tuples_returned)
100 
101 /* pg_stat_get_tuples_updated */
102 PG_STAT_GET_RELENTRY_INT64(tuples_updated)
103 
104 /* pg_stat_get_vacuum_count */
105 PG_STAT_GET_RELENTRY_INT64(vacuum_count)
106 
107 #define PG_STAT_GET_RELENTRY_TIMESTAMPTZ(stat) \
108 Datum \
109 CppConcat(pg_stat_get_,stat)(PG_FUNCTION_ARGS) \
110 { \
111  Oid relid = PG_GETARG_OID(0); \
112  TimestampTz result; \
113  PgStat_StatTabEntry *tabentry; \
114  \
115  if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL) \
116  result = 0; \
117  else \
118  result = tabentry->stat; \
119  \
120  if (result == 0) \
121  PG_RETURN_NULL(); \
122  else \
123  PG_RETURN_TIMESTAMPTZ(result); \
124 }
125 
126 /* pg_stat_get_last_analyze_time */
127 PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_analyze_time)
128 
129 /* pg_stat_get_last_autoanalyze_time */
130 PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_autoanalyze_time)
131 
132 /* pg_stat_get_last_autovacuum_time */
133 PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_autovacuum_time)
134 
135 /* pg_stat_get_last_vacuum_time */
136 PG_STAT_GET_RELENTRY_TIMESTAMPTZ(last_vacuum_time)
137 
138 /* pg_stat_get_lastscan */
140 
141 Datum
143 {
144  Oid funcid = PG_GETARG_OID(0);
145  PgStat_StatFuncEntry *funcentry;
146 
147  if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
148  PG_RETURN_NULL();
149  PG_RETURN_INT64(funcentry->f_numcalls);
150 }
151 
152 Datum
154 {
155  Oid funcid = PG_GETARG_OID(0);
156  PgStat_StatFuncEntry *funcentry;
157 
158  if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
159  PG_RETURN_NULL();
160  /* convert counter from microsec to millisec for display */
161  PG_RETURN_FLOAT8(((double) funcentry->f_total_time) / 1000.0);
162 }
163 
164 Datum
166 {
167  Oid funcid = PG_GETARG_OID(0);
168  PgStat_StatFuncEntry *funcentry;
169 
170  if ((funcentry = pgstat_fetch_stat_funcentry(funcid)) == NULL)
171  PG_RETURN_NULL();
172  /* convert counter from microsec to millisec for display */
173  PG_RETURN_FLOAT8(((double) funcentry->f_self_time) / 1000.0);
174 }
175 
176 Datum
178 {
179  FuncCallContext *funcctx;
180  int *fctx;
181 
182  /* stuff done only on the first call of the function */
183  if (SRF_IS_FIRSTCALL())
184  {
185  /* create a function context for cross-call persistence */
186  funcctx = SRF_FIRSTCALL_INIT();
187 
189  sizeof(int));
190  funcctx->user_fctx = fctx;
191 
192  fctx[0] = 0;
193  }
194 
195  /* stuff done on every call of the function */
196  funcctx = SRF_PERCALL_SETUP();
197  fctx = funcctx->user_fctx;
198 
199  fctx[0] += 1;
200 
201  /*
202  * We recheck pgstat_fetch_stat_numbackends() each time through, just in
203  * case the local status data has been refreshed since we started. It's
204  * plenty cheap enough if not. If a refresh does happen, we'll likely
205  * miss or duplicate some backend IDs, but we're content not to crash.
206  * (Refreshing midway through such a query would be problematic usage
207  * anyway, since the backend IDs we've already returned might no longer
208  * refer to extant sessions.)
209  */
210  if (fctx[0] <= pgstat_fetch_stat_numbackends())
211  {
212  /* do when there is more left to send */
213  LocalPgBackendStatus *local_beentry = pgstat_fetch_stat_local_beentry(fctx[0]);
214 
215  SRF_RETURN_NEXT(funcctx, Int32GetDatum(local_beentry->backend_id));
216  }
217  else
218  {
219  /* do when there is no more left */
220  SRF_RETURN_DONE(funcctx);
221  }
222 }
223 
224 /*
225  * Returns command progress information for the named command.
226  */
227 Datum
229 {
230 #define PG_STAT_GET_PROGRESS_COLS PGSTAT_NUM_PROGRESS_PARAM + 3
231  int num_backends = pgstat_fetch_stat_numbackends();
232  int curr_backend;
233  char *cmd = text_to_cstring(PG_GETARG_TEXT_PP(0));
234  ProgressCommandType cmdtype;
235  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
236 
237  /* Translate command name into command type code. */
238  if (pg_strcasecmp(cmd, "VACUUM") == 0)
239  cmdtype = PROGRESS_COMMAND_VACUUM;
240  else if (pg_strcasecmp(cmd, "ANALYZE") == 0)
241  cmdtype = PROGRESS_COMMAND_ANALYZE;
242  else if (pg_strcasecmp(cmd, "CLUSTER") == 0)
243  cmdtype = PROGRESS_COMMAND_CLUSTER;
244  else if (pg_strcasecmp(cmd, "CREATE INDEX") == 0)
246  else if (pg_strcasecmp(cmd, "BASEBACKUP") == 0)
247  cmdtype = PROGRESS_COMMAND_BASEBACKUP;
248  else if (pg_strcasecmp(cmd, "COPY") == 0)
249  cmdtype = PROGRESS_COMMAND_COPY;
250  else
251  ereport(ERROR,
252  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
253  errmsg("invalid command name: \"%s\"", cmd)));
254 
255  InitMaterializedSRF(fcinfo, 0);
256 
257  /* 1-based index */
258  for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
259  {
260  LocalPgBackendStatus *local_beentry;
261  PgBackendStatus *beentry;
263  bool nulls[PG_STAT_GET_PROGRESS_COLS] = {0};
264  int i;
265 
266  local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
267  beentry = &local_beentry->backendStatus;
268 
269  /*
270  * Report values for only those backends which are running the given
271  * command.
272  */
273  if (beentry->st_progress_command != cmdtype)
274  continue;
275 
276  /* Value available to all callers */
277  values[0] = Int32GetDatum(beentry->st_procpid);
278  values[1] = ObjectIdGetDatum(beentry->st_databaseid);
279 
280  /* show rest of the values including relid only to role members */
281  if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
282  {
284  for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
285  values[i + 3] = Int64GetDatum(beentry->st_progress_param[i]);
286  }
287  else
288  {
289  nulls[2] = true;
290  for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
291  nulls[i + 3] = true;
292  }
293 
294  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
295  }
296 
297  return (Datum) 0;
298 }
299 
300 /*
301  * Returns activity of PG backends.
302  */
303 Datum
305 {
306 #define PG_STAT_GET_ACTIVITY_COLS 30
307  int num_backends = pgstat_fetch_stat_numbackends();
308  int curr_backend;
309  int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
310  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
311 
312  InitMaterializedSRF(fcinfo, 0);
313 
314  /* 1-based index */
315  for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
316  {
317  /* for each row */
319  bool nulls[PG_STAT_GET_ACTIVITY_COLS] = {0};
320  LocalPgBackendStatus *local_beentry;
321  PgBackendStatus *beentry;
322  PGPROC *proc;
323  const char *wait_event_type = NULL;
324  const char *wait_event = NULL;
325 
326  /* Get the next one in the list */
327  local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
328  beentry = &local_beentry->backendStatus;
329 
330  /* If looking for specific PID, ignore all the others */
331  if (pid != -1 && beentry->st_procpid != pid)
332  continue;
333 
334  /* Values available to all callers */
335  if (beentry->st_databaseid != InvalidOid)
336  values[0] = ObjectIdGetDatum(beentry->st_databaseid);
337  else
338  nulls[0] = true;
339 
340  values[1] = Int32GetDatum(beentry->st_procpid);
341 
342  if (beentry->st_userid != InvalidOid)
343  values[2] = ObjectIdGetDatum(beentry->st_userid);
344  else
345  nulls[2] = true;
346 
347  if (beentry->st_appname)
348  values[3] = CStringGetTextDatum(beentry->st_appname);
349  else
350  nulls[3] = true;
351 
352  if (TransactionIdIsValid(local_beentry->backend_xid))
353  values[15] = TransactionIdGetDatum(local_beentry->backend_xid);
354  else
355  nulls[15] = true;
356 
357  if (TransactionIdIsValid(local_beentry->backend_xmin))
358  values[16] = TransactionIdGetDatum(local_beentry->backend_xmin);
359  else
360  nulls[16] = true;
361 
362  /* Values only available to role member or pg_read_all_stats */
363  if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
364  {
365  SockAddr zero_clientaddr;
366  char *clipped_activity;
367 
368  switch (beentry->st_state)
369  {
370  case STATE_IDLE:
371  values[4] = CStringGetTextDatum("idle");
372  break;
373  case STATE_RUNNING:
374  values[4] = CStringGetTextDatum("active");
375  break;
377  values[4] = CStringGetTextDatum("idle in transaction");
378  break;
379  case STATE_FASTPATH:
380  values[4] = CStringGetTextDatum("fastpath function call");
381  break;
383  values[4] = CStringGetTextDatum("idle in transaction (aborted)");
384  break;
385  case STATE_DISABLED:
386  values[4] = CStringGetTextDatum("disabled");
387  break;
388  case STATE_UNDEFINED:
389  nulls[4] = true;
390  break;
391  }
392 
393  clipped_activity = pgstat_clip_activity(beentry->st_activity_raw);
394  values[5] = CStringGetTextDatum(clipped_activity);
395  pfree(clipped_activity);
396 
397  /* leader_pid */
398  nulls[28] = true;
399 
400  proc = BackendPidGetProc(beentry->st_procpid);
401 
402  if (proc == NULL && (beentry->st_backendType != B_BACKEND))
403  {
404  /*
405  * For an auxiliary process, retrieve process info from
406  * AuxiliaryProcs stored in shared-memory.
407  */
408  proc = AuxiliaryPidGetProc(beentry->st_procpid);
409  }
410 
411  /*
412  * If a PGPROC entry was retrieved, display wait events and lock
413  * group leader or apply leader information if any. To avoid
414  * extra overhead, no extra lock is being held, so there is no
415  * guarantee of consistency across multiple rows.
416  */
417  if (proc != NULL)
418  {
419  uint32 raw_wait_event;
420  PGPROC *leader;
421 
422  raw_wait_event = UINT32_ACCESS_ONCE(proc->wait_event_info);
423  wait_event_type = pgstat_get_wait_event_type(raw_wait_event);
424  wait_event = pgstat_get_wait_event(raw_wait_event);
425 
426  leader = proc->lockGroupLeader;
427 
428  /*
429  * Show the leader only for active parallel workers. This
430  * leaves the field as NULL for the leader of a parallel group
431  * or the leader of parallel apply workers.
432  */
433  if (leader && leader->pid != beentry->st_procpid)
434  {
435  values[28] = Int32GetDatum(leader->pid);
436  nulls[28] = false;
437  }
438  else if (beentry->st_backendType == B_BG_WORKER)
439  {
440  int leader_pid = GetLeaderApplyWorkerPid(beentry->st_procpid);
441 
442  if (leader_pid != InvalidPid)
443  {
444  values[28] = Int32GetDatum(leader_pid);
445  nulls[28] = false;
446  }
447  }
448  }
449 
450  if (wait_event_type)
451  values[6] = CStringGetTextDatum(wait_event_type);
452  else
453  nulls[6] = true;
454 
455  if (wait_event)
456  values[7] = CStringGetTextDatum(wait_event);
457  else
458  nulls[7] = true;
459 
460  /*
461  * Don't expose transaction time for walsenders; it confuses
462  * monitoring, particularly because we don't keep the time up-to-
463  * date.
464  */
465  if (beentry->st_xact_start_timestamp != 0 &&
466  beentry->st_backendType != B_WAL_SENDER)
468  else
469  nulls[8] = true;
470 
471  if (beentry->st_activity_start_timestamp != 0)
473  else
474  nulls[9] = true;
475 
476  if (beentry->st_proc_start_timestamp != 0)
478  else
479  nulls[10] = true;
480 
481  if (beentry->st_state_start_timestamp != 0)
483  else
484  nulls[11] = true;
485 
486  /* A zeroed client addr means we don't know */
487  memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
488  if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
489  sizeof(zero_clientaddr)) == 0)
490  {
491  nulls[12] = true;
492  nulls[13] = true;
493  nulls[14] = true;
494  }
495  else
496  {
497  if (beentry->st_clientaddr.addr.ss_family == AF_INET ||
498  beentry->st_clientaddr.addr.ss_family == AF_INET6)
499  {
500  char remote_host[NI_MAXHOST];
501  char remote_port[NI_MAXSERV];
502  int ret;
503 
504  remote_host[0] = '\0';
505  remote_port[0] = '\0';
506  ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
507  beentry->st_clientaddr.salen,
508  remote_host, sizeof(remote_host),
509  remote_port, sizeof(remote_port),
510  NI_NUMERICHOST | NI_NUMERICSERV);
511  if (ret == 0)
512  {
513  clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
515  CStringGetDatum(remote_host));
516  if (beentry->st_clienthostname &&
517  beentry->st_clienthostname[0])
519  else
520  nulls[13] = true;
521  values[14] = Int32GetDatum(atoi(remote_port));
522  }
523  else
524  {
525  nulls[12] = true;
526  nulls[13] = true;
527  nulls[14] = true;
528  }
529  }
530  else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
531  {
532  /*
533  * Unix sockets always reports NULL for host and -1 for
534  * port, so it's possible to tell the difference to
535  * connections we have no permissions to view, or with
536  * errors.
537  */
538  nulls[12] = true;
539  nulls[13] = true;
540  values[14] = Int32GetDatum(-1);
541  }
542  else
543  {
544  /* Unknown address type, should never happen */
545  nulls[12] = true;
546  nulls[13] = true;
547  nulls[14] = true;
548  }
549  }
550  /* Add backend type */
551  if (beentry->st_backendType == B_BG_WORKER)
552  {
553  const char *bgw_type;
554 
555  bgw_type = GetBackgroundWorkerTypeByPid(beentry->st_procpid);
556  if (bgw_type)
557  values[17] = CStringGetTextDatum(bgw_type);
558  else
559  nulls[17] = true;
560  }
561  else
562  values[17] =
564 
565  /* SSL information */
566  if (beentry->st_ssl)
567  {
568  values[18] = BoolGetDatum(true); /* ssl */
571  values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
572 
573  if (beentry->st_sslstatus->ssl_client_dn[0])
575  else
576  nulls[22] = true;
577 
578  if (beentry->st_sslstatus->ssl_client_serial[0])
582  Int32GetDatum(-1));
583  else
584  nulls[23] = true;
585 
586  if (beentry->st_sslstatus->ssl_issuer_dn[0])
588  else
589  nulls[24] = true;
590  }
591  else
592  {
593  values[18] = BoolGetDatum(false); /* ssl */
594  nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = true;
595  }
596 
597  /* GSSAPI information */
598  if (beentry->st_gss)
599  {
600  values[25] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */
602  values[27] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */
603  }
604  else
605  {
606  values[25] = BoolGetDatum(false); /* gss_auth */
607  nulls[26] = true; /* No GSS principal */
608  values[27] = BoolGetDatum(false); /* GSS Encryption not in
609  * use */
610  }
611  if (beentry->st_query_id == 0)
612  nulls[29] = true;
613  else
614  values[29] = UInt64GetDatum(beentry->st_query_id);
615  }
616  else
617  {
618  /* No permissions to view data about this session */
619  values[5] = CStringGetTextDatum("<insufficient privilege>");
620  nulls[4] = true;
621  nulls[6] = true;
622  nulls[7] = true;
623  nulls[8] = true;
624  nulls[9] = true;
625  nulls[10] = true;
626  nulls[11] = true;
627  nulls[12] = true;
628  nulls[13] = true;
629  nulls[14] = true;
630  nulls[17] = true;
631  nulls[18] = true;
632  nulls[19] = true;
633  nulls[20] = true;
634  nulls[21] = true;
635  nulls[22] = true;
636  nulls[23] = true;
637  nulls[24] = true;
638  nulls[25] = true;
639  nulls[26] = true;
640  nulls[27] = true;
641  nulls[28] = true;
642  nulls[29] = true;
643  }
644 
645  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
646 
647  /* If only a single backend was requested, and we found it, break. */
648  if (pid != -1)
649  break;
650  }
651 
652  return (Datum) 0;
653 }
654 
655 
656 Datum
658 {
660 }
661 
662 
663 Datum
665 {
666  int32 beid = PG_GETARG_INT32(0);
667  PgBackendStatus *beentry;
668 
669  if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
670  PG_RETURN_NULL();
671 
672  PG_RETURN_INT32(beentry->st_procpid);
673 }
674 
675 
676 Datum
678 {
679  int32 beid = PG_GETARG_INT32(0);
680  PgBackendStatus *beentry;
681 
682  if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
683  PG_RETURN_NULL();
684 
685  PG_RETURN_OID(beentry->st_databaseid);
686 }
687 
688 
689 Datum
691 {
692  int32 beid = PG_GETARG_INT32(0);
693  PgBackendStatus *beentry;
694 
695  if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
696  PG_RETURN_NULL();
697 
698  PG_RETURN_OID(beentry->st_userid);
699 }
700 
701 Datum
703 {
704 #define PG_STAT_GET_SUBXACT_COLS 2
705  TupleDesc tupdesc;
707  bool nulls[PG_STAT_GET_SUBXACT_COLS];
708  int32 beid = PG_GETARG_INT32(0);
709  LocalPgBackendStatus *local_beentry;
710 
711  /* Initialise values and NULL flags arrays */
712  MemSet(values, 0, sizeof(values));
713  MemSet(nulls, 0, sizeof(nulls));
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_fetch_stat_local_beentry(beid)) != 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 beid = PG_GETARG_INT32(0);
744  PgBackendStatus *beentry;
745  const char *activity;
746  char *clipped_activity;
747  text *ret;
748 
749  if ((beentry = pgstat_fetch_stat_beentry(beid)) == 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 beid = PG_GETARG_INT32(0);
769  PgBackendStatus *beentry;
770  PGPROC *proc;
771  const char *wait_event_type = NULL;
772 
773  if ((beentry = pgstat_fetch_stat_beentry(beid)) == 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 beid = PG_GETARG_INT32(0);
790  PgBackendStatus *beentry;
791  PGPROC *proc;
792  const char *wait_event = NULL;
793 
794  if ((beentry = pgstat_fetch_stat_beentry(beid)) == 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 beid = PG_GETARG_INT32(0);
812  TimestampTz result;
813  PgBackendStatus *beentry;
814 
815  if ((beentry = pgstat_fetch_stat_beentry(beid)) == 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 beid = PG_GETARG_INT32(0);
838  TimestampTz result;
839  PgBackendStatus *beentry;
840 
841  if ((beentry = pgstat_fetch_stat_beentry(beid)) == 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 beid = PG_GETARG_INT32(0);
860  TimestampTz result;
861  PgBackendStatus *beentry;
862 
863  if ((beentry = pgstat_fetch_stat_beentry(beid)) == 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 beid = 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_fetch_stat_beentry(beid)) == 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 beid = 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_fetch_stat_beentry(beid)) == 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 beid;
976 
977  result = 0;
978  for (beid = 1; beid <= tot_backends; beid++)
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 
1070 Datum
1072 {
1073  Oid dbid = PG_GETARG_OID(0);
1074  TimestampTz result;
1075  PgStat_StatDBEntry *dbentry;
1076 
1077  if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1078  result = 0;
1079  else
1080  result = dbentry->stat_reset_timestamp;
1081 
1082  if (result == 0)
1083  PG_RETURN_NULL();
1084  else
1085  PG_RETURN_TIMESTAMPTZ(result);
1086 }
1087 
1088 
1089 Datum
1091 {
1092  Oid dbid = PG_GETARG_OID(0);
1093  int64 result;
1094  PgStat_StatDBEntry *dbentry;
1095 
1096  if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1097  result = 0;
1098  else
1099  result = (int64) (dbentry->conflict_tablespace +
1100  dbentry->conflict_lock +
1101  dbentry->conflict_snapshot +
1102  dbentry->conflict_bufferpin +
1103  dbentry->conflict_startup_deadlock);
1104 
1105  PG_RETURN_INT64(result);
1106 }
1107 
1108 Datum
1110 {
1111  Oid dbid = PG_GETARG_OID(0);
1112  int64 result;
1113  PgStat_StatDBEntry *dbentry;
1114 
1115  if (!DataChecksumsEnabled())
1116  PG_RETURN_NULL();
1117 
1118  if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1119  result = 0;
1120  else
1121  result = (int64) (dbentry->checksum_failures);
1122 
1123  PG_RETURN_INT64(result);
1124 }
1125 
1126 Datum
1128 {
1129  Oid dbid = PG_GETARG_OID(0);
1130  TimestampTz result;
1131  PgStat_StatDBEntry *dbentry;
1132 
1133  if (!DataChecksumsEnabled())
1134  PG_RETURN_NULL();
1135 
1136  if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
1137  result = 0;
1138  else
1139  result = dbentry->last_checksum_failure;
1140 
1141  if (result == 0)
1142  PG_RETURN_NULL();
1143  else
1144  PG_RETURN_TIMESTAMPTZ(result);
1145 }
1146 
1147 #define PG_STAT_GET_DBENTRY_FLOAT8(stat) \
1148 Datum \
1149 CppConcat(pg_stat_get_db_,stat)(PG_FUNCTION_ARGS) \
1150 { \
1151  Oid dbid = PG_GETARG_OID(0); \
1152  double result; \
1153  PgStat_StatDBEntry *dbentry; \
1154  \
1155  if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) \
1156  result = 0; \
1157  else \
1158  result = ((double) dbentry->stat) / 1000.0; \
1159  \
1160  PG_RETURN_FLOAT8(result); \
1161 }
1162 
1163 /* pg_stat_get_db_active_time */
1164 PG_STAT_GET_DBENTRY_FLOAT8(active_time)
1165 
1166 /* pg_stat_get_db_blk_read_time */
1167 PG_STAT_GET_DBENTRY_FLOAT8(blk_read_time)
1168 
1169 /* pg_stat_get_db_blk_write_time */
1170 PG_STAT_GET_DBENTRY_FLOAT8(blk_write_time)
1171 
1172 /* pg_stat_get_db_idle_in_transaction_time */
1173 PG_STAT_GET_DBENTRY_FLOAT8(idle_in_transaction_time)
1174 
1175 /* pg_stat_get_db_session_time */
1176 PG_STAT_GET_DBENTRY_FLOAT8(session_time)
1177 
1178 Datum
1180 {
1181  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->timed_checkpoints);
1182 }
1183 
1184 Datum
1186 {
1187  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->requested_checkpoints);
1188 }
1189 
1190 Datum
1192 {
1193  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->buf_written_checkpoints);
1194 }
1195 
1196 Datum
1198 {
1199  PG_RETURN_INT64(pgstat_fetch_stat_bgwriter()->buf_written_clean);
1200 }
1201 
1202 Datum
1204 {
1205  PG_RETURN_INT64(pgstat_fetch_stat_bgwriter()->maxwritten_clean);
1206 }
1207 
1208 Datum
1210 {
1211  /* time is already in msec, just convert to double for presentation */
1212  PG_RETURN_FLOAT8((double)
1213  pgstat_fetch_stat_checkpointer()->checkpoint_write_time);
1214 }
1215 
1216 Datum
1218 {
1219  /* time is already in msec, just convert to double for presentation */
1220  PG_RETURN_FLOAT8((double)
1221  pgstat_fetch_stat_checkpointer()->checkpoint_sync_time);
1222 }
1223 
1224 Datum
1226 {
1227  PG_RETURN_TIMESTAMPTZ(pgstat_fetch_stat_bgwriter()->stat_reset_timestamp);
1228 }
1229 
1230 Datum
1232 {
1233  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->buf_written_backend);
1234 }
1235 
1236 Datum
1238 {
1239  PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->buf_fsync_backend);
1240 }
1241 
1242 Datum
1244 {
1246 }
1247 
1248 /*
1249 * When adding a new column to the pg_stat_io view, add a new enum value
1250 * here above IO_NUM_COLUMNS.
1251 */
1252 typedef enum io_stat_col
1253 {
1267 
1268 /*
1269  * When adding a new IOOp, add a new io_stat_col and add a case to this
1270  * function returning the corresponding io_stat_col.
1271  */
1272 static io_stat_col
1274 {
1275  switch (io_op)
1276  {
1277  case IOOP_EVICT:
1278  return IO_COL_EVICTIONS;
1279  case IOOP_READ:
1280  return IO_COL_READS;
1281  case IOOP_REUSE:
1282  return IO_COL_REUSES;
1283  case IOOP_WRITE:
1284  return IO_COL_WRITES;
1285  case IOOP_EXTEND:
1286  return IO_COL_EXTENDS;
1287  case IOOP_FSYNC:
1288  return IO_COL_FSYNCS;
1289  }
1290 
1291  elog(ERROR, "unrecognized IOOp value: %d", io_op);
1292  pg_unreachable();
1293 }
1294 
1295 Datum
1297 {
1298  ReturnSetInfo *rsinfo;
1299  PgStat_IO *backends_io_stats;
1300  Datum reset_time;
1301 
1302  InitMaterializedSRF(fcinfo, 0);
1303  rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1304 
1305  backends_io_stats = pgstat_fetch_stat_io();
1306 
1307  reset_time = TimestampTzGetDatum(backends_io_stats->stat_reset_timestamp);
1308 
1309  for (int bktype = 0; bktype < BACKEND_NUM_TYPES; bktype++)
1310  {
1311  Datum bktype_desc = CStringGetTextDatum(GetBackendTypeDesc(bktype));
1312  PgStat_BktypeIO *bktype_stats = &backends_io_stats->stats[bktype];
1313 
1314  /*
1315  * In Assert builds, we can afford an extra loop through all of the
1316  * counters checking that only expected stats are non-zero, since it
1317  * keeps the non-Assert code cleaner.
1318  */
1319  Assert(pgstat_bktype_io_stats_valid(bktype_stats, bktype));
1320 
1321  /*
1322  * For those BackendTypes without IO Operation stats, skip
1323  * representing them in the view altogether.
1324  */
1325  if (!pgstat_tracks_io_bktype(bktype))
1326  continue;
1327 
1328  for (int io_obj = 0; io_obj < IOOBJECT_NUM_TYPES; io_obj++)
1329  {
1330  const char *obj_name = pgstat_get_io_object_name(io_obj);
1331 
1332  for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++)
1333  {
1334  const char *context_name = pgstat_get_io_context_name(io_context);
1335 
1336  Datum values[IO_NUM_COLUMNS] = {0};
1337  bool nulls[IO_NUM_COLUMNS] = {0};
1338 
1339  /*
1340  * Some combinations of BackendType, IOObject, and IOContext
1341  * are not valid for any type of IOOp. In such cases, omit the
1342  * entire row from the view.
1343  */
1344  if (!pgstat_tracks_io_object(bktype, io_obj, io_context))
1345  continue;
1346 
1347  values[IO_COL_BACKEND_TYPE] = bktype_desc;
1348  values[IO_COL_IO_CONTEXT] = CStringGetTextDatum(context_name);
1351 
1352  /*
1353  * Hard-code this to the value of BLCKSZ for now. Future
1354  * values could include XLOG_BLCKSZ, once WAL IO is tracked,
1355  * and constant multipliers, once non-block-oriented IO (e.g.
1356  * temporary file IO) is tracked.
1357  */
1359 
1360  for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
1361  {
1362  int col_idx = pgstat_get_io_op_index(io_op);
1363 
1364  /*
1365  * Some combinations of BackendType and IOOp, of IOContext
1366  * and IOOp, and of IOObject and IOOp are not tracked. Set
1367  * these cells in the view NULL.
1368  */
1369  nulls[col_idx] = !pgstat_tracks_io_op(bktype, io_obj, io_context, io_op);
1370 
1371  if (nulls[col_idx])
1372  continue;
1373 
1374  values[col_idx] =
1375  Int64GetDatum(bktype_stats->data[io_obj][io_context][io_op]);
1376  }
1377 
1378  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
1379  values, nulls);
1380  }
1381  }
1382  }
1383 
1384  return (Datum) 0;
1385 }
1386 
1387 /*
1388  * Returns statistics of WAL activity
1389  */
1390 Datum
1392 {
1393 #define PG_STAT_GET_WAL_COLS 9
1394  TupleDesc tupdesc;
1396  bool nulls[PG_STAT_GET_WAL_COLS] = {0};
1397  char buf[256];
1398  PgStat_WalStats *wal_stats;
1399 
1400  /* Initialise attributes information in the tuple descriptor */
1402  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "wal_records",
1403  INT8OID, -1, 0);
1404  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "wal_fpi",
1405  INT8OID, -1, 0);
1406  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "wal_bytes",
1407  NUMERICOID, -1, 0);
1408  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_buffers_full",
1409  INT8OID, -1, 0);
1410  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "wal_write",
1411  INT8OID, -1, 0);
1412  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "wal_sync",
1413  INT8OID, -1, 0);
1414  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "wal_write_time",
1415  FLOAT8OID, -1, 0);
1416  TupleDescInitEntry(tupdesc, (AttrNumber) 8, "wal_sync_time",
1417  FLOAT8OID, -1, 0);
1418  TupleDescInitEntry(tupdesc, (AttrNumber) 9, "stats_reset",
1419  TIMESTAMPTZOID, -1, 0);
1420 
1421  BlessTupleDesc(tupdesc);
1422 
1423  /* Get statistics about WAL activity */
1424  wal_stats = pgstat_fetch_stat_wal();
1425 
1426  /* Fill values and NULLs */
1427  values[0] = Int64GetDatum(wal_stats->wal_records);
1428  values[1] = Int64GetDatum(wal_stats->wal_fpi);
1429 
1430  /* Convert to numeric. */
1431  snprintf(buf, sizeof buf, UINT64_FORMAT, wal_stats->wal_bytes);
1434  ObjectIdGetDatum(0),
1435  Int32GetDatum(-1));
1436 
1437  values[3] = Int64GetDatum(wal_stats->wal_buffers_full);
1438  values[4] = Int64GetDatum(wal_stats->wal_write);
1439  values[5] = Int64GetDatum(wal_stats->wal_sync);
1440 
1441  /* Convert counters from microsec to millisec for display */
1442  values[6] = Float8GetDatum(((double) wal_stats->wal_write_time) / 1000.0);
1443  values[7] = Float8GetDatum(((double) wal_stats->wal_sync_time) / 1000.0);
1444 
1446 
1447  /* Returns the record as Datum */
1449 }
1450 
1451 /*
1452  * Returns statistics of SLRU caches.
1453  */
1454 Datum
1456 {
1457 #define PG_STAT_GET_SLRU_COLS 9
1458  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1459  int i;
1460  PgStat_SLRUStats *stats;
1461 
1462  InitMaterializedSRF(fcinfo, 0);
1463 
1464  /* request SLRU stats from the cumulative stats system */
1465  stats = pgstat_fetch_slru();
1466 
1467  for (i = 0;; i++)
1468  {
1469  /* for each row */
1471  bool nulls[PG_STAT_GET_SLRU_COLS] = {0};
1473  const char *name;
1474 
1476 
1477  if (!name)
1478  break;
1479 
1480  stat = stats[i];
1481 
1483  values[1] = Int64GetDatum(stat.blocks_zeroed);
1484  values[2] = Int64GetDatum(stat.blocks_hit);
1485  values[3] = Int64GetDatum(stat.blocks_read);
1486  values[4] = Int64GetDatum(stat.blocks_written);
1487  values[5] = Int64GetDatum(stat.blocks_exists);
1488  values[6] = Int64GetDatum(stat.flush);
1489  values[7] = Int64GetDatum(stat.truncate);
1490  values[8] = TimestampTzGetDatum(stat.stat_reset_timestamp);
1491 
1492  tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
1493  }
1494 
1495  return (Datum) 0;
1496 }
1497 
1498 Datum
1500 {
1501  Oid relid = PG_GETARG_OID(0);
1502  int64 result;
1503  PgStat_TableStatus *tabentry;
1504 
1505  if ((tabentry = find_tabstat_entry(relid)) == NULL)
1506  result = 0;
1507  else
1508  result = (int64) (tabentry->t_counts.t_numscans);
1509 
1510  PG_RETURN_INT64(result);
1511 }
1512 
1513 Datum
1515 {
1516  Oid relid = PG_GETARG_OID(0);
1517  int64 result;
1518  PgStat_TableStatus *tabentry;
1519 
1520  if ((tabentry = find_tabstat_entry(relid)) == NULL)
1521  result = 0;
1522  else
1523  result = (int64) (tabentry->t_counts.t_tuples_returned);
1524 
1525  PG_RETURN_INT64(result);
1526 }
1527 
1528 Datum
1530 {
1531  Oid relid = PG_GETARG_OID(0);
1532  int64 result;
1533  PgStat_TableStatus *tabentry;
1534 
1535  if ((tabentry = find_tabstat_entry(relid)) == NULL)
1536  result = 0;
1537  else
1538  result = (int64) (tabentry->t_counts.t_tuples_fetched);
1539 
1540  PG_RETURN_INT64(result);
1541 }
1542 
1543 Datum
1545 {
1546  Oid relid = PG_GETARG_OID(0);
1547  int64 result;
1548  PgStat_TableStatus *tabentry;
1550 
1551  if ((tabentry = find_tabstat_entry(relid)) == NULL)
1552  result = 0;
1553  else
1554  {
1555  result = tabentry->t_counts.t_tuples_inserted;
1556  /* live subtransactions' counts aren't in t_tuples_inserted yet */
1557  for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1558  result += trans->tuples_inserted;
1559  }
1560 
1561  PG_RETURN_INT64(result);
1562 }
1563 
1564 Datum
1566 {
1567  Oid relid = PG_GETARG_OID(0);
1568  int64 result;
1569  PgStat_TableStatus *tabentry;
1571 
1572  if ((tabentry = find_tabstat_entry(relid)) == NULL)
1573  result = 0;
1574  else
1575  {
1576  result = tabentry->t_counts.t_tuples_updated;
1577  /* live subtransactions' counts aren't in t_tuples_updated yet */
1578  for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1579  result += trans->tuples_updated;
1580  }
1581 
1582  PG_RETURN_INT64(result);
1583 }
1584 
1585 Datum
1587 {
1588  Oid relid = PG_GETARG_OID(0);
1589  int64 result;
1590  PgStat_TableStatus *tabentry;
1592 
1593  if ((tabentry = find_tabstat_entry(relid)) == NULL)
1594  result = 0;
1595  else
1596  {
1597  result = tabentry->t_counts.t_tuples_deleted;
1598  /* live subtransactions' counts aren't in t_tuples_deleted yet */
1599  for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1600  result += trans->tuples_deleted;
1601  }
1602 
1603  PG_RETURN_INT64(result);
1604 }
1605 
1606 Datum
1608 {
1609  Oid relid = PG_GETARG_OID(0);
1610  int64 result;
1611  PgStat_TableStatus *tabentry;
1612 
1613  if ((tabentry = find_tabstat_entry(relid)) == NULL)
1614  result = 0;
1615  else
1616  result = (int64) (tabentry->t_counts.t_tuples_hot_updated);
1617 
1618  PG_RETURN_INT64(result);
1619 }
1620 
1621 Datum
1623 {
1624  Oid relid = PG_GETARG_OID(0);
1625  int64 result;
1626  PgStat_TableStatus *tabentry;
1627 
1628  if ((tabentry = find_tabstat_entry(relid)) == NULL)
1629  result = 0;
1630  else
1631  result = (int64) (tabentry->t_counts.t_blocks_fetched);
1632 
1633  PG_RETURN_INT64(result);
1634 }
1635 
1636 Datum
1638 {
1639  Oid relid = PG_GETARG_OID(0);
1640  int64 result;
1641  PgStat_TableStatus *tabentry;
1642 
1643  if ((tabentry = find_tabstat_entry(relid)) == NULL)
1644  result = 0;
1645  else
1646  result = (int64) (tabentry->t_counts.t_blocks_hit);
1647 
1648  PG_RETURN_INT64(result);
1649 }
1650 
1651 Datum
1653 {
1654  Oid funcid = PG_GETARG_OID(0);
1655  PgStat_FunctionCounts *funcentry;
1656 
1657  if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1658  PG_RETURN_NULL();
1659  PG_RETURN_INT64(funcentry->f_numcalls);
1660 }
1661 
1662 Datum
1664 {
1665  Oid funcid = PG_GETARG_OID(0);
1666  PgStat_FunctionCounts *funcentry;
1667 
1668  if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1669  PG_RETURN_NULL();
1671 }
1672 
1673 Datum
1675 {
1676  Oid funcid = PG_GETARG_OID(0);
1677  PgStat_FunctionCounts *funcentry;
1678 
1679  if ((funcentry = find_funcstat_entry(funcid)) == NULL)
1680  PG_RETURN_NULL();
1682 }
1683 
1684 
1685 /* Get the timestamp of the current statistics snapshot */
1686 Datum
1688 {
1689  bool have_snapshot;
1690  TimestampTz ts;
1691 
1692  ts = pgstat_get_stat_snapshot_timestamp(&have_snapshot);
1693 
1694  if (!have_snapshot)
1695  PG_RETURN_NULL();
1696 
1698 }
1699 
1700 /* Discard the active statistics snapshot */
1701 Datum
1703 {
1705 
1706  PG_RETURN_VOID();
1707 }
1708 
1709 
1710 /* Force statistics to be reported at the next occasion */
1711 Datum
1713 {
1715 
1716  PG_RETURN_VOID();
1717 }
1718 
1719 
1720 /* Reset all counters for the current database */
1721 Datum
1723 {
1725 
1726  PG_RETURN_VOID();
1727 }
1728 
1729 /*
1730  * Reset some shared cluster-wide counters
1731  *
1732  * When adding a new reset target, ideally the name should match that in
1733  * pgstat_kind_infos, if relevant.
1734  */
1735 Datum
1737 {
1738  char *target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1739 
1740  if (strcmp(target, "archiver") == 0)
1742  else if (strcmp(target, "bgwriter") == 0)
1743  {
1744  /*
1745  * Historically checkpointer was part of bgwriter, continue to reset
1746  * both for now.
1747  */
1750  }
1751  else if (strcmp(target, "io") == 0)
1753  else if (strcmp(target, "recovery_prefetch") == 0)
1755  else if (strcmp(target, "wal") == 0)
1757  else
1758  ereport(ERROR,
1759  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1760  errmsg("unrecognized reset target: \"%s\"", target),
1761  errhint("Target must be \"archiver\", \"bgwriter\", \"io\", \"recovery_prefetch\", or \"wal\".")));
1762 
1763  PG_RETURN_VOID();
1764 }
1765 
1766 /* Reset a single counter in the current database */
1767 Datum
1769 {
1770  Oid taboid = PG_GETARG_OID(0);
1771 
1773 
1774  PG_RETURN_VOID();
1775 }
1776 
1777 Datum
1779 {
1780  Oid funcoid = PG_GETARG_OID(0);
1781 
1783 
1784  PG_RETURN_VOID();
1785 }
1786 
1787 /* Reset SLRU counters (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_slru(target);
1799  }
1800 
1801  PG_RETURN_VOID();
1802 }
1803 
1804 /* Reset replication slots stats (a specific one or all of them). */
1805 Datum
1807 {
1808  char *target = NULL;
1809 
1810  if (PG_ARGISNULL(0))
1812  else
1813  {
1814  target = text_to_cstring(PG_GETARG_TEXT_PP(0));
1815  pgstat_reset_replslot(target);
1816  }
1817 
1818  PG_RETURN_VOID();
1819 }
1820 
1821 /* Reset subscription stats (a specific one or all of them) */
1822 Datum
1824 {
1825  Oid subid;
1826 
1827  if (PG_ARGISNULL(0))
1828  {
1829  /* Clear all subscription stats */
1831  }
1832  else
1833  {
1834  subid = PG_GETARG_OID(0);
1835 
1836  if (!OidIsValid(subid))
1837  ereport(ERROR,
1838  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1839  errmsg("invalid subscription OID %u", subid)));
1841  }
1842 
1843  PG_RETURN_VOID();
1844 }
1845 
1846 Datum
1848 {
1849  TupleDesc tupdesc;
1850  Datum values[7] = {0};
1851  bool nulls[7] = {0};
1852  PgStat_ArchiverStats *archiver_stats;
1853 
1854  /* Initialise attributes information in the tuple descriptor */
1855  tupdesc = CreateTemplateTupleDesc(7);
1856  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
1857  INT8OID, -1, 0);
1858  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal",
1859  TEXTOID, -1, 0);
1860  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "last_archived_time",
1861  TIMESTAMPTZOID, -1, 0);
1862  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "failed_count",
1863  INT8OID, -1, 0);
1864  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "last_failed_wal",
1865  TEXTOID, -1, 0);
1866  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "last_failed_time",
1867  TIMESTAMPTZOID, -1, 0);
1868  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stats_reset",
1869  TIMESTAMPTZOID, -1, 0);
1870 
1871  BlessTupleDesc(tupdesc);
1872 
1873  /* Get statistics about the archiver process */
1874  archiver_stats = pgstat_fetch_stat_archiver();
1875 
1876  /* Fill values and NULLs */
1877  values[0] = Int64GetDatum(archiver_stats->archived_count);
1878  if (*(archiver_stats->last_archived_wal) == '\0')
1879  nulls[1] = true;
1880  else
1881  values[1] = CStringGetTextDatum(archiver_stats->last_archived_wal);
1882 
1883  if (archiver_stats->last_archived_timestamp == 0)
1884  nulls[2] = true;
1885  else
1886  values[2] = TimestampTzGetDatum(archiver_stats->last_archived_timestamp);
1887 
1888  values[3] = Int64GetDatum(archiver_stats->failed_count);
1889  if (*(archiver_stats->last_failed_wal) == '\0')
1890  nulls[4] = true;
1891  else
1892  values[4] = CStringGetTextDatum(archiver_stats->last_failed_wal);
1893 
1894  if (archiver_stats->last_failed_timestamp == 0)
1895  nulls[5] = true;
1896  else
1897  values[5] = TimestampTzGetDatum(archiver_stats->last_failed_timestamp);
1898 
1899  if (archiver_stats->stat_reset_timestamp == 0)
1900  nulls[6] = true;
1901  else
1902  values[6] = TimestampTzGetDatum(archiver_stats->stat_reset_timestamp);
1903 
1904  /* Returns the record as Datum */
1906 }
1907 
1908 /*
1909  * Get the statistics for the replication slot. If the slot statistics is not
1910  * available, return all-zeroes stats.
1911  */
1912 Datum
1914 {
1915 #define PG_STAT_GET_REPLICATION_SLOT_COLS 10
1916  text *slotname_text = PG_GETARG_TEXT_P(0);
1917  NameData slotname;
1918  TupleDesc tupdesc;
1920  bool nulls[PG_STAT_GET_REPLICATION_SLOT_COLS] = {0};
1921  PgStat_StatReplSlotEntry *slotent;
1922  PgStat_StatReplSlotEntry allzero;
1923 
1924  /* Initialise attributes information in the tuple descriptor */
1926  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "slot_name",
1927  TEXTOID, -1, 0);
1928  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "spill_txns",
1929  INT8OID, -1, 0);
1930  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "spill_count",
1931  INT8OID, -1, 0);
1932  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "spill_bytes",
1933  INT8OID, -1, 0);
1934  TupleDescInitEntry(tupdesc, (AttrNumber) 5, "stream_txns",
1935  INT8OID, -1, 0);
1936  TupleDescInitEntry(tupdesc, (AttrNumber) 6, "stream_count",
1937  INT8OID, -1, 0);
1938  TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stream_bytes",
1939  INT8OID, -1, 0);
1940  TupleDescInitEntry(tupdesc, (AttrNumber) 8, "total_txns",
1941  INT8OID, -1, 0);
1942  TupleDescInitEntry(tupdesc, (AttrNumber) 9, "total_bytes",
1943  INT8OID, -1, 0);
1944  TupleDescInitEntry(tupdesc, (AttrNumber) 10, "stats_reset",
1945  TIMESTAMPTZOID, -1, 0);
1946  BlessTupleDesc(tupdesc);
1947 
1948  namestrcpy(&slotname, text_to_cstring(slotname_text));
1949  slotent = pgstat_fetch_replslot(slotname);
1950  if (!slotent)
1951  {
1952  /*
1953  * If the slot is not found, initialise its stats. This is possible if
1954  * the create slot message is lost.
1955  */
1956  memset(&allzero, 0, sizeof(PgStat_StatReplSlotEntry));
1957  slotent = &allzero;
1958  }
1959 
1960  values[0] = CStringGetTextDatum(NameStr(slotname));
1961  values[1] = Int64GetDatum(slotent->spill_txns);
1962  values[2] = Int64GetDatum(slotent->spill_count);
1963  values[3] = Int64GetDatum(slotent->spill_bytes);
1964  values[4] = Int64GetDatum(slotent->stream_txns);
1965  values[5] = Int64GetDatum(slotent->stream_count);
1966  values[6] = Int64GetDatum(slotent->stream_bytes);
1967  values[7] = Int64GetDatum(slotent->total_txns);
1968  values[8] = Int64GetDatum(slotent->total_bytes);
1969 
1970  if (slotent->stat_reset_timestamp == 0)
1971  nulls[9] = true;
1972  else
1974 
1975  /* Returns the record as Datum */
1977 }
1978 
1979 /*
1980  * Get the subscription statistics for the given subscription. If the
1981  * subscription statistics is not available, return all-zeros stats.
1982  */
1983 Datum
1985 {
1986 #define PG_STAT_GET_SUBSCRIPTION_STATS_COLS 4
1987  Oid subid = PG_GETARG_OID(0);
1988  TupleDesc tupdesc;
1990  bool nulls[PG_STAT_GET_SUBSCRIPTION_STATS_COLS] = {0};
1991  PgStat_StatSubEntry *subentry;
1992  PgStat_StatSubEntry allzero;
1993 
1994  /* Get subscription stats */
1995  subentry = pgstat_fetch_stat_subscription(subid);
1996 
1997  /* Initialise attributes information in the tuple descriptor */
1999  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subid",
2000  OIDOID, -1, 0);
2001  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "apply_error_count",
2002  INT8OID, -1, 0);
2003  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "sync_error_count",
2004  INT8OID, -1, 0);
2005  TupleDescInitEntry(tupdesc, (AttrNumber) 4, "stats_reset",
2006  TIMESTAMPTZOID, -1, 0);
2007  BlessTupleDesc(tupdesc);
2008 
2009  if (!subentry)
2010  {
2011  /* If the subscription is not found, initialise its stats */
2012  memset(&allzero, 0, sizeof(PgStat_StatSubEntry));
2013  subentry = &allzero;
2014  }
2015 
2016  /* subid */
2017  values[0] = ObjectIdGetDatum(subid);
2018 
2019  /* apply_error_count */
2020  values[1] = Int64GetDatum(subentry->apply_error_count);
2021 
2022  /* sync_error_count */
2023  values[2] = Int64GetDatum(subentry->sync_error_count);
2024 
2025  /* stats_reset */
2026  if (subentry->stat_reset_timestamp == 0)
2027  nulls[3] = true;
2028  else
2030 
2031  /* Returns the record as Datum */
2033 }
2034 
2035 /*
2036  * Checks for presence of stats for object with provided kind, database oid,
2037  * object oid.
2038  *
2039  * This is useful for tests, but not really anything else. Therefore not
2040  * documented.
2041  */
2042 Datum
2044 {
2045  char *stats_type = text_to_cstring(PG_GETARG_TEXT_P(0));
2046  Oid dboid = PG_GETARG_OID(1);
2047  Oid objoid = PG_GETARG_OID(2);
2048  PgStat_Kind kind = pgstat_get_kind_from_str(stats_type);
2049 
2050  PG_RETURN_BOOL(pgstat_have_entry(kind, dboid, objoid));
2051 }
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_fetch_stat_local_beentry(int beid)
PgBackendStatus * pgstat_fetch_stat_beentry(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:1285
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define CStringGetTextDatum(s)
Definition: builtins.h:94
#define NameStr(name)
Definition: c.h:730
unsigned int uint32
Definition: c.h:490
signed int int32
Definition: c.h:478
#define UINT64_FORMAT
Definition: c.h:533
#define pg_unreachable()
Definition: c.h:280
#define MemSet(start, val, len)
Definition: c.h:1004
#define OidIsValid(objectId)
Definition: c.h:759
int64 TimestampTz
Definition: timestamp.h:39
int errhint(const char *fmt,...)
Definition: elog.c:1316
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
const char * name
Definition: encode.c:571
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2071
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1794
Datum Float8GetDatum(float8 X)
Definition: fmgr.c:1803
#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:303
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:307
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:309
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:305
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition: funcapi.h:230
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:327
int MyProcPid
Definition: globals.c:44
Oid MyDatabaseId
Definition: globals.c:89
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:191
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:1208
Assert(fmt[strlen(fmt) - 1] !='\n')
void pfree(void *pointer)
Definition: mcxt.c:1436
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1005
#define BACKEND_NUM_TYPES
Definition: miscadmin.h:335
@ B_WAL_SENDER
Definition: miscadmin.h:331
@ B_BG_WORKER
Definition: miscadmin.h:324
@ B_BACKEND
Definition: miscadmin.h:323
#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:67
void pgstat_reset(PgStat_Kind kind, Oid dboid, Oid objoid)
Definition: pgstat.c:719
void pgstat_reset_counters(void)
Definition: pgstat.c:700
bool pgstat_have_entry(PgStat_Kind kind, Oid dboid, Oid objoid)
Definition: pgstat.c:900
void pgstat_reset_of_kind(PgStat_Kind kind)
Definition: pgstat.c:741
void pgstat_force_next_flush(void)
Definition: pgstat.c:679
void pgstat_clear_snapshot(void)
Definition: pgstat.c:766
TimestampTz pgstat_get_stat_snapshot_timestamp(bool *have_snapshot)
Definition: pgstat.c:886
PgStat_Kind pgstat_get_kind_from_str(char *kind_str)
Definition: pgstat.c:1214
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:303
#define IOCONTEXT_NUM_TYPES
Definition: pgstat.h:291
IOOp
Definition: pgstat.h:294
@ IOOP_EXTEND
Definition: pgstat.h:296
@ IOOP_FSYNC
Definition: pgstat.h:297
@ IOOP_READ
Definition: pgstat.h:298
@ IOOP_EVICT
Definition: pgstat.h:295
@ IOOP_REUSE
Definition: pgstat.h:299
@ IOOP_WRITE
Definition: pgstat.h:300
#define IOOBJECT_NUM_TYPES
Definition: pgstat.h:281
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:231
const char * pgstat_get_io_object_name(IOObject io_object)
Definition: pgstat_io.c:153
bool pgstat_bktype_io_stats_valid(PgStat_BktypeIO *backend_io, BackendType bktype)
Definition: pgstat_io.c:34
PgStat_IO * pgstat_fetch_stat_io(void)
Definition: pgstat_io.c:79
bool pgstat_tracks_io_op(BackendType bktype, IOObject io_object, IOContext io_context, IOOp io_op)
Definition: pgstat_io.c:334
const char * pgstat_get_io_context_name(IOContext io_context)
Definition: pgstat_io.c:134
bool pgstat_tracks_io_object(BackendType bktype, IOObject io_object, IOContext io_context)
Definition: pgstat_io.c:269
PgStat_TableStatus * find_tabstat_entry(Oid rel_id)
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:55
Datum pg_stat_get_function_total_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:153
Datum pg_stat_get_xact_tuples_hot_updated(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1607
Datum pg_stat_get_progress_info(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:228
Datum pg_stat_get_snapshot_timestamp(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1687
Datum pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:879
Datum pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1544
Datum pg_stat_get_db_stat_reset_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1071
#define PG_STAT_GET_WAL_COLS
Datum pg_stat_get_wal(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1391
Datum pg_stat_get_checkpoint_write_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1209
Datum pg_stat_reset_replication_slot(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1806
Datum pg_stat_get_checkpoint_sync_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1217
#define UINT32_ACCESS_ONCE(var)
Definition: pgstatfuncs.c:36
Datum pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1231
Datum pg_stat_get_activity(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:304
Datum pg_stat_get_slru(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1455
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:1090
Datum pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1185
Datum pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1191
Datum pg_stat_get_function_self_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:165
Datum pg_stat_get_subscription_stats(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1984
Datum pg_stat_get_xact_function_total_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1663
#define PG_STAT_GET_SLRU_COLS
#define PG_STAT_GET_DBENTRY_INT64(stat)
Definition: pgstatfuncs.c:990
Datum pg_stat_get_xact_blocks_fetched(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1622
Datum pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:664
#define PG_STAT_GET_ACTIVITY_COLS
Datum pg_stat_get_xact_numscans(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1499
Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:741
Datum pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:970
Datum pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1514
Datum pg_stat_get_db_checksum_failures(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1109
Datum pg_stat_reset_subscription_stats(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1823
Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1702
Datum pg_stat_get_xact_blocks_hit(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1637
Datum pg_stat_reset_slru(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1789
Datum pg_stat_get_db_checksum_last_failure(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1127
static io_stat_col pgstat_get_io_op_index(IOOp io_op)
Definition: pgstatfuncs.c:1273
Datum pg_stat_have_stats(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:2043
Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:177
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:1203
Datum pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1197
Datum pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1179
Datum pg_stat_get_io(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1296
Datum pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:690
Datum pg_stat_reset(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1722
Datum pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:787
#define PG_STAT_GET_SUBXACT_COLS
#define PG_STAT_GET_RELENTRY_INT64(stat)
Definition: pgstatfuncs.c:40
Datum pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:677
Datum pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1652
#define PG_STAT_GET_RELENTRY_TIMESTAMPTZ(stat)
Definition: pgstatfuncs.c:107
#define PG_STAT_GET_PROGRESS_COLS
Datum pg_stat_get_xact_tuples_fetched(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1529
#define PG_STAT_GET_DBENTRY_FLOAT8(stat)
Definition: pgstatfuncs.c:1147
Datum pg_stat_get_xact_function_self_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1674
#define HAS_PGSTAT_PERMISSIONS(role)
Definition: pgstatfuncs.c:38
Datum pg_stat_get_buf_fsync_backend(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1237
Datum pg_stat_get_archiver(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1847
Datum pg_stat_reset_shared(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1736
Datum pg_stat_force_next_flush(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1712
Datum pg_stat_reset_single_table_counters(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1768
Datum pg_stat_get_bgwriter_stat_reset_time(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1225
Datum pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:835
Datum pg_stat_get_function_calls(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:142
Datum pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1565
Datum pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:702
Datum pg_stat_get_replication_slot(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1913
Datum pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1586
io_stat_col
Definition: pgstatfuncs.c:1253
@ IO_COL_READS
Definition: pgstatfuncs.c:1257
@ IO_NUM_COLUMNS
Definition: pgstatfuncs.c:1265
@ IO_COL_RESET_TIME
Definition: pgstatfuncs.c:1264
@ IO_COL_EXTENDS
Definition: pgstatfuncs.c:1259
@ IO_COL_IO_CONTEXT
Definition: pgstatfuncs.c:1256
@ IO_COL_REUSES
Definition: pgstatfuncs.c:1262
@ IO_COL_WRITES
Definition: pgstatfuncs.c:1258
@ IO_COL_EVICTIONS
Definition: pgstatfuncs.c:1261
@ IO_COL_CONVERSION
Definition: pgstatfuncs.c:1260
@ IO_COL_BACKEND_TYPE
Definition: pgstatfuncs.c:1254
@ IO_COL_FSYNCS
Definition: pgstatfuncs.c:1263
@ IO_COL_IO_OBJECT
Definition: pgstatfuncs.c:1255
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:1778
Datum pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:1243
Datum pg_backend_pid(PG_FUNCTION_ARGS)
Definition: pgstatfuncs.c:657
#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:3185
PGPROC * AuxiliaryPidGetProc(int pid)
Definition: proc.c:965
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:270
int pid
Definition: proc.h:186
PGPROC * lockGroupLeader
Definition: proc.h:295
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:248
TimestampTz stat_reset_timestamp
Definition: pgstat.h:249
TimestampTz last_archived_timestamp
Definition: pgstat.h:244
char last_failed_wal[MAX_XFN_CHARS+1]
Definition: pgstat.h:246
PgStat_Counter failed_count
Definition: pgstat.h:245
PgStat_Counter archived_count
Definition: pgstat.h:241
char last_archived_wal[MAX_XFN_CHARS+1]
Definition: pgstat.h:242
PgStat_Counter data[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition: pgstat.h:307
instr_time f_total_time
Definition: pgstat.h:110
PgStat_Counter f_numcalls
Definition: pgstat.h:109
instr_time f_self_time
Definition: pgstat.h:111
PgStat_BktypeIO stats[BACKEND_NUM_TYPES]
Definition: pgstat.h:313
TimestampTz stat_reset_timestamp
Definition: pgstat.h:312
PgStat_Counter conflict_startup_deadlock
Definition: pgstat.h:333
PgStat_Counter conflict_lock
Definition: pgstat.h:330
TimestampTz stat_reset_timestamp
Definition: pgstat.h:349
PgStat_Counter conflict_snapshot
Definition: pgstat.h:331
TimestampTz last_checksum_failure
Definition: pgstat.h:338
PgStat_Counter conflict_bufferpin
Definition: pgstat.h:332
PgStat_Counter checksum_failures
Definition: pgstat.h:337
PgStat_Counter conflict_tablespace
Definition: pgstat.h:329
PgStat_Counter f_self_time
Definition: pgstat.h:357
PgStat_Counter f_total_time
Definition: pgstat.h:356
PgStat_Counter f_numcalls
Definition: pgstat.h:354
TimestampTz stat_reset_timestamp
Definition: pgstat.h:370
PgStat_Counter stream_count
Definition: pgstat.h:366
PgStat_Counter total_txns
Definition: pgstat.h:368
PgStat_Counter total_bytes
Definition: pgstat.h:369
PgStat_Counter spill_txns
Definition: pgstat.h:362
PgStat_Counter stream_txns
Definition: pgstat.h:365
PgStat_Counter spill_count
Definition: pgstat.h:363
PgStat_Counter stream_bytes
Definition: pgstat.h:367
PgStat_Counter spill_bytes
Definition: pgstat.h:364
PgStat_Counter apply_error_count
Definition: pgstat.h:387
PgStat_Counter sync_error_count
Definition: pgstat.h:388
TimestampTz stat_reset_timestamp
Definition: pgstat.h:389
PgStat_Counter t_tuples_hot_updated
Definition: pgstat.h:170
PgStat_Counter t_tuples_inserted
Definition: pgstat.h:167
PgStat_Counter t_tuples_updated
Definition: pgstat.h:168
PgStat_Counter t_tuples_fetched
Definition: pgstat.h:165
PgStat_Counter t_tuples_deleted
Definition: pgstat.h:169
PgStat_Counter t_numscans
Definition: pgstat.h:162
PgStat_Counter t_blocks_hit
Definition: pgstat.h:178
PgStat_Counter t_blocks_fetched
Definition: pgstat.h:177
PgStat_Counter t_tuples_returned
Definition: pgstat.h:164
PgStat_TableCounts t_counts
Definition: pgstat.h:201
struct PgStat_TableXactStatus * trans
Definition: pgstat.h:200
PgStat_Counter wal_write
Definition: pgstat.h:429
PgStat_Counter wal_buffers_full
Definition: pgstat.h:428
PgStat_Counter wal_write_time
Definition: pgstat.h:431
TimestampTz stat_reset_timestamp
Definition: pgstat.h:433
uint64 wal_bytes
Definition: pgstat.h:427
PgStat_Counter wal_sync_time
Definition: pgstat.h:432
PgStat_Counter wal_fpi
Definition: pgstat.h:426
PgStat_Counter wal_sync
Definition: pgstat.h:430
PgStat_Counter wal_records
Definition: pgstat.h:425
TupleDesc setDesc
Definition: execnodes.h:334
Tuplestorestate * setResult
Definition: execnodes.h:333
struct sockaddr_storage addr
Definition: pqcomm.h:26
socklen_t salen
Definition: pqcomm.h:27
Definition: c.h:725
Definition: c.h:671
#define TransactionIdIsValid(xid)
Definition: transam.h:41
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:45
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:583
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, 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:215
text * cstring_to_text(const char *s)
Definition: varlena.c:182
const char * pgstat_get_wait_event(uint32 wait_event_info)
Definition: wait_event.c:129
const char * pgstat_get_wait_event_type(uint32 wait_event_info)
Definition: wait_event.c:74
#define stat
Definition: win32_port.h:286
bool DataChecksumsEnabled(void)
Definition: xlog.c:4197
void XLogPrefetchResetStats(void)
static zic_t trans[TZ_MAX_LEAPS]
Definition: zic.c:402