Header And Logo

PostgreSQL
| The world's most advanced open source database.

pgstat.h

Go to the documentation of this file.
00001 /* ----------
00002  *  pgstat.h
00003  *
00004  *  Definitions for the PostgreSQL statistics collector daemon.
00005  *
00006  *  Copyright (c) 2001-2013, PostgreSQL Global Development Group
00007  *
00008  *  src/include/pgstat.h
00009  * ----------
00010  */
00011 #ifndef PGSTAT_H
00012 #define PGSTAT_H
00013 
00014 #include "datatype/timestamp.h"
00015 #include "fmgr.h"
00016 #include "libpq/pqcomm.h"
00017 #include "portability/instr_time.h"
00018 #include "utils/hsearch.h"
00019 #include "utils/relcache.h"
00020 
00021 
00022 /* Values for track_functions GUC variable --- order is significant! */
00023 typedef enum TrackFunctionsLevel
00024 {
00025     TRACK_FUNC_OFF,
00026     TRACK_FUNC_PL,
00027     TRACK_FUNC_ALL
00028 }   TrackFunctionsLevel;
00029 
00030 /* ----------
00031  * The types of backend -> collector messages
00032  * ----------
00033  */
00034 typedef enum StatMsgType
00035 {
00036     PGSTAT_MTYPE_DUMMY,
00037     PGSTAT_MTYPE_INQUIRY,
00038     PGSTAT_MTYPE_TABSTAT,
00039     PGSTAT_MTYPE_TABPURGE,
00040     PGSTAT_MTYPE_DROPDB,
00041     PGSTAT_MTYPE_RESETCOUNTER,
00042     PGSTAT_MTYPE_RESETSHAREDCOUNTER,
00043     PGSTAT_MTYPE_RESETSINGLECOUNTER,
00044     PGSTAT_MTYPE_AUTOVAC_START,
00045     PGSTAT_MTYPE_VACUUM,
00046     PGSTAT_MTYPE_ANALYZE,
00047     PGSTAT_MTYPE_BGWRITER,
00048     PGSTAT_MTYPE_FUNCSTAT,
00049     PGSTAT_MTYPE_FUNCPURGE,
00050     PGSTAT_MTYPE_RECOVERYCONFLICT,
00051     PGSTAT_MTYPE_TEMPFILE,
00052     PGSTAT_MTYPE_DEADLOCK
00053 } StatMsgType;
00054 
00055 /* ----------
00056  * The data type used for counters.
00057  * ----------
00058  */
00059 typedef int64 PgStat_Counter;
00060 
00061 /* ----------
00062  * PgStat_TableCounts           The actual per-table counts kept by a backend
00063  *
00064  * This struct should contain only actual event counters, because we memcmp
00065  * it against zeroes to detect whether there are any counts to transmit.
00066  * It is a component of PgStat_TableStatus (within-backend state) and
00067  * PgStat_TableEntry (the transmitted message format).
00068  *
00069  * Note: for a table, tuples_returned is the number of tuples successfully
00070  * fetched by heap_getnext, while tuples_fetched is the number of tuples
00071  * successfully fetched by heap_fetch under the control of bitmap indexscans.
00072  * For an index, tuples_returned is the number of index entries returned by
00073  * the index AM, while tuples_fetched is the number of tuples successfully
00074  * fetched by heap_fetch under the control of simple indexscans for this index.
00075  *
00076  * tuples_inserted/updated/deleted/hot_updated count attempted actions,
00077  * regardless of whether the transaction committed.  delta_live_tuples,
00078  * delta_dead_tuples, and changed_tuples are set depending on commit or abort.
00079  * Note that delta_live_tuples and delta_dead_tuples can be negative!
00080  * ----------
00081  */
00082 typedef struct PgStat_TableCounts
00083 {
00084     PgStat_Counter t_numscans;
00085 
00086     PgStat_Counter t_tuples_returned;
00087     PgStat_Counter t_tuples_fetched;
00088 
00089     PgStat_Counter t_tuples_inserted;
00090     PgStat_Counter t_tuples_updated;
00091     PgStat_Counter t_tuples_deleted;
00092     PgStat_Counter t_tuples_hot_updated;
00093 
00094     PgStat_Counter t_delta_live_tuples;
00095     PgStat_Counter t_delta_dead_tuples;
00096     PgStat_Counter t_changed_tuples;
00097 
00098     PgStat_Counter t_blocks_fetched;
00099     PgStat_Counter t_blocks_hit;
00100 } PgStat_TableCounts;
00101 
00102 /* Possible targets for resetting cluster-wide shared values */
00103 typedef enum PgStat_Shared_Reset_Target
00104 {
00105     RESET_BGWRITER
00106 } PgStat_Shared_Reset_Target;
00107 
00108 /* Possible object types for resetting single counters */
00109 typedef enum PgStat_Single_Reset_Type
00110 {
00111     RESET_TABLE,
00112     RESET_FUNCTION
00113 } PgStat_Single_Reset_Type;
00114 
00115 /* ------------------------------------------------------------
00116  * Structures kept in backend local memory while accumulating counts
00117  * ------------------------------------------------------------
00118  */
00119 
00120 
00121 /* ----------
00122  * PgStat_TableStatus           Per-table status within a backend
00123  *
00124  * Many of the event counters are nontransactional, ie, we count events
00125  * in committed and aborted transactions alike.  For these, we just count
00126  * directly in the PgStat_TableStatus.  However, delta_live_tuples,
00127  * delta_dead_tuples, and changed_tuples must be derived from event counts
00128  * with awareness of whether the transaction or subtransaction committed or
00129  * aborted.  Hence, we also keep a stack of per-(sub)transaction status
00130  * records for every table modified in the current transaction.  At commit
00131  * or abort, we propagate tuples_inserted/updated/deleted up to the
00132  * parent subtransaction level, or out to the parent PgStat_TableStatus,
00133  * as appropriate.
00134  * ----------
00135  */
00136 typedef struct PgStat_TableStatus
00137 {
00138     Oid         t_id;           /* table's OID */
00139     bool        t_shared;       /* is it a shared catalog? */
00140     struct PgStat_TableXactStatus *trans;       /* lowest subxact's counts */
00141     PgStat_TableCounts t_counts;    /* event counts to be sent */
00142 } PgStat_TableStatus;
00143 
00144 /* ----------
00145  * PgStat_TableXactStatus       Per-table, per-subtransaction status
00146  * ----------
00147  */
00148 typedef struct PgStat_TableXactStatus
00149 {
00150     PgStat_Counter tuples_inserted;     /* tuples inserted in (sub)xact */
00151     PgStat_Counter tuples_updated;      /* tuples updated in (sub)xact */
00152     PgStat_Counter tuples_deleted;      /* tuples deleted in (sub)xact */
00153     int         nest_level;     /* subtransaction nest level */
00154     /* links to other structs for same relation: */
00155     struct PgStat_TableXactStatus *upper;       /* next higher subxact if any */
00156     PgStat_TableStatus *parent; /* per-table status */
00157     /* structs of same subxact level are linked here: */
00158     struct PgStat_TableXactStatus *next;        /* next of same subxact */
00159 } PgStat_TableXactStatus;
00160 
00161 
00162 /* ------------------------------------------------------------
00163  * Message formats follow
00164  * ------------------------------------------------------------
00165  */
00166 
00167 
00168 /* ----------
00169  * PgStat_MsgHdr                The common message header
00170  * ----------
00171  */
00172 typedef struct PgStat_MsgHdr
00173 {
00174     StatMsgType m_type;
00175     int         m_size;
00176 } PgStat_MsgHdr;
00177 
00178 /* ----------
00179  * Space available in a message.  This will keep the UDP packets below 1K,
00180  * which should fit unfragmented into the MTU of the lo interface on most
00181  * platforms. Does anybody care for platforms where it doesn't?
00182  * ----------
00183  */
00184 #define PGSTAT_MSG_PAYLOAD  (1000 - sizeof(PgStat_MsgHdr))
00185 
00186 
00187 /* ----------
00188  * PgStat_MsgDummy              A dummy message, ignored by the collector
00189  * ----------
00190  */
00191 typedef struct PgStat_MsgDummy
00192 {
00193     PgStat_MsgHdr m_hdr;
00194 } PgStat_MsgDummy;
00195 
00196 
00197 /* ----------
00198  * PgStat_MsgInquiry            Sent by a backend to ask the collector
00199  *                              to write the stats file.
00200  * ----------
00201  */
00202 
00203 typedef struct PgStat_MsgInquiry
00204 {
00205     PgStat_MsgHdr m_hdr;
00206     TimestampTz clock_time;     /* observed local clock time */
00207     TimestampTz cutoff_time;    /* minimum acceptable file timestamp */
00208     Oid         databaseid;     /* requested DB (InvalidOid => all DBs) */
00209 } PgStat_MsgInquiry;
00210 
00211 
00212 /* ----------
00213  * PgStat_TableEntry            Per-table info in a MsgTabstat
00214  * ----------
00215  */
00216 typedef struct PgStat_TableEntry
00217 {
00218     Oid         t_id;
00219     PgStat_TableCounts t_counts;
00220 } PgStat_TableEntry;
00221 
00222 /* ----------
00223  * PgStat_MsgTabstat            Sent by the backend to report table
00224  *                              and buffer access statistics.
00225  * ----------
00226  */
00227 #define PGSTAT_NUM_TABENTRIES  \
00228     ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - 3 * sizeof(int))  \
00229      / sizeof(PgStat_TableEntry))
00230 
00231 typedef struct PgStat_MsgTabstat
00232 {
00233     PgStat_MsgHdr m_hdr;
00234     Oid         m_databaseid;
00235     int         m_nentries;
00236     int         m_xact_commit;
00237     int         m_xact_rollback;
00238     PgStat_Counter m_block_read_time;   /* times in microseconds */
00239     PgStat_Counter m_block_write_time;
00240     PgStat_TableEntry m_entry[PGSTAT_NUM_TABENTRIES];
00241 } PgStat_MsgTabstat;
00242 
00243 
00244 /* ----------
00245  * PgStat_MsgTabpurge           Sent by the backend to tell the collector
00246  *                              about dead tables.
00247  * ----------
00248  */
00249 #define PGSTAT_NUM_TABPURGE  \
00250     ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - sizeof(int))  \
00251      / sizeof(Oid))
00252 
00253 typedef struct PgStat_MsgTabpurge
00254 {
00255     PgStat_MsgHdr m_hdr;
00256     Oid         m_databaseid;
00257     int         m_nentries;
00258     Oid         m_tableid[PGSTAT_NUM_TABPURGE];
00259 } PgStat_MsgTabpurge;
00260 
00261 
00262 /* ----------
00263  * PgStat_MsgDropdb             Sent by the backend to tell the collector
00264  *                              about a dropped database
00265  * ----------
00266  */
00267 typedef struct PgStat_MsgDropdb
00268 {
00269     PgStat_MsgHdr m_hdr;
00270     Oid         m_databaseid;
00271 } PgStat_MsgDropdb;
00272 
00273 
00274 /* ----------
00275  * PgStat_MsgResetcounter       Sent by the backend to tell the collector
00276  *                              to reset counters
00277  * ----------
00278  */
00279 typedef struct PgStat_MsgResetcounter
00280 {
00281     PgStat_MsgHdr m_hdr;
00282     Oid         m_databaseid;
00283 } PgStat_MsgResetcounter;
00284 
00285 /* ----------
00286  * PgStat_MsgResetsharedcounter Sent by the backend to tell the collector
00287  *                              to reset a shared counter
00288  * ----------
00289  */
00290 typedef struct PgStat_MsgResetsharedcounter
00291 {
00292     PgStat_MsgHdr m_hdr;
00293     PgStat_Shared_Reset_Target m_resettarget;
00294 } PgStat_MsgResetsharedcounter;
00295 
00296 /* ----------
00297  * PgStat_MsgResetsinglecounter Sent by the backend to tell the collector
00298  *                              to reset a single counter
00299  * ----------
00300  */
00301 typedef struct PgStat_MsgResetsinglecounter
00302 {
00303     PgStat_MsgHdr m_hdr;
00304     Oid         m_databaseid;
00305     PgStat_Single_Reset_Type m_resettype;
00306     Oid         m_objectid;
00307 } PgStat_MsgResetsinglecounter;
00308 
00309 /* ----------
00310  * PgStat_MsgAutovacStart       Sent by the autovacuum daemon to signal
00311  *                              that a database is going to be processed
00312  * ----------
00313  */
00314 typedef struct PgStat_MsgAutovacStart
00315 {
00316     PgStat_MsgHdr m_hdr;
00317     Oid         m_databaseid;
00318     TimestampTz m_start_time;
00319 } PgStat_MsgAutovacStart;
00320 
00321 
00322 /* ----------
00323  * PgStat_MsgVacuum             Sent by the backend or autovacuum daemon
00324  *                              after VACUUM
00325  * ----------
00326  */
00327 typedef struct PgStat_MsgVacuum
00328 {
00329     PgStat_MsgHdr m_hdr;
00330     Oid         m_databaseid;
00331     Oid         m_tableoid;
00332     bool        m_autovacuum;
00333     TimestampTz m_vacuumtime;
00334     PgStat_Counter m_tuples;
00335 } PgStat_MsgVacuum;
00336 
00337 
00338 /* ----------
00339  * PgStat_MsgAnalyze            Sent by the backend or autovacuum daemon
00340  *                              after ANALYZE
00341  * ----------
00342  */
00343 typedef struct PgStat_MsgAnalyze
00344 {
00345     PgStat_MsgHdr m_hdr;
00346     Oid         m_databaseid;
00347     Oid         m_tableoid;
00348     bool        m_autovacuum;
00349     TimestampTz m_analyzetime;
00350     PgStat_Counter m_live_tuples;
00351     PgStat_Counter m_dead_tuples;
00352 } PgStat_MsgAnalyze;
00353 
00354 
00355 /* ----------
00356  * PgStat_MsgBgWriter           Sent by the bgwriter to update statistics.
00357  * ----------
00358  */
00359 typedef struct PgStat_MsgBgWriter
00360 {
00361     PgStat_MsgHdr m_hdr;
00362 
00363     PgStat_Counter m_timed_checkpoints;
00364     PgStat_Counter m_requested_checkpoints;
00365     PgStat_Counter m_buf_written_checkpoints;
00366     PgStat_Counter m_buf_written_clean;
00367     PgStat_Counter m_maxwritten_clean;
00368     PgStat_Counter m_buf_written_backend;
00369     PgStat_Counter m_buf_fsync_backend;
00370     PgStat_Counter m_buf_alloc;
00371     PgStat_Counter m_checkpoint_write_time;     /* times in milliseconds */
00372     PgStat_Counter m_checkpoint_sync_time;
00373 } PgStat_MsgBgWriter;
00374 
00375 /* ----------
00376  * PgStat_MsgRecoveryConflict   Sent by the backend upon recovery conflict
00377  * ----------
00378  */
00379 typedef struct PgStat_MsgRecoveryConflict
00380 {
00381     PgStat_MsgHdr m_hdr;
00382 
00383     Oid         m_databaseid;
00384     int         m_reason;
00385 } PgStat_MsgRecoveryConflict;
00386 
00387 /* ----------
00388  * PgStat_MsgTempFile   Sent by the backend upon creating a temp file
00389  * ----------
00390  */
00391 typedef struct PgStat_MsgTempFile
00392 {
00393     PgStat_MsgHdr m_hdr;
00394 
00395     Oid         m_databaseid;
00396     size_t      m_filesize;
00397 } PgStat_MsgTempFile;
00398 
00399 /* ----------
00400  * PgStat_FunctionCounts    The actual per-function counts kept by a backend
00401  *
00402  * This struct should contain only actual event counters, because we memcmp
00403  * it against zeroes to detect whether there are any counts to transmit.
00404  *
00405  * Note that the time counters are in instr_time format here.  We convert to
00406  * microseconds in PgStat_Counter format when transmitting to the collector.
00407  * ----------
00408  */
00409 typedef struct PgStat_FunctionCounts
00410 {
00411     PgStat_Counter f_numcalls;
00412     instr_time  f_total_time;
00413     instr_time  f_self_time;
00414 } PgStat_FunctionCounts;
00415 
00416 /* ----------
00417  * PgStat_BackendFunctionEntry  Entry in backend's per-function hash table
00418  * ----------
00419  */
00420 typedef struct PgStat_BackendFunctionEntry
00421 {
00422     Oid         f_id;
00423     PgStat_FunctionCounts f_counts;
00424 } PgStat_BackendFunctionEntry;
00425 
00426 /* ----------
00427  * PgStat_FunctionEntry         Per-function info in a MsgFuncstat
00428  * ----------
00429  */
00430 typedef struct PgStat_FunctionEntry
00431 {
00432     Oid         f_id;
00433     PgStat_Counter f_numcalls;
00434     PgStat_Counter f_total_time;    /* times in microseconds */
00435     PgStat_Counter f_self_time;
00436 } PgStat_FunctionEntry;
00437 
00438 /* ----------
00439  * PgStat_MsgFuncstat           Sent by the backend to report function
00440  *                              usage statistics.
00441  * ----------
00442  */
00443 #define PGSTAT_NUM_FUNCENTRIES  \
00444     ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - sizeof(int))  \
00445      / sizeof(PgStat_FunctionEntry))
00446 
00447 typedef struct PgStat_MsgFuncstat
00448 {
00449     PgStat_MsgHdr m_hdr;
00450     Oid         m_databaseid;
00451     int         m_nentries;
00452     PgStat_FunctionEntry m_entry[PGSTAT_NUM_FUNCENTRIES];
00453 } PgStat_MsgFuncstat;
00454 
00455 /* ----------
00456  * PgStat_MsgFuncpurge          Sent by the backend to tell the collector
00457  *                              about dead functions.
00458  * ----------
00459  */
00460 #define PGSTAT_NUM_FUNCPURGE  \
00461     ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - sizeof(int))  \
00462      / sizeof(Oid))
00463 
00464 typedef struct PgStat_MsgFuncpurge
00465 {
00466     PgStat_MsgHdr m_hdr;
00467     Oid         m_databaseid;
00468     int         m_nentries;
00469     Oid         m_functionid[PGSTAT_NUM_FUNCPURGE];
00470 } PgStat_MsgFuncpurge;
00471 
00472 /* ----------
00473  * PgStat_MsgDeadlock           Sent by the backend to tell the collector
00474  *                              about a deadlock that occurred.
00475  * ----------
00476  */
00477 typedef struct PgStat_MsgDeadlock
00478 {
00479     PgStat_MsgHdr m_hdr;
00480     Oid         m_databaseid;
00481 } PgStat_MsgDeadlock;
00482 
00483 
00484 /* ----------
00485  * PgStat_Msg                   Union over all possible messages.
00486  * ----------
00487  */
00488 typedef union PgStat_Msg
00489 {
00490     PgStat_MsgHdr msg_hdr;
00491     PgStat_MsgDummy msg_dummy;
00492     PgStat_MsgInquiry msg_inquiry;
00493     PgStat_MsgTabstat msg_tabstat;
00494     PgStat_MsgTabpurge msg_tabpurge;
00495     PgStat_MsgDropdb msg_dropdb;
00496     PgStat_MsgResetcounter msg_resetcounter;
00497     PgStat_MsgResetsharedcounter msg_resetsharedcounter;
00498     PgStat_MsgResetsinglecounter msg_resetsinglecounter;
00499     PgStat_MsgAutovacStart msg_autovacuum;
00500     PgStat_MsgVacuum msg_vacuum;
00501     PgStat_MsgAnalyze msg_analyze;
00502     PgStat_MsgBgWriter msg_bgwriter;
00503     PgStat_MsgFuncstat msg_funcstat;
00504     PgStat_MsgFuncpurge msg_funcpurge;
00505     PgStat_MsgRecoveryConflict msg_recoveryconflict;
00506     PgStat_MsgDeadlock msg_deadlock;
00507 } PgStat_Msg;
00508 
00509 
00510 /* ------------------------------------------------------------
00511  * Statistic collector data structures follow
00512  *
00513  * PGSTAT_FILE_FORMAT_ID should be changed whenever any of these
00514  * data structures change.
00515  * ------------------------------------------------------------
00516  */
00517 
00518 #define PGSTAT_FILE_FORMAT_ID   0x01A5BC9B
00519 
00520 /* ----------
00521  * PgStat_StatDBEntry           The collector's data per database
00522  * ----------
00523  */
00524 typedef struct PgStat_StatDBEntry
00525 {
00526     Oid         databaseid;
00527     PgStat_Counter n_xact_commit;
00528     PgStat_Counter n_xact_rollback;
00529     PgStat_Counter n_blocks_fetched;
00530     PgStat_Counter n_blocks_hit;
00531     PgStat_Counter n_tuples_returned;
00532     PgStat_Counter n_tuples_fetched;
00533     PgStat_Counter n_tuples_inserted;
00534     PgStat_Counter n_tuples_updated;
00535     PgStat_Counter n_tuples_deleted;
00536     TimestampTz last_autovac_time;
00537     PgStat_Counter n_conflict_tablespace;
00538     PgStat_Counter n_conflict_lock;
00539     PgStat_Counter n_conflict_snapshot;
00540     PgStat_Counter n_conflict_bufferpin;
00541     PgStat_Counter n_conflict_startup_deadlock;
00542     PgStat_Counter n_temp_files;
00543     PgStat_Counter n_temp_bytes;
00544     PgStat_Counter n_deadlocks;
00545     PgStat_Counter n_block_read_time;   /* times in microseconds */
00546     PgStat_Counter n_block_write_time;
00547 
00548     TimestampTz stat_reset_timestamp;
00549     TimestampTz stats_timestamp;    /* time of db stats file update */
00550 
00551     /*
00552      * tables and functions must be last in the struct, because we don't write
00553      * the pointers out to the stats file.
00554      */
00555     HTAB       *tables;
00556     HTAB       *functions;
00557 } PgStat_StatDBEntry;
00558 
00559 
00560 /* ----------
00561  * PgStat_StatTabEntry          The collector's data per table (or index)
00562  * ----------
00563  */
00564 typedef struct PgStat_StatTabEntry
00565 {
00566     Oid         tableid;
00567 
00568     PgStat_Counter numscans;
00569 
00570     PgStat_Counter tuples_returned;
00571     PgStat_Counter tuples_fetched;
00572 
00573     PgStat_Counter tuples_inserted;
00574     PgStat_Counter tuples_updated;
00575     PgStat_Counter tuples_deleted;
00576     PgStat_Counter tuples_hot_updated;
00577 
00578     PgStat_Counter n_live_tuples;
00579     PgStat_Counter n_dead_tuples;
00580     PgStat_Counter changes_since_analyze;
00581 
00582     PgStat_Counter blocks_fetched;
00583     PgStat_Counter blocks_hit;
00584 
00585     TimestampTz vacuum_timestamp;       /* user initiated vacuum */
00586     PgStat_Counter vacuum_count;
00587     TimestampTz autovac_vacuum_timestamp;       /* autovacuum initiated */
00588     PgStat_Counter autovac_vacuum_count;
00589     TimestampTz analyze_timestamp;      /* user initiated */
00590     PgStat_Counter analyze_count;
00591     TimestampTz autovac_analyze_timestamp;      /* autovacuum initiated */
00592     PgStat_Counter autovac_analyze_count;
00593 } PgStat_StatTabEntry;
00594 
00595 
00596 /* ----------
00597  * PgStat_StatFuncEntry         The collector's data per function
00598  * ----------
00599  */
00600 typedef struct PgStat_StatFuncEntry
00601 {
00602     Oid         functionid;
00603 
00604     PgStat_Counter f_numcalls;
00605 
00606     PgStat_Counter f_total_time;    /* times in microseconds */
00607     PgStat_Counter f_self_time;
00608 } PgStat_StatFuncEntry;
00609 
00610 
00611 /*
00612  * Global statistics kept in the stats collector
00613  */
00614 typedef struct PgStat_GlobalStats
00615 {
00616     TimestampTz stats_timestamp;    /* time of stats file update */
00617     PgStat_Counter timed_checkpoints;
00618     PgStat_Counter requested_checkpoints;
00619     PgStat_Counter checkpoint_write_time;       /* times in milliseconds */
00620     PgStat_Counter checkpoint_sync_time;
00621     PgStat_Counter buf_written_checkpoints;
00622     PgStat_Counter buf_written_clean;
00623     PgStat_Counter maxwritten_clean;
00624     PgStat_Counter buf_written_backend;
00625     PgStat_Counter buf_fsync_backend;
00626     PgStat_Counter buf_alloc;
00627     TimestampTz stat_reset_timestamp;
00628 } PgStat_GlobalStats;
00629 
00630 
00631 /* ----------
00632  * Backend states
00633  * ----------
00634  */
00635 typedef enum BackendState
00636 {
00637     STATE_UNDEFINED,
00638     STATE_IDLE,
00639     STATE_RUNNING,
00640     STATE_IDLEINTRANSACTION,
00641     STATE_FASTPATH,
00642     STATE_IDLEINTRANSACTION_ABORTED,
00643     STATE_DISABLED,
00644 } BackendState;
00645 
00646 /* ----------
00647  * Shared-memory data structures
00648  * ----------
00649  */
00650 
00651 
00652 /* ----------
00653  * PgBackendStatus
00654  *
00655  * Each live backend maintains a PgBackendStatus struct in shared memory
00656  * showing its current activity.  (The structs are allocated according to
00657  * BackendId, but that is not critical.)  Note that the collector process
00658  * has no involvement in, or even access to, these structs.
00659  * ----------
00660  */
00661 typedef struct PgBackendStatus
00662 {
00663     /*
00664      * To avoid locking overhead, we use the following protocol: a backend
00665      * increments st_changecount before modifying its entry, and again after
00666      * finishing a modification.  A would-be reader should note the value of
00667      * st_changecount, copy the entry into private memory, then check
00668      * st_changecount again.  If the value hasn't changed, and if it's even,
00669      * the copy is valid; otherwise start over.  This makes updates cheap
00670      * while reads are potentially expensive, but that's the tradeoff we want.
00671      */
00672     int         st_changecount;
00673 
00674     /* The entry is valid iff st_procpid > 0, unused if st_procpid == 0 */
00675     int         st_procpid;
00676 
00677     /* Times when current backend, transaction, and activity started */
00678     TimestampTz st_proc_start_timestamp;
00679     TimestampTz st_xact_start_timestamp;
00680     TimestampTz st_activity_start_timestamp;
00681     TimestampTz st_state_start_timestamp;
00682 
00683     /* Database OID, owning user's OID, connection client address */
00684     Oid         st_databaseid;
00685     Oid         st_userid;
00686     SockAddr    st_clientaddr;
00687     char       *st_clienthostname;      /* MUST be null-terminated */
00688 
00689     /* Is backend currently waiting on an lmgr lock? */
00690     bool        st_waiting;
00691 
00692     /* current state */
00693     BackendState st_state;
00694 
00695     /* application name; MUST be null-terminated */
00696     char       *st_appname;
00697 
00698     /* current command string; MUST be null-terminated */
00699     char       *st_activity;
00700 } PgBackendStatus;
00701 
00702 /*
00703  * Working state needed to accumulate per-function-call timing statistics.
00704  */
00705 typedef struct PgStat_FunctionCallUsage
00706 {
00707     /* Link to function's hashtable entry (must still be there at exit!) */
00708     /* NULL means we are not tracking the current function call */
00709     PgStat_FunctionCounts *fs;
00710     /* Total time previously charged to function, as of function start */
00711     instr_time  save_f_total_time;
00712     /* Backend-wide total time as of function start */
00713     instr_time  save_total;
00714     /* system clock as of function start */
00715     instr_time  f_start;
00716 } PgStat_FunctionCallUsage;
00717 
00718 
00719 /* ----------
00720  * GUC parameters
00721  * ----------
00722  */
00723 extern bool pgstat_track_activities;
00724 extern bool pgstat_track_counts;
00725 extern int  pgstat_track_functions;
00726 extern PGDLLIMPORT int pgstat_track_activity_query_size;
00727 extern char *pgstat_stat_directory;
00728 extern char *pgstat_stat_tmpname;
00729 extern char *pgstat_stat_filename;
00730 
00731 /*
00732  * BgWriter statistics counters are updated directly by bgwriter and bufmgr
00733  */
00734 extern PgStat_MsgBgWriter BgWriterStats;
00735 
00736 /*
00737  * Updated by pgstat_count_buffer_*_time macros
00738  */
00739 extern PgStat_Counter pgStatBlockReadTime;
00740 extern PgStat_Counter pgStatBlockWriteTime;
00741 
00742 /* ----------
00743  * Functions called from postmaster
00744  * ----------
00745  */
00746 extern Size BackendStatusShmemSize(void);
00747 extern void CreateSharedBackendStatus(void);
00748 
00749 extern void pgstat_init(void);
00750 extern int  pgstat_start(void);
00751 extern void pgstat_reset_all(void);
00752 extern void allow_immediate_pgstat_restart(void);
00753 
00754 #ifdef EXEC_BACKEND
00755 extern void PgstatCollectorMain(int argc, char *argv[]) __attribute__((noreturn));
00756 #endif
00757 
00758 
00759 /* ----------
00760  * Functions called from backends
00761  * ----------
00762  */
00763 extern void pgstat_ping(void);
00764 
00765 extern void pgstat_report_stat(bool force);
00766 extern void pgstat_vacuum_stat(void);
00767 extern void pgstat_drop_database(Oid databaseid);
00768 
00769 extern void pgstat_clear_snapshot(void);
00770 extern void pgstat_reset_counters(void);
00771 extern void pgstat_reset_shared_counters(const char *);
00772 extern void pgstat_reset_single_counter(Oid objectid, PgStat_Single_Reset_Type type);
00773 
00774 extern void pgstat_report_autovac(Oid dboid);
00775 extern void pgstat_report_vacuum(Oid tableoid, bool shared,
00776                      PgStat_Counter tuples);
00777 extern void pgstat_report_analyze(Relation rel,
00778                       PgStat_Counter livetuples, PgStat_Counter deadtuples);
00779 
00780 extern void pgstat_report_recovery_conflict(int reason);
00781 extern void pgstat_report_deadlock(void);
00782 
00783 extern void pgstat_initialize(void);
00784 extern void pgstat_bestart(void);
00785 
00786 extern void pgstat_report_activity(BackendState state, const char *cmd_str);
00787 extern void pgstat_report_tempfile(size_t filesize);
00788 extern void pgstat_report_appname(const char *appname);
00789 extern void pgstat_report_xact_timestamp(TimestampTz tstamp);
00790 extern void pgstat_report_waiting(bool waiting);
00791 extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser);
00792 extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer,
00793                                     int buflen);
00794 
00795 extern PgStat_TableStatus *find_tabstat_entry(Oid rel_id);
00796 extern PgStat_BackendFunctionEntry *find_funcstat_entry(Oid func_id);
00797 
00798 extern void pgstat_initstats(Relation rel);
00799 
00800 /* nontransactional event counts are simple enough to inline */
00801 
00802 #define pgstat_count_heap_scan(rel)                                 \
00803     do {                                                            \
00804         if ((rel)->pgstat_info != NULL)                             \
00805             (rel)->pgstat_info->t_counts.t_numscans++;              \
00806     } while (0)
00807 #define pgstat_count_heap_getnext(rel)                              \
00808     do {                                                            \
00809         if ((rel)->pgstat_info != NULL)                             \
00810             (rel)->pgstat_info->t_counts.t_tuples_returned++;       \
00811     } while (0)
00812 #define pgstat_count_heap_fetch(rel)                                \
00813     do {                                                            \
00814         if ((rel)->pgstat_info != NULL)                             \
00815             (rel)->pgstat_info->t_counts.t_tuples_fetched++;        \
00816     } while (0)
00817 #define pgstat_count_index_scan(rel)                                \
00818     do {                                                            \
00819         if ((rel)->pgstat_info != NULL)                             \
00820             (rel)->pgstat_info->t_counts.t_numscans++;              \
00821     } while (0)
00822 #define pgstat_count_index_tuples(rel, n)                           \
00823     do {                                                            \
00824         if ((rel)->pgstat_info != NULL)                             \
00825             (rel)->pgstat_info->t_counts.t_tuples_returned += (n);  \
00826     } while (0)
00827 #define pgstat_count_buffer_read(rel)                               \
00828     do {                                                            \
00829         if ((rel)->pgstat_info != NULL)                             \
00830             (rel)->pgstat_info->t_counts.t_blocks_fetched++;        \
00831     } while (0)
00832 #define pgstat_count_buffer_hit(rel)                                \
00833     do {                                                            \
00834         if ((rel)->pgstat_info != NULL)                             \
00835             (rel)->pgstat_info->t_counts.t_blocks_hit++;            \
00836     } while (0)
00837 #define pgstat_count_buffer_read_time(n)                            \
00838     (pgStatBlockReadTime += (n))
00839 #define pgstat_count_buffer_write_time(n)                           \
00840     (pgStatBlockWriteTime += (n))
00841 
00842 extern void pgstat_count_heap_insert(Relation rel, int n);
00843 extern void pgstat_count_heap_update(Relation rel, bool hot);
00844 extern void pgstat_count_heap_delete(Relation rel);
00845 extern void pgstat_update_heap_dead_tuples(Relation rel, int delta);
00846 
00847 extern void pgstat_init_function_usage(FunctionCallInfoData *fcinfo,
00848                            PgStat_FunctionCallUsage *fcu);
00849 extern void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu,
00850                           bool finalize);
00851 
00852 extern void AtEOXact_PgStat(bool isCommit);
00853 extern void AtEOSubXact_PgStat(bool isCommit, int nestDepth);
00854 
00855 extern void AtPrepare_PgStat(void);
00856 extern void PostPrepare_PgStat(void);
00857 
00858 extern void pgstat_twophase_postcommit(TransactionId xid, uint16 info,
00859                            void *recdata, uint32 len);
00860 extern void pgstat_twophase_postabort(TransactionId xid, uint16 info,
00861                           void *recdata, uint32 len);
00862 
00863 extern void pgstat_send_bgwriter(void);
00864 
00865 /* ----------
00866  * Support functions for the SQL-callable functions to
00867  * generate the pgstat* views.
00868  * ----------
00869  */
00870 extern PgStat_StatDBEntry *pgstat_fetch_stat_dbentry(Oid dbid);
00871 extern PgStat_StatTabEntry *pgstat_fetch_stat_tabentry(Oid relid);
00872 extern PgBackendStatus *pgstat_fetch_stat_beentry(int beid);
00873 extern PgStat_StatFuncEntry *pgstat_fetch_stat_funcentry(Oid funcid);
00874 extern int  pgstat_fetch_stat_numbackends(void);
00875 extern PgStat_GlobalStats *pgstat_fetch_global(void);
00876 
00877 #endif   /* PGSTAT_H */