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.29 2005/05/11 01:41:41 neilc Exp $
14 #include "libpq/pqcomm.h"
15 #include "utils/hsearch.h"
16 #include "utils/nabstime.h"
17 #include "utils/rel.h"
20 * The types of backend/postmaster -> collector messages
23 #define PGSTAT_MTYPE_DUMMY 0
24 #define PGSTAT_MTYPE_BESTART 1
25 #define PGSTAT_MTYPE_BETERM 2
26 #define PGSTAT_MTYPE_ACTIVITY 3
27 #define PGSTAT_MTYPE_TABSTAT 4
28 #define PGSTAT_MTYPE_TABPURGE 5
29 #define PGSTAT_MTYPE_DROPDB 6
30 #define PGSTAT_MTYPE_RESETCOUNTER 7
33 * The data type used for counters.
36 typedef int64 PgStat_Counter;
39 /* ------------------------------------------------------------
40 * Message formats follow
41 * ------------------------------------------------------------
46 * PgStat_MsgHdr The common message header
49 typedef struct PgStat_MsgHdr
58 * Space available in a message. This will keep the UDP packets below 1K,
59 * which should fit unfragmented into the MTU of the lo interface on most
60 * platforms. Does anybody care for platforms where it doesn't?
63 #define PGSTAT_MSG_PAYLOAD (1000 - sizeof(PgStat_MsgHdr))
66 * PgStat_TableEntry Per-table info in a MsgTabstat
69 typedef struct PgStat_TableEntry
73 PgStat_Counter t_numscans;
75 PgStat_Counter t_tuples_returned;
76 PgStat_Counter t_tuples_fetched;
77 PgStat_Counter t_tuples_inserted;
78 PgStat_Counter t_tuples_updated;
79 PgStat_Counter t_tuples_deleted;
81 PgStat_Counter t_blocks_fetched;
82 PgStat_Counter t_blocks_hit;
87 * PgStat_MsgDummy A dummy message, ignored by the collector
90 typedef struct PgStat_MsgDummy
97 * PgStat_MsgBestart Sent by the backend on startup
100 typedef struct PgStat_MsgBestart
105 SockAddr m_clientaddr;
109 * PgStat_MsgBeterm Sent by the postmaster after backend exit
112 typedef struct PgStat_MsgBeterm
118 * PgStat_MsgActivity Sent by the backends when they start
122 #define PGSTAT_ACTIVITY_SIZE PGSTAT_MSG_PAYLOAD
124 typedef struct PgStat_MsgActivity
127 char m_what[PGSTAT_ACTIVITY_SIZE];
128 } PgStat_MsgActivity;
131 * PgStat_MsgTabstat Sent by the backend to report table
132 * and buffer access statistics.
135 #define PGSTAT_NUM_TABENTRIES ((PGSTAT_MSG_PAYLOAD - 3 * sizeof(int)) \
136 / sizeof(PgStat_TableEntry))
138 typedef struct PgStat_MsgTabstat
145 PgStat_TableEntry m_entry[PGSTAT_NUM_TABENTRIES];
149 * PgStat_MsgTabpurge Sent by the backend to tell the collector
153 #define PGSTAT_NUM_TABPURGE ((PGSTAT_MSG_PAYLOAD - sizeof(int)) \
156 typedef struct PgStat_MsgTabpurge
161 Oid m_tableid[PGSTAT_NUM_TABPURGE];
162 } PgStat_MsgTabpurge;
166 * PgStat_MsgDropdb Sent by the backend to tell the collector
167 * about dropped database
170 typedef struct PgStat_MsgDropdb
178 * PgStat_MsgResetcounter Sent by the backend to tell the collector
182 typedef struct PgStat_MsgResetcounter
186 } PgStat_MsgResetcounter;
190 * PgStat_Msg Union over all possible messages.
193 typedef union PgStat_Msg
195 PgStat_MsgHdr msg_hdr;
196 PgStat_MsgDummy msg_dummy;
197 PgStat_MsgBestart msg_bestart;
198 PgStat_MsgActivity msg_activity;
199 PgStat_MsgTabstat msg_tabstat;
200 PgStat_MsgTabpurge msg_tabpurge;
201 PgStat_MsgDropdb msg_dropdb;
202 PgStat_MsgResetcounter msg_resetcounter;
206 /* ------------------------------------------------------------
207 * Statistic collector data structures follow
208 * ------------------------------------------------------------
212 * PgStat_StatDBEntry The collectors data per database
215 typedef struct PgStat_StatDBEntry
220 PgStat_Counter n_xact_commit;
221 PgStat_Counter n_xact_rollback;
222 PgStat_Counter n_blocks_fetched;
223 PgStat_Counter n_blocks_hit;
225 } PgStat_StatDBEntry;
229 * PgStat_StatBeEntry The collectors data per backend
232 typedef struct PgStat_StatBeEntry
234 /* An entry is non-empty iff procpid > 0 */
236 AbsoluteTime start_sec;
238 AbsoluteTime activity_start_sec;
239 int activity_start_usec;
240 char activity[PGSTAT_ACTIVITY_SIZE];
243 * The following fields are initialized by the BESTART message. If
244 * we have received messages from a backend before we have
245 * received its BESTART, these fields will be uninitialized:
246 * userid and databaseid will be InvalidOid, and clientaddr will
252 } PgStat_StatBeEntry;
256 * PgStat_StatBeDead Because UDP packets can arrive out of
257 * order, we need to keep some information
258 * about backends that are known to be
259 * dead for some seconds. This info is held
260 * in a hash table of these structs.
263 typedef struct PgStat_StatBeDead
272 * PgStat_StatTabEntry The collectors data table data
275 typedef struct PgStat_StatTabEntry
279 PgStat_Counter numscans;
281 PgStat_Counter tuples_returned;
282 PgStat_Counter tuples_fetched;
283 PgStat_Counter tuples_inserted;
284 PgStat_Counter tuples_updated;
285 PgStat_Counter tuples_deleted;
287 PgStat_Counter blocks_fetched;
288 PgStat_Counter blocks_hit;
291 } PgStat_StatTabEntry;
298 extern bool pgstat_collect_startcollector;
299 extern bool pgstat_collect_resetonpmstart;
300 extern bool pgstat_collect_querystring;
301 extern bool pgstat_collect_tuplelevel;
302 extern bool pgstat_collect_blocklevel;
306 * Functions called from postmaster
309 extern void pgstat_init(void);
310 extern int pgstat_start(void);
311 extern void pgstat_beterm(int pid);
314 extern void PgstatBufferMain(int argc, char *argv[]);
315 extern void PgstatCollectorMain(int argc, char *argv[]);
320 * Functions called from backends
323 extern void pgstat_bestart(void);
325 extern void pgstat_ping(void);
326 extern void pgstat_report_activity(const char *what);
327 extern void pgstat_report_tabstat(void);
328 extern int pgstat_vacuum_tabstat(void);
330 extern void pgstat_reset_counters(void);
332 extern void pgstat_initstats(PgStat_Info *stats, Relation rel);
335 #define pgstat_reset_heap_scan(s) \
337 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
338 (s)->heap_scan_counted = FALSE; \
340 #define pgstat_count_heap_scan(s) \
342 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL && \
343 !(s)->heap_scan_counted) { \
344 ((PgStat_TableEntry *)((s)->tabentry))->t_numscans++; \
345 (s)->heap_scan_counted = TRUE; \
348 #define pgstat_count_heap_getnext(s) \
350 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
351 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_returned++; \
353 #define pgstat_count_heap_fetch(s) \
355 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
356 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_fetched++; \
358 #define pgstat_count_heap_insert(s) \
360 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
361 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_inserted++; \
363 #define pgstat_count_heap_update(s) \
365 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
366 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_updated++; \
368 #define pgstat_count_heap_delete(s) \
370 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
371 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_deleted++; \
373 #define pgstat_reset_index_scan(s) \
375 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
376 (s)->index_scan_counted = FALSE; \
378 #define pgstat_count_index_scan(s) \
380 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL && \
381 !(s)->index_scan_counted) { \
382 ((PgStat_TableEntry *)((s)->tabentry))->t_numscans++; \
383 (s)->index_scan_counted = TRUE; \
386 #define pgstat_count_index_getnext(s) \
388 if (pgstat_collect_tuplelevel && (s)->tabentry != NULL) \
389 ((PgStat_TableEntry *)((s)->tabentry))->t_tuples_returned++; \
391 #define pgstat_count_buffer_read(s,r) \
393 if (pgstat_collect_blocklevel && (s)->tabentry != NULL) \
394 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_fetched++; \
396 if (pgstat_collect_blocklevel && !(s)->no_stats) { \
397 pgstat_initstats((s), (r)); \
398 if ((s)->tabentry != NULL) \
399 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_fetched++; \
403 #define pgstat_count_buffer_hit(s,r) \
405 if (pgstat_collect_blocklevel && (s)->tabentry != NULL) \
406 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_hit++; \
408 if (pgstat_collect_blocklevel && !(s)->no_stats) { \
409 pgstat_initstats((s), (r)); \
410 if ((s)->tabentry != NULL) \
411 ((PgStat_TableEntry *)((s)->tabentry))->t_blocks_hit++; \
417 extern void pgstat_count_xact_commit(void);
418 extern void pgstat_count_xact_rollback(void);
421 * Support functions for the SQL-callable functions to
422 * generate the pgstat* views.
425 extern PgStat_StatDBEntry *pgstat_fetch_stat_dbentry(Oid dbid);
426 extern PgStat_StatTabEntry *pgstat_fetch_stat_tabentry(Oid relid);
427 extern PgStat_StatBeEntry *pgstat_fetch_stat_beentry(int beid);
428 extern int pgstat_fetch_stat_numbackends(void);
430 #endif /* PGSTAT_H */