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