4 * Definitions for the PostgreSQL statistics collector daemon.
6 * Copyright (c) 2001-2005, PostgreSQL Global Development Group
8 * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.37 2005/10/06 02:29:19 tgl Exp $
14 #include "libpq/pqcomm.h"
15 #include "utils/hsearch.h"
16 #include "utils/rel.h"
17 #include "utils/timestamp.h"
20 * The types of backend/postmaster -> collector messages
23 typedef enum StatMsgType
28 PGSTAT_MTYPE_ACTIVITY,
30 PGSTAT_MTYPE_TABPURGE,
32 PGSTAT_MTYPE_RESETCOUNTER,
33 PGSTAT_MTYPE_AUTOVAC_START,
39 * The data type used for counters.
42 typedef int64 PgStat_Counter;
45 /* ------------------------------------------------------------
46 * Message formats follow
47 * ------------------------------------------------------------
52 * PgStat_MsgHdr The common message header
55 typedef struct PgStat_MsgHdr
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?
69 #define PGSTAT_MSG_PAYLOAD (1000 - sizeof(PgStat_MsgHdr))
72 * PgStat_TableEntry Per-table info in a MsgTabstat
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.
82 typedef struct PgStat_TableEntry
86 PgStat_Counter t_numscans;
88 PgStat_Counter t_tuples_returned;
89 PgStat_Counter t_tuples_fetched;
91 PgStat_Counter t_tuples_inserted;
92 PgStat_Counter t_tuples_updated;
93 PgStat_Counter t_tuples_deleted;
95 PgStat_Counter t_blocks_fetched;
96 PgStat_Counter t_blocks_hit;
101 * PgStat_MsgDummy A dummy message, ignored by the collector
104 typedef struct PgStat_MsgDummy
111 * PgStat_MsgBestart Sent by the backend on startup
114 typedef struct PgStat_MsgBestart
119 SockAddr m_clientaddr;
123 * PgStat_MsgBeterm Sent by the postmaster after backend exit
126 typedef struct PgStat_MsgBeterm
132 * PgStat_MsgAutovacStart Sent by the autovacuum daemon to signal
133 * that a database is going to be processed
136 typedef struct PgStat_MsgAutovacStart
140 TimestampTz m_start_time;
141 } PgStat_MsgAutovacStart;
144 * PgStat_MsgVacuum Sent by the backend or autovacuum daemon
145 * after VACUUM or VACUUM ANALYZE
148 typedef struct PgStat_MsgVacuum
154 PgStat_Counter m_tuples;
158 * PgStat_MsgAnalyze Sent by the backend or autovacuum daemon
162 typedef struct PgStat_MsgAnalyze
167 PgStat_Counter m_live_tuples;
168 PgStat_Counter m_dead_tuples;
173 * PgStat_MsgActivity Sent by the backends when they start
177 #define PGSTAT_ACTIVITY_SIZE PGSTAT_MSG_PAYLOAD
179 typedef struct PgStat_MsgActivity
182 char m_what[PGSTAT_ACTIVITY_SIZE];
183 } PgStat_MsgActivity;
186 * PgStat_MsgTabstat Sent by the backend to report table
187 * and buffer access statistics.
190 #define PGSTAT_NUM_TABENTRIES \
191 ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - 3 * sizeof(int)) \
192 / sizeof(PgStat_TableEntry))
194 typedef struct PgStat_MsgTabstat
201 PgStat_TableEntry m_entry[PGSTAT_NUM_TABENTRIES];
205 * PgStat_MsgTabpurge Sent by the backend to tell the collector
209 #define PGSTAT_NUM_TABPURGE \
210 ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - sizeof(int)) \
213 typedef struct PgStat_MsgTabpurge
218 Oid m_tableid[PGSTAT_NUM_TABPURGE];
219 } PgStat_MsgTabpurge;
223 * PgStat_MsgDropdb Sent by the backend to tell the collector
224 * about a dropped database
227 typedef struct PgStat_MsgDropdb
235 * PgStat_MsgResetcounter Sent by the backend to tell the collector
239 typedef struct PgStat_MsgResetcounter
243 } PgStat_MsgResetcounter;
247 * PgStat_Msg Union over all possible messages.
250 typedef union PgStat_Msg
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;
266 /* ------------------------------------------------------------
267 * Statistic collector data structures follow
269 * PGSTAT_FILE_FORMAT_ID should be changed whenever any of these
270 * data structures change.
271 * ------------------------------------------------------------
274 #define PGSTAT_FILE_FORMAT_ID 0x01A5BC93
277 * PgStat_StatDBEntry The collector's data per database
280 typedef struct PgStat_StatDBEntry
285 PgStat_Counter n_xact_commit;
286 PgStat_Counter n_xact_rollback;
287 PgStat_Counter n_blocks_fetched;
288 PgStat_Counter n_blocks_hit;
290 TimestampTz last_autovac_time;
291 } PgStat_StatDBEntry;
295 * PgStat_StatBeEntry The collector's data per backend
298 typedef struct PgStat_StatBeEntry
300 /* An entry is non-empty iff procpid > 0 */
302 TimestampTz start_timestamp;
303 TimestampTz activity_start_timestamp;
304 char activity[PGSTAT_ACTIVITY_SIZE];
307 * The following fields are initialized by the BESTART message. If
308 * we have received messages from a backend before we have
309 * received its BESTART, these fields will be uninitialized:
310 * userid and databaseid will be InvalidOid, and clientaddr will
316 } PgStat_StatBeEntry;
320 * PgStat_StatBeDead Because UDP packets can arrive out of
321 * order, we need to keep some information
322 * about backends that are known to be
323 * dead for some seconds. This info is held
324 * in a hash table of these structs.
327 typedef struct PgStat_StatBeDead
336 * PgStat_StatTabEntry The collector's data per table (or index)
339 typedef struct PgStat_StatTabEntry
343 PgStat_Counter numscans;
345 PgStat_Counter tuples_returned;
346 PgStat_Counter tuples_fetched;
348 PgStat_Counter tuples_inserted;
349 PgStat_Counter tuples_updated;
350 PgStat_Counter tuples_deleted;
352 PgStat_Counter n_live_tuples;
353 PgStat_Counter n_dead_tuples;
354 PgStat_Counter last_anl_tuples;
356 PgStat_Counter blocks_fetched;
357 PgStat_Counter blocks_hit;
360 } PgStat_StatTabEntry;
367 extern bool pgstat_collect_startcollector;
368 extern bool pgstat_collect_resetonpmstart;
369 extern bool pgstat_collect_querystring;
370 extern bool pgstat_collect_tuplelevel;
371 extern bool pgstat_collect_blocklevel;
375 * Functions called from postmaster
378 extern void pgstat_init(void);
379 extern int pgstat_start(void);
380 extern void pgstat_beterm(int pid);
381 extern void pgstat_reset_all(void);
384 extern void PgstatBufferMain(int argc, char *argv[]);
385 extern void PgstatCollectorMain(int argc, char *argv[]);
390 * Functions called from backends
393 extern void pgstat_bestart(void);
395 extern void pgstat_ping(void);
396 extern void pgstat_report_activity(const char *what);
397 extern void pgstat_report_tabstat(void);
398 extern void pgstat_report_autovac(Oid dboid);
399 extern void pgstat_report_vacuum(Oid tableoid, bool shared,
400 bool analyze, PgStat_Counter tuples);
401 extern void pgstat_report_analyze(Oid tableoid, bool shared,
402 PgStat_Counter livetuples,
403 PgStat_Counter deadtuples);
404 extern int pgstat_vacuum_tabstat(void);
406 extern void pgstat_reset_counters(void);
408 extern void pgstat_initstats(PgStat_Info *stats, Relation rel);
411 #define pgstat_count_heap_scan(s) \
413 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
414 ((PgStat_TableEntry *)((s)->tabentry))->t_numscans++; \
416 /* kluge for bitmap scans: */
417 #define pgstat_discount_heap_scan(s) \
419 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
420 ((PgStat_TableEntry *)((s)->tabentry))->t_numscans--; \
422 #define pgstat_count_heap_getnext(s) \
424 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
425 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_returned++; \
427 #define pgstat_count_heap_fetch(s) \
429 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
430 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_fetched++; \
432 #define pgstat_count_heap_insert(s) \
434 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
435 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_inserted++; \
437 #define pgstat_count_heap_update(s) \
439 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
440 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_updated++; \
442 #define pgstat_count_heap_delete(s) \
444 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
445 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_deleted++; \
447 #define pgstat_count_index_scan(s) \
449 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
450 ((PgStat_TableEntry *)((s)->tabentry))->t_numscans++; \
452 #define pgstat_count_index_tuples(s, n) \
454 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
455 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_returned += (n); \
457 #define pgstat_count_buffer_read(s,r) \
459 if (pgstat_collect_blocklevel) { \
460 if ((s)->tabentry != NULL) \
461 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_fetched++; \
463 pgstat_initstats((s), (r)); \
464 if ((s)->tabentry != NULL) \
465 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_fetched++; \
469 #define pgstat_count_buffer_hit(s,r) \
471 if (pgstat_collect_blocklevel) { \
472 if ((s)->tabentry != NULL) \
473 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_hit++; \
475 pgstat_initstats((s), (r)); \
476 if ((s)->tabentry != NULL) \
477 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_hit++; \
483 extern void pgstat_count_xact_commit(void);
484 extern void pgstat_count_xact_rollback(void);
487 * Support functions for the SQL-callable functions to
488 * generate the pgstat* views.
491 extern PgStat_StatDBEntry *pgstat_fetch_stat_dbentry(Oid dbid);
492 extern PgStat_StatTabEntry *pgstat_fetch_stat_tabentry(Oid relid);
493 extern PgStat_StatBeEntry *pgstat_fetch_stat_beentry(int beid);
494 extern int pgstat_fetch_stat_numbackends(void);
496 #endif /* PGSTAT_H */