1 /* ----------
2  *	pgstat.h
3  *
4  *	Definitions for the PostgreSQL statistics collector daemon.
5  *
6  *	Copyright (c) 2001-2020, PostgreSQL Global Development Group
7  *
8  *	src/include/pgstat.h
9  * ----------
10  */
11 #ifndef PGSTAT_H
12 #define PGSTAT_H
13 
14 #include "datatype/timestamp.h"
15 #include "libpq/pqcomm.h"
16 #include "miscadmin.h"
17 #include "port/atomics.h"
18 #include "portability/instr_time.h"
19 #include "postmaster/pgarch.h"
20 #include "storage/proc.h"
21 #include "utils/hsearch.h"
22 #include "utils/relcache.h"
23 
24 
25 /* ----------
26  * Paths for the statistics files (relative to installation's $PGDATA).
27  * ----------
28  */
29 #define PGSTAT_STAT_PERMANENT_DIRECTORY		"pg_stat"
30 #define PGSTAT_STAT_PERMANENT_FILENAME		"pg_stat/global.stat"
31 #define PGSTAT_STAT_PERMANENT_TMPFILE		"pg_stat/global.tmp"
32 
33 /* Default directory to store temporary statistics data in */
34 #define PG_STAT_TMP_DIR		"pg_stat_tmp"
35 
36 /* Values for track_functions GUC variable --- order is significant! */
37 typedef enum TrackFunctionsLevel
38 {
39 	TRACK_FUNC_OFF,
40 	TRACK_FUNC_PL,
41 	TRACK_FUNC_ALL
42 }			TrackFunctionsLevel;
43 
44 /* ----------
45  * The types of backend -> collector messages
46  * ----------
47  */
48 typedef enum StatMsgType
49 {
50 	PGSTAT_MTYPE_DUMMY,
51 	PGSTAT_MTYPE_INQUIRY,
52 	PGSTAT_MTYPE_TABSTAT,
53 	PGSTAT_MTYPE_TABPURGE,
54 	PGSTAT_MTYPE_DROPDB,
55 	PGSTAT_MTYPE_RESETCOUNTER,
56 	PGSTAT_MTYPE_RESETSHAREDCOUNTER,
57 	PGSTAT_MTYPE_RESETSINGLECOUNTER,
58 	PGSTAT_MTYPE_RESETSLRUCOUNTER,
59 	PGSTAT_MTYPE_AUTOVAC_START,
60 	PGSTAT_MTYPE_VACUUM,
61 	PGSTAT_MTYPE_ANALYZE,
62 	PGSTAT_MTYPE_ARCHIVER,
63 	PGSTAT_MTYPE_BGWRITER,
64 	PGSTAT_MTYPE_SLRU,
65 	PGSTAT_MTYPE_FUNCSTAT,
66 	PGSTAT_MTYPE_FUNCPURGE,
67 	PGSTAT_MTYPE_RECOVERYCONFLICT,
68 	PGSTAT_MTYPE_TEMPFILE,
69 	PGSTAT_MTYPE_DEADLOCK,
70 	PGSTAT_MTYPE_CHECKSUMFAILURE
71 } StatMsgType;
72 
73 /* ----------
74  * The data type used for counters.
75  * ----------
76  */
77 typedef int64 PgStat_Counter;
78 
79 /* ----------
80  * PgStat_TableCounts			The actual per-table counts kept by a backend
81  *
82  * This struct should contain only actual event counters, because we memcmp
83  * it against zeroes to detect whether there are any counts to transmit.
84  * It is a component of PgStat_TableStatus (within-backend state) and
85  * PgStat_TableEntry (the transmitted message format).
86  *
87  * Note: for a table, tuples_returned is the number of tuples successfully
88  * fetched by heap_getnext, while tuples_fetched is the number of tuples
89  * successfully fetched by heap_fetch under the control of bitmap indexscans.
90  * For an index, tuples_returned is the number of index entries returned by
91  * the index AM, while tuples_fetched is the number of tuples successfully
92  * fetched by heap_fetch under the control of simple indexscans for this index.
93  *
94  * tuples_inserted/updated/deleted/hot_updated count attempted actions,
95  * regardless of whether the transaction committed.  delta_live_tuples,
96  * delta_dead_tuples, and changed_tuples are set depending on commit or abort.
97  * Note that delta_live_tuples and delta_dead_tuples can be negative!
98  * ----------
99  */
100 typedef struct PgStat_TableCounts
101 {
102 	PgStat_Counter t_numscans;
103 
104 	PgStat_Counter t_tuples_returned;
105 	PgStat_Counter t_tuples_fetched;
106 
107 	PgStat_Counter t_tuples_inserted;
108 	PgStat_Counter t_tuples_updated;
109 	PgStat_Counter t_tuples_deleted;
110 	PgStat_Counter t_tuples_hot_updated;
111 	bool		t_truncated;
112 
113 	PgStat_Counter t_delta_live_tuples;
114 	PgStat_Counter t_delta_dead_tuples;
115 	PgStat_Counter t_changed_tuples;
116 
117 	PgStat_Counter t_blocks_fetched;
118 	PgStat_Counter t_blocks_hit;
119 } PgStat_TableCounts;
120 
121 /* Possible targets for resetting cluster-wide shared values */
122 typedef enum PgStat_Shared_Reset_Target
123 {
124 	RESET_ARCHIVER,
125 	RESET_BGWRITER
126 } PgStat_Shared_Reset_Target;
127 
128 /* Possible object types for resetting single counters */
129 typedef enum PgStat_Single_Reset_Type
130 {
131 	RESET_TABLE,
132 	RESET_FUNCTION
133 } PgStat_Single_Reset_Type;
134 
135 /* ------------------------------------------------------------
136  * Structures kept in backend local memory while accumulating counts
137  * ------------------------------------------------------------
138  */
139 
140 
141 /* ----------
142  * PgStat_TableStatus			Per-table status within a backend
143  *
144  * Many of the event counters are nontransactional, ie, we count events
145  * in committed and aborted transactions alike.  For these, we just count
146  * directly in the PgStat_TableStatus.  However, delta_live_tuples,
147  * delta_dead_tuples, and changed_tuples must be derived from event counts
148  * with awareness of whether the transaction or subtransaction committed or
149  * aborted.  Hence, we also keep a stack of per-(sub)transaction status
150  * records for every table modified in the current transaction.  At commit
151  * or abort, we propagate tuples_inserted/updated/deleted up to the
152  * parent subtransaction level, or out to the parent PgStat_TableStatus,
153  * as appropriate.
154  * ----------
155  */
156 typedef struct PgStat_TableStatus
157 {
158 	Oid			t_id;			/* table's OID */
159 	bool		t_shared;		/* is it a shared catalog? */
160 	struct PgStat_TableXactStatus *trans;	/* lowest subxact's counts */
161 	PgStat_TableCounts t_counts;	/* event counts to be sent */
162 } PgStat_TableStatus;
163 
164 /* ----------
165  * PgStat_TableXactStatus		Per-table, per-subtransaction status
166  * ----------
167  */
168 typedef struct PgStat_TableXactStatus
169 {
170 	PgStat_Counter tuples_inserted; /* tuples inserted in (sub)xact */
171 	PgStat_Counter tuples_updated;	/* tuples updated in (sub)xact */
172 	PgStat_Counter tuples_deleted;	/* tuples deleted in (sub)xact */
173 	bool		truncated;		/* relation truncated in this (sub)xact */
174 	PgStat_Counter inserted_pre_trunc;	/* tuples inserted prior to truncate */
175 	PgStat_Counter updated_pre_trunc;	/* tuples updated prior to truncate */
176 	PgStat_Counter deleted_pre_trunc;	/* tuples deleted prior to truncate */
177 	int			nest_level;		/* subtransaction nest level */
178 	/* links to other structs for same relation: */
179 	struct PgStat_TableXactStatus *upper;	/* next higher subxact if any */
180 	PgStat_TableStatus *parent; /* per-table status */
181 	/* structs of same subxact level are linked here: */
182 	struct PgStat_TableXactStatus *next;	/* next of same subxact */
183 } PgStat_TableXactStatus;
184 
185 
186 /* ------------------------------------------------------------
187  * Message formats follow
188  * ------------------------------------------------------------
189  */
190 
191 
192 /* ----------
193  * PgStat_MsgHdr				The common message header
194  * ----------
195  */
196 typedef struct PgStat_MsgHdr
197 {
198 	StatMsgType m_type;
199 	int			m_size;
200 } PgStat_MsgHdr;
201 
202 /* ----------
203  * Space available in a message.  This will keep the UDP packets below 1K,
204  * which should fit unfragmented into the MTU of the loopback interface.
205  * (Larger values of PGSTAT_MAX_MSG_SIZE would work for that on most
206  * platforms, but we're being conservative here.)
207  * ----------
208  */
209 #define PGSTAT_MAX_MSG_SIZE 1000
210 #define PGSTAT_MSG_PAYLOAD	(PGSTAT_MAX_MSG_SIZE - sizeof(PgStat_MsgHdr))
211 
212 
213 /* ----------
214  * PgStat_MsgDummy				A dummy message, ignored by the collector
215  * ----------
216  */
217 typedef struct PgStat_MsgDummy
218 {
219 	PgStat_MsgHdr m_hdr;
220 } PgStat_MsgDummy;
221 
222 
223 /* ----------
224  * PgStat_MsgInquiry			Sent by a backend to ask the collector
225  *								to write the stats file(s).
226  *
227  * Ordinarily, an inquiry message prompts writing of the global stats file,
228  * the stats file for shared catalogs, and the stats file for the specified
229  * database.  If databaseid is InvalidOid, only the first two are written.
230  *
231  * New file(s) will be written only if the existing file has a timestamp
232  * older than the specified cutoff_time; this prevents duplicated effort
233  * when multiple requests arrive at nearly the same time, assuming that
234  * backends send requests with cutoff_times a little bit in the past.
235  *
236  * clock_time should be the requestor's current local time; the collector
237  * uses this to check for the system clock going backward, but it has no
238  * effect unless that occurs.  We assume clock_time >= cutoff_time, though.
239  * ----------
240  */
241 
242 typedef struct PgStat_MsgInquiry
243 {
244 	PgStat_MsgHdr m_hdr;
245 	TimestampTz clock_time;		/* observed local clock time */
246 	TimestampTz cutoff_time;	/* minimum acceptable file timestamp */
247 	Oid			databaseid;		/* requested DB (InvalidOid => shared only) */
248 } PgStat_MsgInquiry;
249 
250 
251 /* ----------
252  * PgStat_TableEntry			Per-table info in a MsgTabstat
253  * ----------
254  */
255 typedef struct PgStat_TableEntry
256 {
257 	Oid			t_id;
258 	PgStat_TableCounts t_counts;
259 } PgStat_TableEntry;
260 
261 /* ----------
262  * PgStat_MsgTabstat			Sent by the backend to report table
263  *								and buffer access statistics.
264  * ----------
265  */
266 #define PGSTAT_NUM_TABENTRIES  \
267 	((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - 3 * sizeof(int) - 2 * sizeof(PgStat_Counter))	\
268 	 / sizeof(PgStat_TableEntry))
269 
270 typedef struct PgStat_MsgTabstat
271 {
272 	PgStat_MsgHdr m_hdr;
273 	Oid			m_databaseid;
274 	int			m_nentries;
275 	int			m_xact_commit;
276 	int			m_xact_rollback;
277 	PgStat_Counter m_block_read_time;	/* times in microseconds */
278 	PgStat_Counter m_block_write_time;
279 	PgStat_TableEntry m_entry[PGSTAT_NUM_TABENTRIES];
280 } PgStat_MsgTabstat;
281 
282 
283 /* ----------
284  * PgStat_MsgTabpurge			Sent by the backend to tell the collector
285  *								about dead tables.
286  * ----------
287  */
288 #define PGSTAT_NUM_TABPURGE  \
289 	((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - sizeof(int))  \
290 	 / sizeof(Oid))
291 
292 typedef struct PgStat_MsgTabpurge
293 {
294 	PgStat_MsgHdr m_hdr;
295 	Oid			m_databaseid;
296 	int			m_nentries;
297 	Oid			m_tableid[PGSTAT_NUM_TABPURGE];
298 } PgStat_MsgTabpurge;
299 
300 
301 /* ----------
302  * PgStat_MsgDropdb				Sent by the backend to tell the collector
303  *								about a dropped database
304  * ----------
305  */
306 typedef struct PgStat_MsgDropdb
307 {
308 	PgStat_MsgHdr m_hdr;
309 	Oid			m_databaseid;
310 } PgStat_MsgDropdb;
311 
312 
313 /* ----------
314  * PgStat_MsgResetcounter		Sent by the backend to tell the collector
315  *								to reset counters
316  * ----------
317  */
318 typedef struct PgStat_MsgResetcounter
319 {
320 	PgStat_MsgHdr m_hdr;
321 	Oid			m_databaseid;
322 } PgStat_MsgResetcounter;
323 
324 /* ----------
325  * PgStat_MsgResetsharedcounter Sent by the backend to tell the collector
326  *								to reset a shared counter
327  * ----------
328  */
329 typedef struct PgStat_MsgResetsharedcounter
330 {
331 	PgStat_MsgHdr m_hdr;
332 	PgStat_Shared_Reset_Target m_resettarget;
333 } PgStat_MsgResetsharedcounter;
334 
335 /* ----------
336  * PgStat_MsgResetsinglecounter Sent by the backend to tell the collector
337  *								to reset a single counter
338  * ----------
339  */
340 typedef struct PgStat_MsgResetsinglecounter
341 {
342 	PgStat_MsgHdr m_hdr;
343 	Oid			m_databaseid;
344 	PgStat_Single_Reset_Type m_resettype;
345 	Oid			m_objectid;
346 } PgStat_MsgResetsinglecounter;
347 
348 /* ----------
349  * PgStat_MsgResetslrucounter Sent by the backend to tell the collector
350  *								to reset a SLRU counter
351  * ----------
352  */
353 typedef struct PgStat_MsgResetslrucounter
354 {
355 	PgStat_MsgHdr m_hdr;
356 	int			m_index;
357 } PgStat_MsgResetslrucounter;
358 
359 /* ----------
360  * PgStat_MsgAutovacStart		Sent by the autovacuum daemon to signal
361  *								that a database is going to be processed
362  * ----------
363  */
364 typedef struct PgStat_MsgAutovacStart
365 {
366 	PgStat_MsgHdr m_hdr;
367 	Oid			m_databaseid;
368 	TimestampTz m_start_time;
369 } PgStat_MsgAutovacStart;
370 
371 
372 /* ----------
373  * PgStat_MsgVacuum				Sent by the backend or autovacuum daemon
374  *								after VACUUM
375  * ----------
376  */
377 typedef struct PgStat_MsgVacuum
378 {
379 	PgStat_MsgHdr m_hdr;
380 	Oid			m_databaseid;
381 	Oid			m_tableoid;
382 	bool		m_autovacuum;
383 	TimestampTz m_vacuumtime;
384 	PgStat_Counter m_live_tuples;
385 	PgStat_Counter m_dead_tuples;
386 } PgStat_MsgVacuum;
387 
388 
389 /* ----------
390  * PgStat_MsgAnalyze			Sent by the backend or autovacuum daemon
391  *								after ANALYZE
392  * ----------
393  */
394 typedef struct PgStat_MsgAnalyze
395 {
396 	PgStat_MsgHdr m_hdr;
397 	Oid			m_databaseid;
398 	Oid			m_tableoid;
399 	bool		m_autovacuum;
400 	bool		m_resetcounter;
401 	TimestampTz m_analyzetime;
402 	PgStat_Counter m_live_tuples;
403 	PgStat_Counter m_dead_tuples;
404 } PgStat_MsgAnalyze;
405 
406 
407 /* ----------
408  * PgStat_MsgArchiver			Sent by the archiver to update statistics.
409  * ----------
410  */
411 typedef struct PgStat_MsgArchiver
412 {
413 	PgStat_MsgHdr m_hdr;
414 	bool		m_failed;		/* Failed attempt */
415 	char		m_xlog[MAX_XFN_CHARS + 1];
416 	TimestampTz m_timestamp;
417 } PgStat_MsgArchiver;
418 
419 /* ----------
420  * PgStat_MsgBgWriter			Sent by the bgwriter to update statistics.
421  * ----------
422  */
423 typedef struct PgStat_MsgBgWriter
424 {
425 	PgStat_MsgHdr m_hdr;
426 
427 	PgStat_Counter m_timed_checkpoints;
428 	PgStat_Counter m_requested_checkpoints;
429 	PgStat_Counter m_buf_written_checkpoints;
430 	PgStat_Counter m_buf_written_clean;
431 	PgStat_Counter m_maxwritten_clean;
432 	PgStat_Counter m_buf_written_backend;
433 	PgStat_Counter m_buf_fsync_backend;
434 	PgStat_Counter m_buf_alloc;
435 	PgStat_Counter m_checkpoint_write_time; /* times in milliseconds */
436 	PgStat_Counter m_checkpoint_sync_time;
437 } PgStat_MsgBgWriter;
438 
439 /* ----------
440  * PgStat_MsgSLRU			Sent by a backend to update SLRU statistics.
441  * ----------
442  */
443 typedef struct PgStat_MsgSLRU
444 {
445 	PgStat_MsgHdr m_hdr;
446 	PgStat_Counter m_index;
447 	PgStat_Counter m_blocks_zeroed;
448 	PgStat_Counter m_blocks_hit;
449 	PgStat_Counter m_blocks_read;
450 	PgStat_Counter m_blocks_written;
451 	PgStat_Counter m_blocks_exists;
452 	PgStat_Counter m_flush;
453 	PgStat_Counter m_truncate;
454 } PgStat_MsgSLRU;
455 
456 /* ----------
457  * PgStat_MsgRecoveryConflict	Sent by the backend upon recovery conflict
458  * ----------
459  */
460 typedef struct PgStat_MsgRecoveryConflict
461 {
462 	PgStat_MsgHdr m_hdr;
463 
464 	Oid			m_databaseid;
465 	int			m_reason;
466 } PgStat_MsgRecoveryConflict;
467 
468 /* ----------
469  * PgStat_MsgTempFile	Sent by the backend upon creating a temp file
470  * ----------
471  */
472 typedef struct PgStat_MsgTempFile
473 {
474 	PgStat_MsgHdr m_hdr;
475 
476 	Oid			m_databaseid;
477 	size_t		m_filesize;
478 } PgStat_MsgTempFile;
479 
480 /* ----------
481  * PgStat_FunctionCounts	The actual per-function counts kept by a backend
482  *
483  * This struct should contain only actual event counters, because we memcmp
484  * it against zeroes to detect whether there are any counts to transmit.
485  *
486  * Note that the time counters are in instr_time format here.  We convert to
487  * microseconds in PgStat_Counter format when transmitting to the collector.
488  * ----------
489  */
490 typedef struct PgStat_FunctionCounts
491 {
492 	PgStat_Counter f_numcalls;
493 	instr_time	f_total_time;
494 	instr_time	f_self_time;
495 } PgStat_FunctionCounts;
496 
497 /* ----------
498  * PgStat_BackendFunctionEntry	Entry in backend's per-function hash table
499  * ----------
500  */
501 typedef struct PgStat_BackendFunctionEntry
502 {
503 	Oid			f_id;
504 	PgStat_FunctionCounts f_counts;
505 } PgStat_BackendFunctionEntry;
506 
507 /* ----------
508  * PgStat_FunctionEntry			Per-function info in a MsgFuncstat
509  * ----------
510  */
511 typedef struct PgStat_FunctionEntry
512 {
513 	Oid			f_id;
514 	PgStat_Counter f_numcalls;
515 	PgStat_Counter f_total_time;	/* times in microseconds */
516 	PgStat_Counter f_self_time;
517 } PgStat_FunctionEntry;
518 
519 /* ----------
520  * PgStat_MsgFuncstat			Sent by the backend to report function
521  *								usage statistics.
522  * ----------
523  */
524 #define PGSTAT_NUM_FUNCENTRIES	\
525 	((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - sizeof(int))  \
526 	 / sizeof(PgStat_FunctionEntry))
527 
528 typedef struct PgStat_MsgFuncstat
529 {
530 	PgStat_MsgHdr m_hdr;
531 	Oid			m_databaseid;
532 	int			m_nentries;
533 	PgStat_FunctionEntry m_entry[PGSTAT_NUM_FUNCENTRIES];
534 } PgStat_MsgFuncstat;
535 
536 /* ----------
537  * PgStat_MsgFuncpurge			Sent by the backend to tell the collector
538  *								about dead functions.
539  * ----------
540  */
541 #define PGSTAT_NUM_FUNCPURGE  \
542 	((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - sizeof(int))  \
543 	 / sizeof(Oid))
544 
545 typedef struct PgStat_MsgFuncpurge
546 {
547 	PgStat_MsgHdr m_hdr;
548 	Oid			m_databaseid;
549 	int			m_nentries;
550 	Oid			m_functionid[PGSTAT_NUM_FUNCPURGE];
551 } PgStat_MsgFuncpurge;
552 
553 /* ----------
554  * PgStat_MsgDeadlock			Sent by the backend to tell the collector
555  *								about a deadlock that occurred.
556  * ----------
557  */
558 typedef struct PgStat_MsgDeadlock
559 {
560 	PgStat_MsgHdr m_hdr;
561 	Oid			m_databaseid;
562 } PgStat_MsgDeadlock;
563 
564 /* ----------
565  * PgStat_MsgChecksumFailure	Sent by the backend to tell the collector
566  *								about checksum failures noticed.
567  * ----------
568  */
569 typedef struct PgStat_MsgChecksumFailure
570 {
571 	PgStat_MsgHdr m_hdr;
572 	Oid			m_databaseid;
573 	int			m_failurecount;
574 	TimestampTz m_failure_time;
575 } PgStat_MsgChecksumFailure;
576 
577 
578 /* ----------
579  * PgStat_Msg					Union over all possible messages.
580  * ----------
581  */
582 typedef union PgStat_Msg
583 {
584 	PgStat_MsgHdr msg_hdr;
585 	PgStat_MsgDummy msg_dummy;
586 	PgStat_MsgInquiry msg_inquiry;
587 	PgStat_MsgTabstat msg_tabstat;
588 	PgStat_MsgTabpurge msg_tabpurge;
589 	PgStat_MsgDropdb msg_dropdb;
590 	PgStat_MsgResetcounter msg_resetcounter;
591 	PgStat_MsgResetsharedcounter msg_resetsharedcounter;
592 	PgStat_MsgResetsinglecounter msg_resetsinglecounter;
593 	PgStat_MsgResetslrucounter msg_resetslrucounter;
594 	PgStat_MsgAutovacStart msg_autovacuum_start;
595 	PgStat_MsgVacuum msg_vacuum;
596 	PgStat_MsgAnalyze msg_analyze;
597 	PgStat_MsgArchiver msg_archiver;
598 	PgStat_MsgBgWriter msg_bgwriter;
599 	PgStat_MsgSLRU msg_slru;
600 	PgStat_MsgFuncstat msg_funcstat;
601 	PgStat_MsgFuncpurge msg_funcpurge;
602 	PgStat_MsgRecoveryConflict msg_recoveryconflict;
603 	PgStat_MsgDeadlock msg_deadlock;
604 	PgStat_MsgTempFile msg_tempfile;
605 	PgStat_MsgChecksumFailure msg_checksumfailure;
606 } PgStat_Msg;
607 
608 
609 /* ------------------------------------------------------------
610  * Statistic collector data structures follow
611  *
612  * PGSTAT_FILE_FORMAT_ID should be changed whenever any of these
613  * data structures change.
614  * ------------------------------------------------------------
615  */
616 
617 #define PGSTAT_FILE_FORMAT_ID	0x01A5BC9D
618 
619 /* ----------
620  * PgStat_StatDBEntry			The collector's data per database
621  * ----------
622  */
623 typedef struct PgStat_StatDBEntry
624 {
625 	Oid			databaseid;
626 	PgStat_Counter n_xact_commit;
627 	PgStat_Counter n_xact_rollback;
628 	PgStat_Counter n_blocks_fetched;
629 	PgStat_Counter n_blocks_hit;
630 	PgStat_Counter n_tuples_returned;
631 	PgStat_Counter n_tuples_fetched;
632 	PgStat_Counter n_tuples_inserted;
633 	PgStat_Counter n_tuples_updated;
634 	PgStat_Counter n_tuples_deleted;
635 	TimestampTz last_autovac_time;
636 	PgStat_Counter n_conflict_tablespace;
637 	PgStat_Counter n_conflict_lock;
638 	PgStat_Counter n_conflict_snapshot;
639 	PgStat_Counter n_conflict_bufferpin;
640 	PgStat_Counter n_conflict_startup_deadlock;
641 	PgStat_Counter n_temp_files;
642 	PgStat_Counter n_temp_bytes;
643 	PgStat_Counter n_deadlocks;
644 	PgStat_Counter n_checksum_failures;
645 	TimestampTz last_checksum_failure;
646 	PgStat_Counter n_block_read_time;	/* times in microseconds */
647 	PgStat_Counter n_block_write_time;
648 
649 	TimestampTz stat_reset_timestamp;
650 	TimestampTz stats_timestamp;	/* time of db stats file update */
651 
652 	/*
653 	 * tables and functions must be last in the struct, because we don't write
654 	 * the pointers out to the stats file.
655 	 */
656 	HTAB	   *tables;
657 	HTAB	   *functions;
658 } PgStat_StatDBEntry;
659 
660 
661 /* ----------
662  * PgStat_StatTabEntry			The collector's data per table (or index)
663  * ----------
664  */
665 typedef struct PgStat_StatTabEntry
666 {
667 	Oid			tableid;
668 
669 	PgStat_Counter numscans;
670 
671 	PgStat_Counter tuples_returned;
672 	PgStat_Counter tuples_fetched;
673 
674 	PgStat_Counter tuples_inserted;
675 	PgStat_Counter tuples_updated;
676 	PgStat_Counter tuples_deleted;
677 	PgStat_Counter tuples_hot_updated;
678 
679 	PgStat_Counter n_live_tuples;
680 	PgStat_Counter n_dead_tuples;
681 	PgStat_Counter changes_since_analyze;
682 	PgStat_Counter inserts_since_vacuum;
683 
684 	PgStat_Counter blocks_fetched;
685 	PgStat_Counter blocks_hit;
686 
687 	TimestampTz vacuum_timestamp;	/* user initiated vacuum */
688 	PgStat_Counter vacuum_count;
689 	TimestampTz autovac_vacuum_timestamp;	/* autovacuum initiated */
690 	PgStat_Counter autovac_vacuum_count;
691 	TimestampTz analyze_timestamp;	/* user initiated */
692 	PgStat_Counter analyze_count;
693 	TimestampTz autovac_analyze_timestamp;	/* autovacuum initiated */
694 	PgStat_Counter autovac_analyze_count;
695 } PgStat_StatTabEntry;
696 
697 
698 /* ----------
699  * PgStat_StatFuncEntry			The collector's data per function
700  * ----------
701  */
702 typedef struct PgStat_StatFuncEntry
703 {
704 	Oid			functionid;
705 
706 	PgStat_Counter f_numcalls;
707 
708 	PgStat_Counter f_total_time;	/* times in microseconds */
709 	PgStat_Counter f_self_time;
710 } PgStat_StatFuncEntry;
711 
712 
713 /*
714  * Archiver statistics kept in the stats collector
715  */
716 typedef struct PgStat_ArchiverStats
717 {
718 	PgStat_Counter archived_count;	/* archival successes */
719 	char		last_archived_wal[MAX_XFN_CHARS + 1];	/* last WAL file
720 														 * archived */
721 	TimestampTz last_archived_timestamp;	/* last archival success time */
722 	PgStat_Counter failed_count;	/* failed archival attempts */
723 	char		last_failed_wal[MAX_XFN_CHARS + 1]; /* WAL file involved in
724 													 * last failure */
725 	TimestampTz last_failed_timestamp;	/* last archival failure time */
726 	TimestampTz stat_reset_timestamp;
727 } PgStat_ArchiverStats;
728 
729 /*
730  * Global statistics kept in the stats collector
731  */
732 typedef struct PgStat_GlobalStats
733 {
734 	TimestampTz stats_timestamp;	/* time of stats file update */
735 	PgStat_Counter timed_checkpoints;
736 	PgStat_Counter requested_checkpoints;
737 	PgStat_Counter checkpoint_write_time;	/* times in milliseconds */
738 	PgStat_Counter checkpoint_sync_time;
739 	PgStat_Counter buf_written_checkpoints;
740 	PgStat_Counter buf_written_clean;
741 	PgStat_Counter maxwritten_clean;
742 	PgStat_Counter buf_written_backend;
743 	PgStat_Counter buf_fsync_backend;
744 	PgStat_Counter buf_alloc;
745 	TimestampTz stat_reset_timestamp;
746 } PgStat_GlobalStats;
747 
748 /*
749  * SLRU statistics kept in the stats collector
750  */
751 typedef struct PgStat_SLRUStats
752 {
753 	PgStat_Counter blocks_zeroed;
754 	PgStat_Counter blocks_hit;
755 	PgStat_Counter blocks_read;
756 	PgStat_Counter blocks_written;
757 	PgStat_Counter blocks_exists;
758 	PgStat_Counter flush;
759 	PgStat_Counter truncate;
760 	TimestampTz stat_reset_timestamp;
761 } PgStat_SLRUStats;
762 
763 
764 /* ----------
765  * Backend states
766  * ----------
767  */
768 typedef enum BackendState
769 {
770 	STATE_UNDEFINED,
771 	STATE_IDLE,
772 	STATE_RUNNING,
773 	STATE_IDLEINTRANSACTION,
774 	STATE_FASTPATH,
775 	STATE_IDLEINTRANSACTION_ABORTED,
776 	STATE_DISABLED
777 } BackendState;
778 
779 
780 /* ----------
781  * Wait Classes
782  * ----------
783  */
784 #define PG_WAIT_LWLOCK				0x01000000U
785 #define PG_WAIT_LOCK				0x03000000U
786 #define PG_WAIT_BUFFER_PIN			0x04000000U
787 #define PG_WAIT_ACTIVITY			0x05000000U
788 #define PG_WAIT_CLIENT				0x06000000U
789 #define PG_WAIT_EXTENSION			0x07000000U
790 #define PG_WAIT_IPC					0x08000000U
791 #define PG_WAIT_TIMEOUT				0x09000000U
792 #define PG_WAIT_IO					0x0A000000U
793 
794 /* ----------
795  * Wait Events - Activity
796  *
797  * Use this category when a process is waiting because it has no work to do,
798  * unless the "Client" or "Timeout" category describes the situation better.
799  * Typically, this should only be used for background processes.
800  * ----------
801  */
802 typedef enum
803 {
804 	WAIT_EVENT_ARCHIVER_MAIN = PG_WAIT_ACTIVITY,
805 	WAIT_EVENT_AUTOVACUUM_MAIN,
806 	WAIT_EVENT_BGWRITER_HIBERNATE,
807 	WAIT_EVENT_BGWRITER_MAIN,
808 	WAIT_EVENT_CHECKPOINTER_MAIN,
809 	WAIT_EVENT_LOGICAL_APPLY_MAIN,
810 	WAIT_EVENT_LOGICAL_LAUNCHER_MAIN,
811 	WAIT_EVENT_PGSTAT_MAIN,
812 	WAIT_EVENT_RECOVERY_WAL_STREAM,
813 	WAIT_EVENT_SYSLOGGER_MAIN,
814 	WAIT_EVENT_WAL_RECEIVER_MAIN,
815 	WAIT_EVENT_WAL_SENDER_MAIN,
816 	WAIT_EVENT_WAL_WRITER_MAIN
817 } WaitEventActivity;
818 
819 /* ----------
820  * Wait Events - Client
821  *
822  * Use this category when a process is waiting to send data to or receive data
823  * from the frontend process to which it is connected.  This is never used for
824  * a background process, which has no client connection.
825  * ----------
826  */
827 typedef enum
828 {
829 	WAIT_EVENT_CLIENT_READ = PG_WAIT_CLIENT,
830 	WAIT_EVENT_CLIENT_WRITE,
831 	WAIT_EVENT_GSS_OPEN_SERVER,
832 	WAIT_EVENT_LIBPQWALRECEIVER_CONNECT,
833 	WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE,
834 	WAIT_EVENT_SSL_OPEN_SERVER,
835 	WAIT_EVENT_WAL_RECEIVER_WAIT_START,
836 	WAIT_EVENT_WAL_SENDER_WAIT_WAL,
837 	WAIT_EVENT_WAL_SENDER_WRITE_DATA,
838 } WaitEventClient;
839 
840 /* ----------
841  * Wait Events - IPC
842  *
843  * Use this category when a process cannot complete the work it is doing because
844  * it is waiting for a notification from another process.
845  * ----------
846  */
847 typedef enum
848 {
849 	WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE = PG_WAIT_IPC,
850 	WAIT_EVENT_BGWORKER_SHUTDOWN,
851 	WAIT_EVENT_BGWORKER_STARTUP,
852 	WAIT_EVENT_BTREE_PAGE,
853 	WAIT_EVENT_CHECKPOINT_DONE,
854 	WAIT_EVENT_CHECKPOINT_START,
855 	WAIT_EVENT_EXECUTE_GATHER,
856 	WAIT_EVENT_HASH_BATCH_ALLOCATE,
857 	WAIT_EVENT_HASH_BATCH_ELECT,
858 	WAIT_EVENT_HASH_BATCH_LOAD,
859 	WAIT_EVENT_HASH_BUILD_ALLOCATE,
860 	WAIT_EVENT_HASH_BUILD_ELECT,
861 	WAIT_EVENT_HASH_BUILD_HASH_INNER,
862 	WAIT_EVENT_HASH_BUILD_HASH_OUTER,
863 	WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE,
864 	WAIT_EVENT_HASH_GROW_BATCHES_DECIDE,
865 	WAIT_EVENT_HASH_GROW_BATCHES_ELECT,
866 	WAIT_EVENT_HASH_GROW_BATCHES_FINISH,
867 	WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION,
868 	WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE,
869 	WAIT_EVENT_HASH_GROW_BUCKETS_ELECT,
870 	WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT,
871 	WAIT_EVENT_LOGICAL_SYNC_DATA,
872 	WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE,
873 	WAIT_EVENT_MQ_INTERNAL,
874 	WAIT_EVENT_MQ_PUT_MESSAGE,
875 	WAIT_EVENT_MQ_RECEIVE,
876 	WAIT_EVENT_MQ_SEND,
877 	WAIT_EVENT_PARALLEL_BITMAP_SCAN,
878 	WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN,
879 	WAIT_EVENT_PARALLEL_FINISH,
880 	WAIT_EVENT_PROCARRAY_GROUP_UPDATE,
881 	WAIT_EVENT_PROC_SIGNAL_BARRIER,
882 	WAIT_EVENT_PROMOTE,
883 	WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT,
884 	WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE,
885 	WAIT_EVENT_RECOVERY_PAUSE,
886 	WAIT_EVENT_REPLICATION_ORIGIN_DROP,
887 	WAIT_EVENT_REPLICATION_SLOT_DROP,
888 	WAIT_EVENT_SAFE_SNAPSHOT,
889 	WAIT_EVENT_SYNC_REP,
890 	WAIT_EVENT_XACT_GROUP_UPDATE
891 } WaitEventIPC;
892 
893 /* ----------
894  * Wait Events - Timeout
895  *
896  * Use this category when a process is waiting for a timeout to expire.
897  * ----------
898  */
899 typedef enum
900 {
901 	WAIT_EVENT_BASE_BACKUP_THROTTLE = PG_WAIT_TIMEOUT,
902 	WAIT_EVENT_PG_SLEEP,
903 	WAIT_EVENT_RECOVERY_APPLY_DELAY,
904 	WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL,
905 	WAIT_EVENT_VACUUM_DELAY
906 } WaitEventTimeout;
907 
908 /* ----------
909  * Wait Events - IO
910  *
911  * Use this category when a process is waiting for a IO.
912  * ----------
913  */
914 typedef enum
915 {
916 	WAIT_EVENT_BUFFILE_READ = PG_WAIT_IO,
917 	WAIT_EVENT_BUFFILE_WRITE,
918 	WAIT_EVENT_CONTROL_FILE_READ,
919 	WAIT_EVENT_CONTROL_FILE_SYNC,
920 	WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE,
921 	WAIT_EVENT_CONTROL_FILE_WRITE,
922 	WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE,
923 	WAIT_EVENT_COPY_FILE_READ,
924 	WAIT_EVENT_COPY_FILE_WRITE,
925 	WAIT_EVENT_DATA_FILE_EXTEND,
926 	WAIT_EVENT_DATA_FILE_FLUSH,
927 	WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC,
928 	WAIT_EVENT_DATA_FILE_PREFETCH,
929 	WAIT_EVENT_DATA_FILE_READ,
930 	WAIT_EVENT_DATA_FILE_SYNC,
931 	WAIT_EVENT_DATA_FILE_TRUNCATE,
932 	WAIT_EVENT_DATA_FILE_WRITE,
933 	WAIT_EVENT_DSM_FILL_ZERO_WRITE,
934 	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ,
935 	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC,
936 	WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE,
937 	WAIT_EVENT_LOCK_FILE_CREATE_READ,
938 	WAIT_EVENT_LOCK_FILE_CREATE_SYNC,
939 	WAIT_EVENT_LOCK_FILE_CREATE_WRITE,
940 	WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ,
941 	WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC,
942 	WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC,
943 	WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE,
944 	WAIT_EVENT_LOGICAL_REWRITE_SYNC,
945 	WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE,
946 	WAIT_EVENT_LOGICAL_REWRITE_WRITE,
947 	WAIT_EVENT_RELATION_MAP_READ,
948 	WAIT_EVENT_RELATION_MAP_SYNC,
949 	WAIT_EVENT_RELATION_MAP_WRITE,
950 	WAIT_EVENT_REORDER_BUFFER_READ,
951 	WAIT_EVENT_REORDER_BUFFER_WRITE,
952 	WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ,
953 	WAIT_EVENT_REPLICATION_SLOT_READ,
954 	WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC,
955 	WAIT_EVENT_REPLICATION_SLOT_SYNC,
956 	WAIT_EVENT_REPLICATION_SLOT_WRITE,
957 	WAIT_EVENT_SLRU_FLUSH_SYNC,
958 	WAIT_EVENT_SLRU_READ,
959 	WAIT_EVENT_SLRU_SYNC,
960 	WAIT_EVENT_SLRU_WRITE,
961 	WAIT_EVENT_SNAPBUILD_READ,
962 	WAIT_EVENT_SNAPBUILD_SYNC,
963 	WAIT_EVENT_SNAPBUILD_WRITE,
964 	WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC,
965 	WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE,
966 	WAIT_EVENT_TIMELINE_HISTORY_READ,
967 	WAIT_EVENT_TIMELINE_HISTORY_SYNC,
968 	WAIT_EVENT_TIMELINE_HISTORY_WRITE,
969 	WAIT_EVENT_TWOPHASE_FILE_READ,
970 	WAIT_EVENT_TWOPHASE_FILE_SYNC,
971 	WAIT_EVENT_TWOPHASE_FILE_WRITE,
972 	WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ,
973 	WAIT_EVENT_WAL_BOOTSTRAP_SYNC,
974 	WAIT_EVENT_WAL_BOOTSTRAP_WRITE,
975 	WAIT_EVENT_WAL_COPY_READ,
976 	WAIT_EVENT_WAL_COPY_SYNC,
977 	WAIT_EVENT_WAL_COPY_WRITE,
978 	WAIT_EVENT_WAL_INIT_SYNC,
979 	WAIT_EVENT_WAL_INIT_WRITE,
980 	WAIT_EVENT_WAL_READ,
981 	WAIT_EVENT_WAL_SYNC,
982 	WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN,
983 	WAIT_EVENT_WAL_WRITE
984 } WaitEventIO;
985 
986 /* ----------
987  * Command type for progress reporting purposes
988  * ----------
989  */
990 typedef enum ProgressCommandType
991 {
992 	PROGRESS_COMMAND_INVALID,
993 	PROGRESS_COMMAND_VACUUM,
994 	PROGRESS_COMMAND_ANALYZE,
995 	PROGRESS_COMMAND_CLUSTER,
996 	PROGRESS_COMMAND_CREATE_INDEX,
997 	PROGRESS_COMMAND_BASEBACKUP
998 } ProgressCommandType;
999 
1000 #define PGSTAT_NUM_PROGRESS_PARAM	20
1001 
1002 /* ----------
1003  * Shared-memory data structures
1004  * ----------
1005  */
1006 
1007 
1008 /*
1009  * PgBackendSSLStatus
1010  *
1011  * For each backend, we keep the SSL status in a separate struct, that
1012  * is only filled in if SSL is enabled.
1013  *
1014  * All char arrays must be null-terminated.
1015  */
1016 typedef struct PgBackendSSLStatus
1017 {
1018 	/* Information about SSL connection */
1019 	int			ssl_bits;
1020 	bool		ssl_compression;
1021 	char		ssl_version[NAMEDATALEN];
1022 	char		ssl_cipher[NAMEDATALEN];
1023 	char		ssl_client_dn[NAMEDATALEN];
1024 
1025 	/*
1026 	 * serial number is max "20 octets" per RFC 5280, so this size should be
1027 	 * fine
1028 	 */
1029 	char		ssl_client_serial[NAMEDATALEN];
1030 
1031 	char		ssl_issuer_dn[NAMEDATALEN];
1032 } PgBackendSSLStatus;
1033 
1034 /*
1035  * PgBackendGSSStatus
1036  *
1037  * For each backend, we keep the GSS status in a separate struct, that
1038  * is only filled in if GSS is enabled.
1039  *
1040  * All char arrays must be null-terminated.
1041  */
1042 typedef struct PgBackendGSSStatus
1043 {
1044 	/* Information about GSSAPI connection */
1045 	char		gss_princ[NAMEDATALEN]; /* GSSAPI Principal used to auth */
1046 	bool		gss_auth;		/* If GSSAPI authentication was used */
1047 	bool		gss_enc;		/* If encryption is being used */
1048 
1049 } PgBackendGSSStatus;
1050 
1051 
1052 /* ----------
1053  * PgBackendStatus
1054  *
1055  * Each live backend maintains a PgBackendStatus struct in shared memory
1056  * showing its current activity.  (The structs are allocated according to
1057  * BackendId, but that is not critical.)  Note that the collector process
1058  * has no involvement in, or even access to, these structs.
1059  *
1060  * Each auxiliary process also maintains a PgBackendStatus struct in shared
1061  * memory.
1062  * ----------
1063  */
1064 typedef struct PgBackendStatus
1065 {
1066 	/*
1067 	 * To avoid locking overhead, we use the following protocol: a backend
1068 	 * increments st_changecount before modifying its entry, and again after
1069 	 * finishing a modification.  A would-be reader should note the value of
1070 	 * st_changecount, copy the entry into private memory, then check
1071 	 * st_changecount again.  If the value hasn't changed, and if it's even,
1072 	 * the copy is valid; otherwise start over.  This makes updates cheap
1073 	 * while reads are potentially expensive, but that's the tradeoff we want.
1074 	 *
1075 	 * The above protocol needs memory barriers to ensure that the apparent
1076 	 * order of execution is as it desires.  Otherwise, for example, the CPU
1077 	 * might rearrange the code so that st_changecount is incremented twice
1078 	 * before the modification on a machine with weak memory ordering.  Hence,
1079 	 * use the macros defined below for manipulating st_changecount, rather
1080 	 * than touching it directly.
1081 	 */
1082 	int			st_changecount;
1083 
1084 	/* The entry is valid iff st_procpid > 0, unused if st_procpid == 0 */
1085 	int			st_procpid;
1086 
1087 	/* Type of backends */
1088 	BackendType st_backendType;
1089 
1090 	/* Times when current backend, transaction, and activity started */
1091 	TimestampTz st_proc_start_timestamp;
1092 	TimestampTz st_xact_start_timestamp;
1093 	TimestampTz st_activity_start_timestamp;
1094 	TimestampTz st_state_start_timestamp;
1095 
1096 	/* Database OID, owning user's OID, connection client address */
1097 	Oid			st_databaseid;
1098 	Oid			st_userid;
1099 	SockAddr	st_clientaddr;
1100 	char	   *st_clienthostname;	/* MUST be null-terminated */
1101 
1102 	/* Information about SSL connection */
1103 	bool		st_ssl;
1104 	PgBackendSSLStatus *st_sslstatus;
1105 
1106 	/* Information about GSSAPI connection */
1107 	bool		st_gss;
1108 	PgBackendGSSStatus *st_gssstatus;
1109 
1110 	/* current state */
1111 	BackendState st_state;
1112 
1113 	/* application name; MUST be null-terminated */
1114 	char	   *st_appname;
1115 
1116 	/*
1117 	 * Current command string; MUST be null-terminated. Note that this string
1118 	 * possibly is truncated in the middle of a multi-byte character. As
1119 	 * activity strings are stored more frequently than read, that allows to
1120 	 * move the cost of correct truncation to the display side. Use
1121 	 * pgstat_clip_activity() to truncate correctly.
1122 	 */
1123 	char	   *st_activity_raw;
1124 
1125 	/*
1126 	 * Command progress reporting.  Any command which wishes can advertise
1127 	 * that it is running by setting st_progress_command,
1128 	 * st_progress_command_target, and st_progress_param[].
1129 	 * st_progress_command_target should be the OID of the relation which the
1130 	 * command targets (we assume there's just one, as this is meant for
1131 	 * utility commands), but the meaning of each element in the
1132 	 * st_progress_param array is command-specific.
1133 	 */
1134 	ProgressCommandType st_progress_command;
1135 	Oid			st_progress_command_target;
1136 	int64		st_progress_param[PGSTAT_NUM_PROGRESS_PARAM];
1137 } PgBackendStatus;
1138 
1139 /*
1140  * Macros to load and store st_changecount with appropriate memory barriers.
1141  *
1142  * Use PGSTAT_BEGIN_WRITE_ACTIVITY() before, and PGSTAT_END_WRITE_ACTIVITY()
1143  * after, modifying the current process's PgBackendStatus data.  Note that,
1144  * since there is no mechanism for cleaning up st_changecount after an error,
1145  * THESE MACROS FORM A CRITICAL SECTION.  Any error between them will be
1146  * promoted to PANIC, causing a database restart to clean up shared memory!
1147  * Hence, keep the critical section as short and straight-line as possible.
1148  * Aside from being safer, that minimizes the window in which readers will
1149  * have to loop.
1150  *
1151  * Reader logic should follow this sketch:
1152  *
1153  *		for (;;)
1154  *		{
1155  *			int before_ct, after_ct;
1156  *
1157  *			pgstat_begin_read_activity(beentry, before_ct);
1158  *			... copy beentry data to local memory ...
1159  *			pgstat_end_read_activity(beentry, after_ct);
1160  *			if (pgstat_read_activity_complete(before_ct, after_ct))
1161  *				break;
1162  *			CHECK_FOR_INTERRUPTS();
1163  *		}
1164  *
1165  * For extra safety, we generally use volatile beentry pointers, although
1166  * the memory barriers should theoretically be sufficient.
1167  */
1168 #define PGSTAT_BEGIN_WRITE_ACTIVITY(beentry) \
1169 	do { \
1170 		START_CRIT_SECTION(); \
1171 		(beentry)->st_changecount++; \
1172 		pg_write_barrier(); \
1173 	} while (0)
1174 
1175 #define PGSTAT_END_WRITE_ACTIVITY(beentry) \
1176 	do { \
1177 		pg_write_barrier(); \
1178 		(beentry)->st_changecount++; \
1179 		Assert(((beentry)->st_changecount & 1) == 0); \
1180 		END_CRIT_SECTION(); \
1181 	} while (0)
1182 
1183 #define pgstat_begin_read_activity(beentry, before_changecount) \
1184 	do { \
1185 		(before_changecount) = (beentry)->st_changecount; \
1186 		pg_read_barrier(); \
1187 	} while (0)
1188 
1189 #define pgstat_end_read_activity(beentry, after_changecount) \
1190 	do { \
1191 		pg_read_barrier(); \
1192 		(after_changecount) = (beentry)->st_changecount; \
1193 	} while (0)
1194 
1195 #define pgstat_read_activity_complete(before_changecount, after_changecount) \
1196 	((before_changecount) == (after_changecount) && \
1197 	 ((before_changecount) & 1) == 0)
1198 
1199 
1200 /* ----------
1201  * LocalPgBackendStatus
1202  *
1203  * When we build the backend status array, we use LocalPgBackendStatus to be
1204  * able to add new values to the struct when needed without adding new fields
1205  * to the shared memory. It contains the backend status as a first member.
1206  * ----------
1207  */
1208 typedef struct LocalPgBackendStatus
1209 {
1210 	/*
1211 	 * Local version of the backend status entry.
1212 	 */
1213 	PgBackendStatus backendStatus;
1214 
1215 	/*
1216 	 * The xid of the current transaction if available, InvalidTransactionId
1217 	 * if not.
1218 	 */
1219 	TransactionId backend_xid;
1220 
1221 	/*
1222 	 * The xmin of the current session if available, InvalidTransactionId if
1223 	 * not.
1224 	 */
1225 	TransactionId backend_xmin;
1226 } LocalPgBackendStatus;
1227 
1228 /*
1229  * Working state needed to accumulate per-function-call timing statistics.
1230  */
1231 typedef struct PgStat_FunctionCallUsage
1232 {
1233 	/* Link to function's hashtable entry (must still be there at exit!) */
1234 	/* NULL means we are not tracking the current function call */
1235 	PgStat_FunctionCounts *fs;
1236 	/* Total time previously charged to function, as of function start */
1237 	instr_time	save_f_total_time;
1238 	/* Backend-wide total time as of function start */
1239 	instr_time	save_total;
1240 	/* system clock as of function start */
1241 	instr_time	f_start;
1242 } PgStat_FunctionCallUsage;
1243 
1244 
1245 /* ----------
1246  * GUC parameters
1247  * ----------
1248  */
1249 extern PGDLLIMPORT bool pgstat_track_activities;
1250 extern PGDLLIMPORT bool pgstat_track_counts;
1251 extern PGDLLIMPORT int pgstat_track_functions;
1252 extern PGDLLIMPORT int pgstat_track_activity_query_size;
1253 extern char *pgstat_stat_directory;
1254 extern char *pgstat_stat_tmpname;
1255 extern char *pgstat_stat_filename;
1256 
1257 /*
1258  * BgWriter statistics counters are updated directly by bgwriter and bufmgr
1259  */
1260 extern PgStat_MsgBgWriter BgWriterStats;
1261 
1262 /*
1263  * Updated by pgstat_count_buffer_*_time macros
1264  */
1265 extern PgStat_Counter pgStatBlockReadTime;
1266 extern PgStat_Counter pgStatBlockWriteTime;
1267 
1268 /* ----------
1269  * Functions called from postmaster
1270  * ----------
1271  */
1272 extern Size BackendStatusShmemSize(void);
1273 extern void CreateSharedBackendStatus(void);
1274 
1275 extern void pgstat_init(void);
1276 extern int	pgstat_start(void);
1277 extern void pgstat_reset_all(void);
1278 extern void allow_immediate_pgstat_restart(void);
1279 
1280 #ifdef EXEC_BACKEND
1281 extern void PgstatCollectorMain(int argc, char *argv[]) pg_attribute_noreturn();
1282 #endif
1283 
1284 
1285 /* ----------
1286  * Functions called from backends
1287  * ----------
1288  */
1289 extern void pgstat_ping(void);
1290 
1291 extern void pgstat_report_stat(bool force);
1292 extern void pgstat_vacuum_stat(void);
1293 extern void pgstat_drop_database(Oid databaseid);
1294 
1295 extern void pgstat_clear_snapshot(void);
1296 extern void pgstat_reset_counters(void);
1297 extern void pgstat_reset_shared_counters(const char *);
1298 extern void pgstat_reset_single_counter(Oid objectid, PgStat_Single_Reset_Type type);
1299 extern void pgstat_reset_slru_counter(const char *);
1300 
1301 extern void pgstat_report_autovac(Oid dboid);
1302 extern void pgstat_report_vacuum(Oid tableoid, bool shared,
1303 								 PgStat_Counter livetuples, PgStat_Counter deadtuples);
1304 extern void pgstat_report_analyze(Relation rel,
1305 								  PgStat_Counter livetuples, PgStat_Counter deadtuples,
1306 								  bool resetcounter);
1307 
1308 extern void pgstat_report_recovery_conflict(int reason);
1309 extern void pgstat_report_deadlock(void);
1310 extern void pgstat_report_checksum_failures_in_db(Oid dboid, int failurecount);
1311 extern void pgstat_report_checksum_failure(void);
1312 
1313 extern void pgstat_initialize(void);
1314 extern void pgstat_bestart(void);
1315 
1316 extern void pgstat_report_activity(BackendState state, const char *cmd_str);
1317 extern void pgstat_report_tempfile(size_t filesize);
1318 extern void pgstat_report_appname(const char *appname);
1319 extern void pgstat_report_xact_timestamp(TimestampTz tstamp);
1320 extern const char *pgstat_get_wait_event(uint32 wait_event_info);
1321 extern const char *pgstat_get_wait_event_type(uint32 wait_event_info);
1322 extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser);
1323 extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer,
1324 													   int buflen);
1325 
1326 extern void pgstat_progress_start_command(ProgressCommandType cmdtype,
1327 										  Oid relid);
1328 extern void pgstat_progress_update_param(int index, int64 val);
1329 extern void pgstat_progress_update_multi_param(int nparam, const int *index,
1330 											   const int64 *val);
1331 extern void pgstat_progress_end_command(void);
1332 
1333 extern PgStat_TableStatus *find_tabstat_entry(Oid rel_id);
1334 extern PgStat_BackendFunctionEntry *find_funcstat_entry(Oid func_id);
1335 
1336 extern void pgstat_initstats(Relation rel);
1337 
1338 extern char *pgstat_clip_activity(const char *raw_activity);
1339 
1340 /* ----------
1341  * pgstat_report_wait_start() -
1342  *
1343  *	Called from places where server process needs to wait.  This is called
1344  *	to report wait event information.  The wait information is stored
1345  *	as 4-bytes where first byte represents the wait event class (type of
1346  *	wait, for different types of wait, refer WaitClass) and the next
1347  *	3-bytes represent the actual wait event.  Currently 2-bytes are used
1348  *	for wait event which is sufficient for current usage, 1-byte is
1349  *	reserved for future usage.
1350  *
1351  * NB: this *must* be able to survive being called before MyProc has been
1352  * initialized.
1353  * ----------
1354  */
1355 static inline void
pgstat_report_wait_start(uint32 wait_event_info)1356 pgstat_report_wait_start(uint32 wait_event_info)
1357 {
1358 	volatile PGPROC *proc = MyProc;
1359 
1360 	if (!pgstat_track_activities || !proc)
1361 		return;
1362 
1363 	/*
1364 	 * Since this is a four-byte field which is always read and written as
1365 	 * four-bytes, updates are atomic.
1366 	 */
1367 	proc->wait_event_info = wait_event_info;
1368 }
1369 
1370 /* ----------
1371  * pgstat_report_wait_end() -
1372  *
1373  *	Called to report end of a wait.
1374  *
1375  * NB: this *must* be able to survive being called before MyProc has been
1376  * initialized.
1377  * ----------
1378  */
1379 static inline void
pgstat_report_wait_end(void)1380 pgstat_report_wait_end(void)
1381 {
1382 	volatile PGPROC *proc = MyProc;
1383 
1384 	if (!pgstat_track_activities || !proc)
1385 		return;
1386 
1387 	/*
1388 	 * Since this is a four-byte field which is always read and written as
1389 	 * four-bytes, updates are atomic.
1390 	 */
1391 	proc->wait_event_info = 0;
1392 }
1393 
1394 /* nontransactional event counts are simple enough to inline */
1395 
1396 #define pgstat_count_heap_scan(rel)									\
1397 	do {															\
1398 		if ((rel)->pgstat_info != NULL)								\
1399 			(rel)->pgstat_info->t_counts.t_numscans++;				\
1400 	} while (0)
1401 #define pgstat_count_heap_getnext(rel)								\
1402 	do {															\
1403 		if ((rel)->pgstat_info != NULL)								\
1404 			(rel)->pgstat_info->t_counts.t_tuples_returned++;		\
1405 	} while (0)
1406 #define pgstat_count_heap_fetch(rel)								\
1407 	do {															\
1408 		if ((rel)->pgstat_info != NULL)								\
1409 			(rel)->pgstat_info->t_counts.t_tuples_fetched++;		\
1410 	} while (0)
1411 #define pgstat_count_index_scan(rel)								\
1412 	do {															\
1413 		if ((rel)->pgstat_info != NULL)								\
1414 			(rel)->pgstat_info->t_counts.t_numscans++;				\
1415 	} while (0)
1416 #define pgstat_count_index_tuples(rel, n)							\
1417 	do {															\
1418 		if ((rel)->pgstat_info != NULL)								\
1419 			(rel)->pgstat_info->t_counts.t_tuples_returned += (n);	\
1420 	} while (0)
1421 #define pgstat_count_buffer_read(rel)								\
1422 	do {															\
1423 		if ((rel)->pgstat_info != NULL)								\
1424 			(rel)->pgstat_info->t_counts.t_blocks_fetched++;		\
1425 	} while (0)
1426 #define pgstat_count_buffer_hit(rel)								\
1427 	do {															\
1428 		if ((rel)->pgstat_info != NULL)								\
1429 			(rel)->pgstat_info->t_counts.t_blocks_hit++;			\
1430 	} while (0)
1431 #define pgstat_count_buffer_read_time(n)							\
1432 	(pgStatBlockReadTime += (n))
1433 #define pgstat_count_buffer_write_time(n)							\
1434 	(pgStatBlockWriteTime += (n))
1435 
1436 extern void pgstat_count_heap_insert(Relation rel, PgStat_Counter n);
1437 extern void pgstat_count_heap_update(Relation rel, bool hot);
1438 extern void pgstat_count_heap_delete(Relation rel);
1439 extern void pgstat_count_truncate(Relation rel);
1440 extern void pgstat_update_heap_dead_tuples(Relation rel, int delta);
1441 
1442 struct FunctionCallInfoBaseData;
1443 extern void pgstat_init_function_usage(struct FunctionCallInfoBaseData *fcinfo,
1444 									   PgStat_FunctionCallUsage *fcu);
1445 extern void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu,
1446 									  bool finalize);
1447 
1448 extern void AtEOXact_PgStat(bool isCommit, bool parallel);
1449 extern void AtEOSubXact_PgStat(bool isCommit, int nestDepth);
1450 
1451 extern void AtPrepare_PgStat(void);
1452 extern void PostPrepare_PgStat(void);
1453 
1454 extern void pgstat_twophase_postcommit(TransactionId xid, uint16 info,
1455 									   void *recdata, uint32 len);
1456 extern void pgstat_twophase_postabort(TransactionId xid, uint16 info,
1457 									  void *recdata, uint32 len);
1458 
1459 extern void pgstat_send_archiver(const char *xlog, bool failed);
1460 extern void pgstat_send_bgwriter(void);
1461 
1462 /* ----------
1463  * Support functions for the SQL-callable functions to
1464  * generate the pgstat* views.
1465  * ----------
1466  */
1467 extern PgStat_StatDBEntry *pgstat_fetch_stat_dbentry(Oid dbid);
1468 extern PgStat_StatTabEntry *pgstat_fetch_stat_tabentry(Oid relid);
1469 extern PgBackendStatus *pgstat_fetch_stat_beentry(int beid);
1470 extern LocalPgBackendStatus *pgstat_fetch_stat_local_beentry(int beid);
1471 extern PgStat_StatFuncEntry *pgstat_fetch_stat_funcentry(Oid funcid);
1472 extern int	pgstat_fetch_stat_numbackends(void);
1473 extern PgStat_ArchiverStats *pgstat_fetch_stat_archiver(void);
1474 extern PgStat_GlobalStats *pgstat_fetch_global(void);
1475 extern PgStat_SLRUStats *pgstat_fetch_slru(void);
1476 
1477 extern void pgstat_count_slru_page_zeroed(int slru_idx);
1478 extern void pgstat_count_slru_page_hit(int slru_idx);
1479 extern void pgstat_count_slru_page_read(int slru_idx);
1480 extern void pgstat_count_slru_page_written(int slru_idx);
1481 extern void pgstat_count_slru_page_exists(int slru_idx);
1482 extern void pgstat_count_slru_flush(int slru_idx);
1483 extern void pgstat_count_slru_truncate(int slru_idx);
1484 extern const char *pgstat_slru_name(int slru_idx);
1485 extern int	pgstat_slru_index(const char *name);
1486 
1487 #endif							/* PGSTAT_H */
1488