1 /*-------------------------------------------------------------------------
2  *
3  * instrument.h
4  *	  definitions for run-time statistics collection
5  *
6  *
7  * Copyright (c) 2001-2021, PostgreSQL Global Development Group
8  *
9  * src/include/executor/instrument.h
10  *
11  *-------------------------------------------------------------------------
12  */
13 #ifndef INSTRUMENT_H
14 #define INSTRUMENT_H
15 
16 #include "portability/instr_time.h"
17 
18 
19 /*
20  * BufferUsage and WalUsage counters keep being incremented infinitely,
21  * i.e., must never be reset to zero, so that we can calculate how much
22  * the counters are incremented in an arbitrary period.
23  */
24 typedef struct BufferUsage
25 {
26 	int64		shared_blks_hit;	/* # of shared buffer hits */
27 	int64		shared_blks_read;	/* # of shared disk blocks read */
28 	int64		shared_blks_dirtied;	/* # of shared blocks dirtied */
29 	int64		shared_blks_written;	/* # of shared disk blocks written */
30 	int64		local_blks_hit; /* # of local buffer hits */
31 	int64		local_blks_read;	/* # of local disk blocks read */
32 	int64		local_blks_dirtied; /* # of local blocks dirtied */
33 	int64		local_blks_written; /* # of local disk blocks written */
34 	int64		temp_blks_read; /* # of temp blocks read */
35 	int64		temp_blks_written;	/* # of temp blocks written */
36 	instr_time	blk_read_time;	/* time spent reading */
37 	instr_time	blk_write_time; /* time spent writing */
38 } BufferUsage;
39 
40 /*
41  * WalUsage tracks only WAL activity like WAL records generation that
42  * can be measured per query and is displayed by EXPLAIN command,
43  * pg_stat_statements extension, etc. It does not track other WAL activity
44  * like WAL writes that it's not worth measuring per query. That's tracked
45  * by WAL global statistics counters in WalStats, instead.
46  */
47 typedef struct WalUsage
48 {
49 	int64		wal_records;	/* # of WAL records produced */
50 	int64		wal_fpi;		/* # of WAL full page images produced */
51 	uint64		wal_bytes;		/* size of WAL records produced */
52 } WalUsage;
53 
54 /* Flag bits included in InstrAlloc's instrument_options bitmask */
55 typedef enum InstrumentOption
56 {
57 	INSTRUMENT_TIMER = 1 << 0,	/* needs timer (and row counts) */
58 	INSTRUMENT_BUFFERS = 1 << 1,	/* needs buffer usage */
59 	INSTRUMENT_ROWS = 1 << 2,	/* needs row count */
60 	INSTRUMENT_WAL = 1 << 3,	/* needs WAL usage */
61 	INSTRUMENT_ALL = PG_INT32_MAX
62 } InstrumentOption;
63 
64 typedef struct Instrumentation
65 {
66 	/* Parameters set at node creation: */
67 	bool		need_timer;		/* true if we need timer data */
68 	bool		need_bufusage;	/* true if we need buffer usage data */
69 	bool		need_walusage;	/* true if we need WAL usage data */
70 	bool		async_mode;		/* true if node is in async mode */
71 	/* Info about current plan cycle: */
72 	bool		running;		/* true if we've completed first tuple */
73 	instr_time	starttime;		/* start time of current iteration of node */
74 	instr_time	counter;		/* accumulated runtime for this node */
75 	double		firsttuple;		/* time for first tuple of this cycle */
76 	double		tuplecount;		/* # of tuples emitted so far this cycle */
77 	BufferUsage bufusage_start; /* buffer usage at start */
78 	WalUsage	walusage_start; /* WAL usage at start */
79 	/* Accumulated statistics across all completed cycles: */
80 	double		startup;		/* total startup time (in seconds) */
81 	double		total;			/* total time (in seconds) */
82 	double		ntuples;		/* total tuples produced */
83 	double		ntuples2;		/* secondary node-specific tuple counter */
84 	double		nloops;			/* # of run cycles for this node */
85 	double		nfiltered1;		/* # of tuples removed by scanqual or joinqual */
86 	double		nfiltered2;		/* # of tuples removed by "other" quals */
87 	BufferUsage bufusage;		/* total buffer usage */
88 	WalUsage	walusage;		/* total WAL usage */
89 } Instrumentation;
90 
91 typedef struct WorkerInstrumentation
92 {
93 	int			num_workers;	/* # of structures that follow */
94 	Instrumentation instrument[FLEXIBLE_ARRAY_MEMBER];
95 } WorkerInstrumentation;
96 
97 extern PGDLLIMPORT BufferUsage pgBufferUsage;
98 extern PGDLLIMPORT WalUsage pgWalUsage;
99 
100 extern Instrumentation *InstrAlloc(int n, int instrument_options,
101 								   bool async_mode);
102 extern void InstrInit(Instrumentation *instr, int instrument_options);
103 extern void InstrStartNode(Instrumentation *instr);
104 extern void InstrStopNode(Instrumentation *instr, double nTuples);
105 extern void InstrUpdateTupleCount(Instrumentation *instr, double nTuples);
106 extern void InstrEndLoop(Instrumentation *instr);
107 extern void InstrAggNode(Instrumentation *dst, Instrumentation *add);
108 extern void InstrStartParallelQuery(void);
109 extern void InstrEndParallelQuery(BufferUsage *bufusage, WalUsage *walusage);
110 extern void InstrAccumParallelQuery(BufferUsage *bufusage, WalUsage *walusage);
111 extern void BufferUsageAccumDiff(BufferUsage *dst,
112 								 const BufferUsage *add, const BufferUsage *sub);
113 extern void WalUsageAccumDiff(WalUsage *dst, const WalUsage *add,
114 							  const WalUsage *sub);
115 
116 #endif							/* INSTRUMENT_H */
117