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.35 2005/08/11 21:11:49 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
75 typedef struct PgStat_TableEntry
79 PgStat_Counter t_numscans;
81 PgStat_Counter t_tuples_returned;
82 PgStat_Counter t_tuples_fetched;
83 PgStat_Counter t_tuples_inserted;
84 PgStat_Counter t_tuples_updated;
85 PgStat_Counter t_tuples_deleted;
87 PgStat_Counter t_blocks_fetched;
88 PgStat_Counter t_blocks_hit;
93 * PgStat_MsgDummy A dummy message, ignored by the collector
96 typedef struct PgStat_MsgDummy
103 * PgStat_MsgBestart Sent by the backend on startup
106 typedef struct PgStat_MsgBestart
111 SockAddr m_clientaddr;
115 * PgStat_MsgBeterm Sent by the postmaster after backend exit
118 typedef struct PgStat_MsgBeterm
124 * PgStat_MsgAutovacStart Sent by the autovacuum daemon to signal
125 * that a database is going to be processed
128 typedef struct PgStat_MsgAutovacStart
132 TimestampTz m_start_time;
133 } PgStat_MsgAutovacStart;
136 * PgStat_MsgVacuum Sent by the backend or autovacuum daemon
137 * after VACUUM or VACUUM ANALYZE
140 typedef struct PgStat_MsgVacuum
146 PgStat_Counter m_tuples;
150 * PgStat_MsgAnalyze Sent by the backend or autovacuum daemon
154 typedef struct PgStat_MsgAnalyze
159 PgStat_Counter m_live_tuples;
160 PgStat_Counter m_dead_tuples;
165 * PgStat_MsgActivity Sent by the backends when they start
169 #define PGSTAT_ACTIVITY_SIZE PGSTAT_MSG_PAYLOAD
171 typedef struct PgStat_MsgActivity
174 char m_what[PGSTAT_ACTIVITY_SIZE];
175 } PgStat_MsgActivity;
178 * PgStat_MsgTabstat Sent by the backend to report table
179 * and buffer access statistics.
182 #define PGSTAT_NUM_TABENTRIES ((PGSTAT_MSG_PAYLOAD - 3 * sizeof(int)) \
183 / sizeof(PgStat_TableEntry))
185 typedef struct PgStat_MsgTabstat
192 PgStat_TableEntry m_entry[PGSTAT_NUM_TABENTRIES];
196 * PgStat_MsgTabpurge Sent by the backend to tell the collector
200 #define PGSTAT_NUM_TABPURGE ((PGSTAT_MSG_PAYLOAD - sizeof(int)) \
203 typedef struct PgStat_MsgTabpurge
208 Oid m_tableid[PGSTAT_NUM_TABPURGE];
209 } PgStat_MsgTabpurge;
213 * PgStat_MsgDropdb Sent by the backend to tell the collector
214 * about dropped database
217 typedef struct PgStat_MsgDropdb
225 * PgStat_MsgResetcounter Sent by the backend to tell the collector
229 typedef struct PgStat_MsgResetcounter
233 } PgStat_MsgResetcounter;
237 * PgStat_Msg Union over all possible messages.
240 typedef union PgStat_Msg
242 PgStat_MsgHdr msg_hdr;
243 PgStat_MsgDummy msg_dummy;
244 PgStat_MsgBestart msg_bestart;
245 PgStat_MsgActivity msg_activity;
246 PgStat_MsgTabstat msg_tabstat;
247 PgStat_MsgTabpurge msg_tabpurge;
248 PgStat_MsgDropdb msg_dropdb;
249 PgStat_MsgResetcounter msg_resetcounter;
250 PgStat_MsgAutovacStart msg_autovacuum;
251 PgStat_MsgVacuum msg_vacuum;
252 PgStat_MsgAnalyze msg_analyze;
256 /* ------------------------------------------------------------
257 * Statistic collector data structures follow
259 * PGSTAT_FILE_FORMAT_ID should be changed whenever any of these
260 * data structures change.
261 * ------------------------------------------------------------
264 #define PGSTAT_FILE_FORMAT_ID 0x01A5BC93
267 * PgStat_StatDBEntry The collectors data per database
270 typedef struct PgStat_StatDBEntry
275 PgStat_Counter n_xact_commit;
276 PgStat_Counter n_xact_rollback;
277 PgStat_Counter n_blocks_fetched;
278 PgStat_Counter n_blocks_hit;
280 TimestampTz last_autovac_time;
281 } PgStat_StatDBEntry;
285 * PgStat_StatBeEntry The collectors data per backend
288 typedef struct PgStat_StatBeEntry
290 /* An entry is non-empty iff procpid > 0 */
292 TimestampTz start_timestamp;
293 TimestampTz activity_start_timestamp;
294 char activity[PGSTAT_ACTIVITY_SIZE];
297 * The following fields are initialized by the BESTART message. If
298 * we have received messages from a backend before we have
299 * received its BESTART, these fields will be uninitialized:
300 * userid and databaseid will be InvalidOid, and clientaddr will
306 } PgStat_StatBeEntry;
310 * PgStat_StatBeDead Because UDP packets can arrive out of
311 * order, we need to keep some information
312 * about backends that are known to be
313 * dead for some seconds. This info is held
314 * in a hash table of these structs.
317 typedef struct PgStat_StatBeDead
326 * PgStat_StatTabEntry The collectors data table data
329 typedef struct PgStat_StatTabEntry
333 PgStat_Counter numscans;
335 PgStat_Counter tuples_returned;
336 PgStat_Counter tuples_fetched;
337 PgStat_Counter tuples_inserted;
338 PgStat_Counter tuples_updated;
339 PgStat_Counter tuples_deleted;
341 PgStat_Counter n_live_tuples;
342 PgStat_Counter n_dead_tuples;
343 PgStat_Counter last_anl_tuples;
345 PgStat_Counter blocks_fetched;
346 PgStat_Counter blocks_hit;
349 } PgStat_StatTabEntry;
356 extern bool pgstat_collect_startcollector;
357 extern bool pgstat_collect_resetonpmstart;
358 extern bool pgstat_collect_querystring;
359 extern bool pgstat_collect_tuplelevel;
360 extern bool pgstat_collect_blocklevel;
364 * Functions called from postmaster
367 extern void pgstat_init(void);
368 extern int pgstat_start(void);
369 extern void pgstat_beterm(int pid);
370 extern void pgstat_reset_all(void);
373 extern void PgstatBufferMain(int argc, char *argv[]);
374 extern void PgstatCollectorMain(int argc, char *argv[]);
379 * Functions called from backends
382 extern void pgstat_bestart(void);
384 extern void pgstat_ping(void);
385 extern void pgstat_report_activity(const char *what);
386 extern void pgstat_report_tabstat(void);
387 extern void pgstat_report_autovac(void);
388 extern void pgstat_report_vacuum(Oid tableoid, bool shared,
389 bool analyze, PgStat_Counter tuples);
390 extern void pgstat_report_analyze(Oid tableoid, bool shared,
391 PgStat_Counter livetuples,
392 PgStat_Counter deadtuples);
393 extern int pgstat_vacuum_tabstat(void);
395 extern void pgstat_reset_counters(void);
397 extern void pgstat_initstats(PgStat_Info *stats, Relation rel);
400 #define pgstat_reset_heap_scan(s) \
402 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
403 (s)->heap_scan_counted = FALSE; \
405 #define pgstat_count_heap_scan(s) \
407 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL && \
408 !(s)->heap_scan_counted) { \
409 ((PgStat_TableEntry *)((s)->tabentry))->t_numscans++; \
410 (s)->heap_scan_counted = TRUE; \
413 #define pgstat_count_heap_getnext(s) \
415 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
416 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_returned++; \
418 #define pgstat_count_heap_fetch(s) \
420 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
421 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_fetched++; \
423 #define pgstat_count_heap_insert(s) \
425 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
426 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_inserted++; \
428 #define pgstat_count_heap_update(s) \
430 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
431 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_updated++; \
433 #define pgstat_count_heap_delete(s) \
435 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
436 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_deleted++; \
438 #define pgstat_reset_index_scan(s) \
440 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
441 (s)->index_scan_counted = FALSE; \
443 #define pgstat_count_index_scan(s) \
445 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL && \
446 !(s)->index_scan_counted) { \
447 ((PgStat_TableEntry *)((s)->tabentry))->t_numscans++; \
448 (s)->index_scan_counted = TRUE; \
451 #define pgstat_count_index_getnext(s) \
453 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
454 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_returned++; \
456 #define pgstat_count_buffer_read(s,r) \
458 if (pgstat_collect_blocklevel && (s)->tabentry != NULL) \
459 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_fetched++; \
461 if (pgstat_collect_blocklevel && !(s)->no_stats) { \
462 pgstat_initstats((s), (r)); \
463 if ((s)->tabentry != NULL) \
464 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_fetched++; \
468 #define pgstat_count_buffer_hit(s,r) \
470 if (pgstat_collect_blocklevel && (s)->tabentry != NULL) \
471 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_hit++; \
473 if (pgstat_collect_blocklevel && !(s)->no_stats) { \
474 pgstat_initstats((s), (r)); \
475 if ((s)->tabentry != NULL) \
476 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_hit++; \
482 extern void pgstat_count_xact_commit(void);
483 extern void pgstat_count_xact_rollback(void);
486 * Support functions for the SQL-callable functions to
487 * generate the pgstat* views.
490 extern PgStat_StatDBEntry *pgstat_fetch_stat_dbentry(Oid dbid);
491 extern PgStat_StatTabEntry *pgstat_fetch_stat_tabentry(Oid relid);
492 extern PgStat_StatBeEntry *pgstat_fetch_stat_beentry(int beid);
493 extern int pgstat_fetch_stat_numbackends(void);
495 #endif /* PGSTAT_H */