]> granicus.if.org Git - postgresql/blob - src/include/pgstat.h
Remove the pgstats logic for delaying destruction of stats table entries.
[postgresql] / src / include / pgstat.h
1 /* ----------
2  *      pgstat.h
3  *
4  *      Definitions for the PostgreSQL statistics collector daemon.
5  *
6  *      Copyright (c) 2001-2006, PostgreSQL Global Development Group
7  *
8  *      $PostgreSQL: pgsql/src/include/pgstat.h,v 1.43 2006/04/06 20:38:00 tgl Exp $
9  * ----------
10  */
11 #ifndef PGSTAT_H
12 #define PGSTAT_H
13
14 #include "libpq/pqcomm.h"
15 #include "utils/hsearch.h"
16 #include "utils/rel.h"
17 #include "utils/timestamp.h"
18
19 /* ----------
20  * The types of backend/postmaster -> collector messages
21  * ----------
22  */
23 typedef enum StatMsgType
24 {
25         PGSTAT_MTYPE_DUMMY,
26         PGSTAT_MTYPE_BESTART,
27         PGSTAT_MTYPE_BETERM,
28         PGSTAT_MTYPE_ACTIVITY,
29         PGSTAT_MTYPE_TABSTAT,
30         PGSTAT_MTYPE_TABPURGE,
31         PGSTAT_MTYPE_DROPDB,
32         PGSTAT_MTYPE_RESETCOUNTER,
33         PGSTAT_MTYPE_AUTOVAC_START,
34         PGSTAT_MTYPE_VACUUM,
35         PGSTAT_MTYPE_ANALYZE
36 } StatMsgType;
37
38 /* ----------
39  * The data type used for counters.
40  * ----------
41  */
42 typedef int64 PgStat_Counter;
43
44
45 /* ------------------------------------------------------------
46  * Message formats follow
47  * ------------------------------------------------------------
48  */
49
50
51 /* ----------
52  * PgStat_MsgHdr                                The common message header
53  * ----------
54  */
55 typedef struct PgStat_MsgHdr
56 {
57         StatMsgType m_type;
58         int                     m_size;
59         int                     m_backendid;
60         int                     m_procpid;
61 } PgStat_MsgHdr;
62
63 /* ----------
64  * Space available in a message.  This will keep the UDP packets below 1K,
65  * which should fit unfragmented into the MTU of the lo interface on most
66  * platforms. Does anybody care for platforms where it doesn't?
67  * ----------
68  */
69 #define PGSTAT_MSG_PAYLOAD      (1000 - sizeof(PgStat_MsgHdr))
70
71 /* ----------
72  * PgStat_TableEntry                    Per-table info in a MsgTabstat
73  *
74  * Note: for a table, tuples_returned is the number of tuples successfully
75  * fetched by heap_getnext, while tuples_fetched is the number of tuples
76  * successfully fetched by heap_fetch under the control of bitmap indexscans.
77  * For an index, tuples_returned is the number of index entries returned by
78  * the index AM, while tuples_fetched is the number of tuples successfully
79  * fetched by heap_fetch under the control of simple indexscans for this index.
80  * ----------
81  */
82 typedef struct PgStat_TableEntry
83 {
84         Oid                     t_id;
85
86         PgStat_Counter t_numscans;
87
88         PgStat_Counter t_tuples_returned;
89         PgStat_Counter t_tuples_fetched;
90
91         PgStat_Counter t_tuples_inserted;
92         PgStat_Counter t_tuples_updated;
93         PgStat_Counter t_tuples_deleted;
94
95         PgStat_Counter t_blocks_fetched;
96         PgStat_Counter t_blocks_hit;
97 } PgStat_TableEntry;
98
99
100 /* ----------
101  * PgStat_MsgDummy                              A dummy message, ignored by the collector
102  * ----------
103  */
104 typedef struct PgStat_MsgDummy
105 {
106         PgStat_MsgHdr m_hdr;
107         char            m_dummy[512];
108 } PgStat_MsgDummy;
109
110 /* ----------
111  * PgStat_MsgBestart                    Sent by the backend on startup
112  * ----------
113  */
114 typedef struct PgStat_MsgBestart
115 {
116         PgStat_MsgHdr m_hdr;
117         Oid                     m_databaseid;
118         Oid                     m_userid;
119         SockAddr        m_clientaddr;
120 } PgStat_MsgBestart;
121
122 /* ----------
123  * PgStat_MsgBeterm                             Sent by the postmaster after backend exit
124  * ----------
125  */
126 typedef struct PgStat_MsgBeterm
127 {
128         PgStat_MsgHdr m_hdr;
129 } PgStat_MsgBeterm;
130
131 /* ----------
132  * PgStat_MsgAutovacStart               Sent by the autovacuum daemon to signal
133  *                                                              that a database is going to be processed
134  * ----------
135  */
136 typedef struct PgStat_MsgAutovacStart
137 {
138         PgStat_MsgHdr m_hdr;
139         Oid                     m_databaseid;
140         TimestampTz m_start_time;
141 } PgStat_MsgAutovacStart;
142
143 /* ----------
144  * PgStat_MsgVacuum                             Sent by the backend or autovacuum daemon
145  *                                                              after VACUUM or VACUUM ANALYZE
146  * ----------
147  */
148 typedef struct PgStat_MsgVacuum
149 {
150         PgStat_MsgHdr m_hdr;
151         Oid                     m_databaseid;
152         Oid                     m_tableoid;
153         bool            m_analyze;
154         PgStat_Counter m_tuples;
155 } PgStat_MsgVacuum;
156
157 /* ----------
158  * PgStat_MsgAnalyze                    Sent by the backend or autovacuum daemon
159  *                                                              after ANALYZE
160  * ----------
161  */
162 typedef struct PgStat_MsgAnalyze
163 {
164         PgStat_MsgHdr m_hdr;
165         Oid                     m_databaseid;
166         Oid                     m_tableoid;
167         PgStat_Counter m_live_tuples;
168         PgStat_Counter m_dead_tuples;
169 } PgStat_MsgAnalyze;
170
171
172 /* ----------
173  * PgStat_MsgActivity                   Sent by the backends when they start
174  *                                                              to parse a query.
175  * ----------
176  */
177 #define PGSTAT_ACTIVITY_SIZE    PGSTAT_MSG_PAYLOAD
178
179 typedef struct PgStat_MsgActivity
180 {
181         PgStat_MsgHdr m_hdr;
182         char            m_cmd_str[PGSTAT_ACTIVITY_SIZE];
183 } PgStat_MsgActivity;
184
185 /* ----------
186  * PgStat_MsgTabstat                    Sent by the backend to report table
187  *                                                              and buffer access statistics.
188  * ----------
189  */
190 #define PGSTAT_NUM_TABENTRIES  \
191         ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - 3 * sizeof(int))  \
192          / sizeof(PgStat_TableEntry))
193
194 typedef struct PgStat_MsgTabstat
195 {
196         PgStat_MsgHdr m_hdr;
197         Oid                     m_databaseid;
198         int                     m_nentries;
199         int                     m_xact_commit;
200         int                     m_xact_rollback;
201         PgStat_TableEntry m_entry[PGSTAT_NUM_TABENTRIES];
202 } PgStat_MsgTabstat;
203
204 /* ----------
205  * PgStat_MsgTabpurge                   Sent by the backend to tell the collector
206  *                                                              about dead tables.
207  * ----------
208  */
209 #define PGSTAT_NUM_TABPURGE  \
210         ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - sizeof(int))  \
211          / sizeof(Oid))
212
213 typedef struct PgStat_MsgTabpurge
214 {
215         PgStat_MsgHdr m_hdr;
216         Oid                     m_databaseid;
217         int                     m_nentries;
218         Oid                     m_tableid[PGSTAT_NUM_TABPURGE];
219 } PgStat_MsgTabpurge;
220
221
222 /* ----------
223  * PgStat_MsgDropdb                             Sent by the backend to tell the collector
224  *                                                              about a dropped database
225  * ----------
226  */
227 typedef struct PgStat_MsgDropdb
228 {
229         PgStat_MsgHdr m_hdr;
230         Oid                     m_databaseid;
231 } PgStat_MsgDropdb;
232
233
234 /* ----------
235  * PgStat_MsgResetcounter               Sent by the backend to tell the collector
236  *                                                              to reset counters
237  * ----------
238  */
239 typedef struct PgStat_MsgResetcounter
240 {
241         PgStat_MsgHdr m_hdr;
242         Oid                     m_databaseid;
243 } PgStat_MsgResetcounter;
244
245
246 /* ----------
247  * PgStat_Msg                                   Union over all possible messages.
248  * ----------
249  */
250 typedef union PgStat_Msg
251 {
252         PgStat_MsgHdr msg_hdr;
253         PgStat_MsgDummy msg_dummy;
254         PgStat_MsgBestart msg_bestart;
255         PgStat_MsgActivity msg_activity;
256         PgStat_MsgTabstat msg_tabstat;
257         PgStat_MsgTabpurge msg_tabpurge;
258         PgStat_MsgDropdb msg_dropdb;
259         PgStat_MsgResetcounter msg_resetcounter;
260         PgStat_MsgAutovacStart msg_autovacuum;
261         PgStat_MsgVacuum msg_vacuum;
262         PgStat_MsgAnalyze msg_analyze;
263 } PgStat_Msg;
264
265
266 /* ------------------------------------------------------------
267  * Statistic collector data structures follow
268  *
269  * PGSTAT_FILE_FORMAT_ID should be changed whenever any of these
270  * data structures change.
271  * ------------------------------------------------------------
272  */
273
274 #define PGSTAT_FILE_FORMAT_ID   0x01A5BC95
275
276 /* ----------
277  * PgStat_StatDBEntry                   The collector's data per database
278  *
279  * Note: n_backends is not maintained within the collector.  It's computed
280  * when a backend reads the stats file for use.
281  * ----------
282  */
283 typedef struct PgStat_StatDBEntry
284 {
285         Oid                     databaseid;
286         int                     n_backends;
287         PgStat_Counter n_xact_commit;
288         PgStat_Counter n_xact_rollback;
289         PgStat_Counter n_blocks_fetched;
290         PgStat_Counter n_blocks_hit;
291         TimestampTz last_autovac_time;
292
293         /*
294          * tables must be last in the struct, because we don't write the pointer
295          * out to the stats file.
296          */
297         HTAB       *tables;
298 } PgStat_StatDBEntry;
299
300
301 /* ----------
302  * PgStat_StatBeEntry                   The collector's data per backend
303  * ----------
304  */
305 typedef struct PgStat_StatBeEntry
306 {
307         /* An entry is non-empty iff procpid > 0 */
308         int                     procpid;
309         TimestampTz start_timestamp;
310         TimestampTz activity_start_timestamp;
311
312         /*
313          * These fields are initialized by the BESTART message. If we have
314          * received messages from a backend before we have received its BESTART,
315          * these fields will be uninitialized: userid and databaseid will be
316          * InvalidOid, and clientaddr will be undefined.
317          */
318         Oid                     userid;
319         Oid                     databaseid;
320         SockAddr        clientaddr;
321
322         /*
323          * activity[] must be last in the struct, because we only write as much
324          * of it as needed to the stats file.
325          */
326         char            activity[PGSTAT_ACTIVITY_SIZE];
327 } PgStat_StatBeEntry;
328
329
330 /* ----------
331  * PgStat_StatTabEntry                  The collector's data per table (or index)
332  * ----------
333  */
334 typedef struct PgStat_StatTabEntry
335 {
336         Oid                     tableid;
337
338         PgStat_Counter numscans;
339
340         PgStat_Counter tuples_returned;
341         PgStat_Counter tuples_fetched;
342
343         PgStat_Counter tuples_inserted;
344         PgStat_Counter tuples_updated;
345         PgStat_Counter tuples_deleted;
346
347         PgStat_Counter n_live_tuples;
348         PgStat_Counter n_dead_tuples;
349         PgStat_Counter last_anl_tuples;
350
351         PgStat_Counter blocks_fetched;
352         PgStat_Counter blocks_hit;
353 } PgStat_StatTabEntry;
354
355
356 /* ----------
357  * GUC parameters
358  * ----------
359  */
360 extern bool pgstat_collect_startcollector;
361 extern bool pgstat_collect_resetonpmstart;
362 extern bool pgstat_collect_querystring;
363 extern bool pgstat_collect_tuplelevel;
364 extern bool pgstat_collect_blocklevel;
365
366
367 /* ----------
368  * Functions called from postmaster
369  * ----------
370  */
371 extern void pgstat_init(void);
372 extern int      pgstat_start(void);
373 extern void pgstat_beterm(int pid);
374 extern void pgstat_reset_all(void);
375
376 #ifdef EXEC_BACKEND
377 extern void PgstatBufferMain(int argc, char *argv[]);
378 extern void PgstatCollectorMain(int argc, char *argv[]);
379 #endif
380
381
382 /* ----------
383  * Functions called from backends
384  * ----------
385  */
386 extern void pgstat_bestart(void);
387
388 extern void pgstat_ping(void);
389 extern void pgstat_report_activity(const char *what);
390 extern void pgstat_report_tabstat(void);
391 extern void pgstat_report_autovac(Oid dboid);
392 extern void pgstat_report_vacuum(Oid tableoid, bool shared,
393                                          bool analyze, PgStat_Counter tuples);
394 extern void pgstat_report_analyze(Oid tableoid, bool shared,
395                                           PgStat_Counter livetuples,
396                                           PgStat_Counter deadtuples);
397 extern void pgstat_vacuum_tabstat(void);
398 extern void pgstat_drop_relation(Oid relid);
399
400 extern void pgstat_reset_counters(void);
401
402 extern void pgstat_initstats(PgStat_Info *stats, Relation rel);
403
404
405 #define pgstat_count_heap_scan(s)                                                                               \
406         do {                                                                                                                            \
407                 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL)                 \
408                         ((PgStat_TableEntry *)((s)->tabentry))->t_numscans++;           \
409         } while (0)
410 /* kluge for bitmap scans: */
411 #define pgstat_discount_heap_scan(s)                                                                    \
412         do {                                                                                                                            \
413                 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL)                 \
414                         ((PgStat_TableEntry *)((s)->tabentry))->t_numscans--;           \
415         } while (0)
416 #define pgstat_count_heap_getnext(s)                                                                    \
417         do {                                                                                                                            \
418                 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL)                 \
419                         ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_returned++; \
420         } while (0)
421 #define pgstat_count_heap_fetch(s)                                                                              \
422         do {                                                                                                                            \
423                 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL)                 \
424                         ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_fetched++; \
425         } while (0)
426 #define pgstat_count_heap_insert(s)                                                                             \
427         do {                                                                                                                            \
428                 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL)                 \
429                         ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_inserted++; \
430         } while (0)
431 #define pgstat_count_heap_update(s)                                                                             \
432         do {                                                                                                                            \
433                 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL)                 \
434                         ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_updated++; \
435         } while (0)
436 #define pgstat_count_heap_delete(s)                                                                             \
437         do {                                                                                                                            \
438                 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL)                 \
439                         ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_deleted++; \
440         } while (0)
441 #define pgstat_count_index_scan(s)                                                                              \
442         do {                                                                                                                            \
443                 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL)                 \
444                         ((PgStat_TableEntry *)((s)->tabentry))->t_numscans++;           \
445         } while (0)
446 #define pgstat_count_index_tuples(s, n)                                                                 \
447         do {                                                                                                                            \
448                 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL)                 \
449                         ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_returned += (n); \
450         } while (0)
451 #define pgstat_count_buffer_read(s,r)                                                                   \
452         do {                                                                                                                            \
453                 if (pgstat_collect_blocklevel) {                                                                \
454                         if ((s)->tabentry != NULL)                                                                      \
455                                 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_fetched++; \
456                         else {                                                                                                          \
457                                 pgstat_initstats((s), (r));                                                             \
458                                 if ((s)->tabentry != NULL)                                                              \
459                                         ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_fetched++; \
460                         }                                                                                                                       \
461                 }                                                                                                                               \
462         } while (0)
463 #define pgstat_count_buffer_hit(s,r)                                                                    \
464         do {                                                                                                                            \
465                 if (pgstat_collect_blocklevel) {                                                                \
466                         if ((s)->tabentry != NULL)                                                                      \
467                                 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_hit++; \
468                         else {                                                                                                          \
469                                 pgstat_initstats((s), (r));                                                             \
470                                 if ((s)->tabentry != NULL)                                                              \
471                                         ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_hit++; \
472                         }                                                                                                                       \
473                 }                                                                                                                               \
474         } while (0)
475
476
477 extern void pgstat_count_xact_commit(void);
478 extern void pgstat_count_xact_rollback(void);
479
480 /* ----------
481  * Support functions for the SQL-callable functions to
482  * generate the pgstat* views.
483  * ----------
484  */
485 extern PgStat_StatDBEntry *pgstat_fetch_stat_dbentry(Oid dbid);
486 extern PgStat_StatTabEntry *pgstat_fetch_stat_tabentry(Oid relid);
487 extern PgStat_StatBeEntry *pgstat_fetch_stat_beentry(int beid);
488 extern int      pgstat_fetch_stat_numbackends(void);
489
490 #endif   /* PGSTAT_H */