4 * Definitions for the PostgreSQL cumulative statistics system.
6 * Copyright (c) 2001-2025, PostgreSQL Global Development Group
23#include "utils/wait_event.h" /* for backward compatibility */ /* IWYU pragma: export */
27 * Paths for the statistics files (relative to installation's $PGDATA).
30 #define PGSTAT_STAT_PERMANENT_DIRECTORY "pg_stat"
31 #define PGSTAT_STAT_PERMANENT_FILENAME "pg_stat/pgstat.stat"
32 #define PGSTAT_STAT_PERMANENT_TMPFILE "pg_stat/pgstat.tmp"
34/* Default directory to store temporary statistics data in */
35 #define PG_STAT_TMP_DIR "pg_stat_tmp"
37/* Values for track_functions GUC variable --- order is significant! */
52/* Values to track the cause of session termination */
63 * The data type used for counters.
69/* ------------------------------------------------------------
70 * Structures kept in backend local memory while accumulating counts
71 * ------------------------------------------------------------
75 * PgStat_FunctionCounts The actual per-function counts kept by a backend
77 * Note that the time counters are in instr_time format here. We convert to
78 * microseconds in PgStat_Counter format when flushing out pending statistics.
89 * Working state needed to accumulate per-function-call timing statistics.
93 /* Link to function's hashtable entry (must still be there at exit!) */
94 /* NULL means we are not tracking the current function call */
96 /* Total time previously charged to function, as of function start */
98 /* Backend-wide total time as of function start */
100 /* system clock as of function start */
105 * PgStat_BackendSubEntry Non-flushed subscription stats.
116 * PgStat_TableCounts The actual per-table counts kept by a backend
118 * This struct should contain only actual event counters, because we make use
119 * of pg_memory_is_all_zeros() to detect whether there are any stats updates
122 * It is a component of PgStat_TableStatus (within-backend state).
124 * Note: for a table, tuples_returned is the number of tuples successfully
125 * fetched by heap_getnext, while tuples_fetched is the number of tuples
126 * successfully fetched by heap_fetch under the control of bitmap indexscans.
127 * For an index, tuples_returned is the number of index entries returned by
128 * the index AM, while tuples_fetched is the number of tuples successfully
129 * fetched by heap_fetch under the control of simple indexscans for this index.
131 * tuples_inserted/updated/deleted/hot_updated/newpage_updated count attempted
132 * actions, regardless of whether the transaction committed. delta_live_tuples,
133 * delta_dead_tuples, and changed_tuples are set depending on commit or abort.
134 * Note that delta_live_tuples and delta_dead_tuples can be negative!
160 * PgStat_TableStatus Per-table status within a backend
162 * Many of the event counters are nontransactional, ie, we count events
163 * in committed and aborted transactions alike. For these, we just count
164 * directly in the PgStat_TableStatus. However, delta_live_tuples,
165 * delta_dead_tuples, and changed_tuples must be derived from event counts
166 * with awareness of whether the transaction or subtransaction committed or
167 * aborted. Hence, we also keep a stack of per-(sub)transaction status
168 * records for every table modified in the current transaction. At commit
169 * or abort, we propagate tuples_inserted/updated/deleted up to the
170 * parent subtransaction level, or out to the parent PgStat_TableStatus,
177 bool shared;
/* is it a shared catalog? */
184 * PgStat_TableXactStatus Per-table, per-subtransaction status
194 /* tuples i/u/d prior to truncate/drop */
199 /* links to other structs for same relation: */
202 /* structs of same subxact level are linked here: */
207/* ------------------------------------------------------------
208 * Data structures on disk and in shared memory follow
210 * PGSTAT_FILE_FORMAT_ID should be changed whenever any of these
211 * data structures change.
212 * ------------------------------------------------------------
215 #define PGSTAT_FILE_FORMAT_ID 0x01A5BCB7
231 * PgStat_BgWriterStats Background Writer statistics
233 * This struct should contain only actual event counters, because we make use
234 * of pg_memory_is_all_zeros() to detect whether there are any stats updates
247 * PgStat_CheckpointerStats Checkpoint statistics
249 * This struct should contain only actual event counters, because we make use
250 * of pg_memory_is_all_zeros() to detect whether there are any stats updates to
271 * Types related to counting IO operations
280 #define IOOBJECT_NUM_TYPES (IOOBJECT_WAL + 1)
291 #define IOCONTEXT_NUM_TYPES (IOCONTEXT_VACUUM + 1)
294 * Enumeration of IO operations.
296 * This enum categorizes IO operations into two groups, depending on if
297 * byte operations are supported.
299 * Ensure IOOP_EXTEND is the first and IOOP_WRITE is the last ones in the
300 * tracked in bytes group and that the groups stay in that order.
304 /* IOs not tracked in bytes */
311 /* IOs tracked in bytes */
317 #define IOOP_NUM_TYPES (IOOP_WRITE + 1)
319 #define pgstat_is_ioop_tracked_in_bytes(io_op) \
320 (((unsigned int) (io_op)) < IOOP_NUM_TYPES && \
321 ((unsigned int) (io_op)) >= IOOP_EXTEND)
460 * PgStat_WalCounters WAL activity data gathered from WalUsage
462 * This stores all the counters and data gathered from WalUsage for WAL
463 * activity statistics, separated into its own structure so as this can be
464 * shared across multiple Stats structures.
476 * PgStat_WalStats WAL statistics
486 * PgStat_Backend Backend statistics
497 * PgStat_BackendPending Non-flushed backend stats.
503 * Backend statistics store the same amount of IO data as PGSTAT_KIND_IO.
509 * Functions in pgstat.c
512/* functions called from postmaster */
516/* Functions called during server startup / shutdown */
521/* Functions for backend initialization */
524/* Functions called from backends */
542 * Functions in pgstat_archiver.c
549 * Functions in pgstat_backend.c
552/* used by pgstat_io.c for I/O stats tracked in backends */
568 * Functions in pgstat_bgwriter.c
576 * Functions in pgstat_checkpointer.c
584 * Functions in pgstat_io.c
608 * Functions in pgstat_database.c
621 #define pgstat_count_buffer_read_time(n) \
622 (pgStatBlockReadTime += (n))
623 #define pgstat_count_buffer_write_time(n) \
624 (pgStatBlockWriteTime += (n))
625 #define pgstat_count_conn_active_time(n) \
626 (pgStatActiveTime += (n))
627 #define pgstat_count_conn_txn_idle_time(n) \
628 (pgStatTransactionIdleTime += (n))
634 * Functions in pgstat_function.c
651 * Functions in pgstat_relation.c
670 * If stats are enabled, but pending data hasn't been prepared yet, call
671 * pgstat_assoc_relation() to do so. See its comment for why this is done
672 * separately from pgstat_init_relation().
674 #define pgstat_should_count_relation(rel) \
675 (likely((rel)->pgstat_info != NULL) ? true : \
676 ((rel)->pgstat_enabled ? pgstat_assoc_relation(rel), true : false))
678/* nontransactional event counts are simple enough to inline */
680 #define pgstat_count_heap_scan(rel) \
682 if (pgstat_should_count_relation(rel)) \
683 (rel)->pgstat_info->counts.numscans++; \
685 #define pgstat_count_heap_getnext(rel) \
687 if (pgstat_should_count_relation(rel)) \
688 (rel)->pgstat_info->counts.tuples_returned++; \
690 #define pgstat_count_heap_fetch(rel) \
692 if (pgstat_should_count_relation(rel)) \
693 (rel)->pgstat_info->counts.tuples_fetched++; \
695 #define pgstat_count_index_scan(rel) \
697 if (pgstat_should_count_relation(rel)) \
698 (rel)->pgstat_info->counts.numscans++; \
700 #define pgstat_count_index_tuples(rel, n) \
702 if (pgstat_should_count_relation(rel)) \
703 (rel)->pgstat_info->counts.tuples_returned += (n); \
705 #define pgstat_count_buffer_read(rel) \
707 if (pgstat_should_count_relation(rel)) \
708 (rel)->pgstat_info->counts.blocks_fetched++; \
710 #define pgstat_count_buffer_hit(rel) \
712 if (pgstat_should_count_relation(rel)) \
713 (rel)->pgstat_info->counts.blocks_hit++; \
734 * Functions in pgstat_replslot.c
747 * Functions in pgstat_slru.c
764 * Functions in pgstat_subscription.c
775 * Functions in pgstat_xact.c
788 * Functions in pgstat_wal.c
796 * Variables in pgstat.c
806 * Variables in pgstat_bgwriter.c
809/* updated directly by bgwriter and bufmgr */
814 * Variables in pgstat_checkpointer.c
818 * Checkpointer statistics counters are updated directly by checkpointer and
825 * Variables in pgstat_database.c
828/* Updated by pgstat_count_buffer_*_time macros */
833 * Updated by pgstat_count_conn_*_time macros, called by
834 * pgstat_report_activity().
839/* updated by the traffic cop and in errfinish() */
#define CONFLICT_NUM_TYPES
#define BACKEND_NUM_TYPES
void pgstat_reset(PgStat_Kind kind, Oid dboid, uint64 objid)
void pgstat_drop_function(Oid proid)
void pgstat_create_backend(ProcNumber procnum)
void pgstat_drop_subscription(Oid subid)
struct PgStat_TableStatus PgStat_TableStatus
void pgstat_update_parallel_workers_stats(PgStat_Counter workers_to_launch, PgStat_Counter workers_launched)
void pgstat_reset_replslot(const char *name)
instr_time pgstat_prepare_io_time(bool track_io_guc)
void pgstat_count_io_op(IOObject io_object, IOContext io_context, IOOp io_op, uint32 cnt, uint64 bytes)
void AtPrepare_PgStat(void)
int pgstat_get_transactional_drops(bool isCommit, struct xl_xact_stats_item **items)
void pgstat_copy_relation_stats(Relation dst, Relation src)
void pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter livetuples, PgStat_Counter deadtuples, TimestampTz starttime)
void pgstat_unlink_relation(Relation rel)
struct PgStat_CheckpointerStats PgStat_CheckpointerStats
void pgstat_reset_slru(const char *)
PgStat_StatFuncEntry * pgstat_fetch_stat_funcentry(Oid func_id)
void pgstat_create_subscription(Oid subid)
void pgstat_count_heap_update(Relation rel, bool hot, bool newpage)
void pgstat_count_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op, instr_time start_time, uint32 cnt, uint64 bytes)
@ PGSTAT_FETCH_CONSISTENCY_NONE
@ PGSTAT_FETCH_CONSISTENCY_CACHE
@ PGSTAT_FETCH_CONSISTENCY_SNAPSHOT
bool pgstat_tracks_backend_bktype(BackendType bktype)
void pgstat_execute_transactional_drops(int ndrops, struct xl_xact_stats_item *items, bool is_redo)
void StatsShmemInit(void)
void pgstat_reset_counters(void)
void pgstat_count_slru_blocks_zeroed(int slru_idx)
void pgstat_report_subscription_conflict(Oid subid, ConflictType type)
PgStat_IO * pgstat_fetch_stat_io(void)
struct PgStat_StatSubEntry PgStat_StatSubEntry
void AtEOXact_PgStat(bool isCommit, bool parallel)
int pgstat_get_slru_index(const char *name)
PgStat_SLRUStats * pgstat_fetch_slru(void)
struct PgStat_PendingIO PgStat_PendingIO
void pgstat_count_slru_blocks_hit(int slru_idx)
const char * pgstat_get_io_context_name(IOContext io_context)
PgStat_StatReplSlotEntry * pgstat_fetch_replslot(NameData slotname)
bool pgstat_tracks_io_bktype(BackendType bktype)
void pgstat_report_subscription_error(Oid subid, bool is_apply_error)
void pgstat_init_function_usage(struct FunctionCallInfoBaseData *fcinfo, PgStat_FunctionCallUsage *fcu)
void pgstat_report_autovac(Oid dboid)
struct PgStat_TableCounts PgStat_TableCounts
void pgstat_prepare_report_checksum_failure(Oid dboid)
void pgstat_report_analyze(Relation rel, PgStat_Counter livetuples, PgStat_Counter deadtuples, bool resetcounter, TimestampTz starttime)
void pgstat_report_connect(Oid dboid)
void pgstat_initialize(void)
struct PgStat_BackendSubEntry PgStat_BackendSubEntry
void pgstat_count_backend_io_op(IOObject io_object, IOContext io_context, IOOp io_op, uint32 cnt, uint64 bytes)
void pgstat_assoc_relation(Relation rel)
long pgstat_report_stat(bool force)
struct PgStat_FunctionCallUsage PgStat_FunctionCallUsage
void pgstat_report_checksum_failures_in_db(Oid dboid, int failurecount)
void pgstat_count_slru_truncate(int slru_idx)
void pgstat_reset_of_kind(PgStat_Kind kind)
const char * pgstat_get_io_object_name(IOObject io_object)
struct PgStat_SLRUStats PgStat_SLRUStats
PgStat_StatTabEntry * pgstat_fetch_stat_tabentry_ext(bool shared, Oid reloid)
PGDLLIMPORT int pgstat_fetch_consistency
struct PgStat_BktypeIO PgStat_BktypeIO
PgStat_StatTabEntry * pgstat_fetch_stat_tabentry(Oid relid)
#define IOCONTEXT_NUM_TYPES
void pgstat_before_server_shutdown(int code, Datum arg)
void pgstat_count_slru_blocks_read(int slru_idx)
void pgstat_report_deadlock(void)
void pgstat_count_slru_blocks_written(int slru_idx)
void pgstat_acquire_replslot(struct ReplicationSlot *slot)
void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, bool finalize)
void pgstat_report_recovery_conflict(int reason)
void pgstat_force_next_flush(void)
void pgstat_create_function(Oid proid)
const char * pgstat_get_slru_name(int slru_idx)
struct PgStat_ArchiverStats PgStat_ArchiverStats
PGDLLIMPORT PgStat_Counter pgStatActiveTime
void pgstat_clear_snapshot(void)
TimestampTz pgstat_get_stat_snapshot_timestamp(bool *have_snapshot)
bool pgstat_bktype_io_stats_valid(PgStat_BktypeIO *backend_io, BackendType bktype)
PGDLLIMPORT PgStat_Counter pgStatBlockWriteTime
Size StatsShmemSize(void)
void pgstat_create_relation(Relation rel)
void PostPrepare_PgStat(void)
PGDLLIMPORT PgStat_BgWriterStats PendingBgWriterStats
struct PgStat_FunctionCounts PgStat_FunctionCounts
bool pgstat_have_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
struct PgStat_StatReplSlotEntry PgStat_StatReplSlotEntry
PGDLLIMPORT PgStat_Counter pgStatBlockReadTime
void pgstat_update_heap_dead_tuples(Relation rel, int delta)
void pgstat_report_wal(bool force)
PgStat_StatSubEntry * pgstat_fetch_stat_subscription(Oid subid)
PgStat_BgWriterStats * pgstat_fetch_stat_bgwriter(void)
PGDLLIMPORT int pgstat_track_functions
void pgstat_count_heap_delete(Relation rel)
void pgstat_count_heap_insert(Relation rel, PgStat_Counter n)
struct PgStat_Backend PgStat_Backend
void pgstat_restore_stats(void)
struct PgStat_StatDBEntry PgStat_StatDBEntry
PGDLLIMPORT PgStat_CheckpointerStats PendingCheckpointerStats
PgStat_TableStatus * find_tabstat_entry(Oid rel_id)
void pgstat_count_slru_flush(int slru_idx)
PGDLLIMPORT PgStat_Counter pgStatTransactionIdleTime
PgStat_Backend * pgstat_fetch_stat_backend_by_pid(int pid, BackendType *bktype)
void pgstat_report_checkpointer(void)
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
struct PgStat_WalStats PgStat_WalStats
void pgstat_create_replslot(struct ReplicationSlot *slot)
void pgstat_report_replslot(struct ReplicationSlot *slot, const PgStat_StatReplSlotEntry *repSlotStat)
void pgstat_drop_database(Oid databaseid)
void pgstat_count_backend_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op, instr_time io_time)
struct PgStat_BgWriterStats PgStat_BgWriterStats
struct PgStat_StatTabEntry PgStat_StatTabEntry
bool pgstat_tracks_io_op(BackendType bktype, IOObject io_object, IOContext io_context, IOOp io_op)
void pgstat_twophase_postcommit(FullTransactionId fxid, uint16 info, void *recdata, uint32 len)
void pgstat_count_truncate(Relation rel)
void pgstat_drop_replslot(struct ReplicationSlot *slot)
PgStat_ArchiverStats * pgstat_fetch_stat_archiver(void)
PGDLLIMPORT bool pgstat_track_counts
void pgstat_drop_relation(Relation rel)
void pgstat_count_slru_blocks_exists(int slru_idx)
PgStat_StatDBEntry * pgstat_fetch_stat_dbentry(Oid dboid)
void pgstat_twophase_postabort(FullTransactionId fxid, uint16 info, void *recdata, uint32 len)
PgStat_Backend * pgstat_fetch_stat_backend(ProcNumber procNumber)
struct PgStat_WalCounters PgStat_WalCounters
void pgstat_discard_stats(void)
PgStat_CheckpointerStats * pgstat_fetch_stat_checkpointer(void)
bool pgstat_tracks_io_object(BackendType bktype, IOObject io_object, IOContext io_context)
PgStat_WalStats * pgstat_fetch_stat_wal(void)
void pgstat_report_bgwriter(void)
void pgstat_report_archiver(const char *xlog, bool failed)
#define IOOBJECT_NUM_TYPES
struct PgStat_TableXactStatus PgStat_TableXactStatus
PgStat_Kind pgstat_get_kind_from_str(char *kind_str)
struct PgStat_StatFuncEntry PgStat_StatFuncEntry
PGDLLIMPORT SessionEndType pgStatSessionEndCause
PgStat_FunctionCounts * find_funcstat_entry(Oid func_id)
void pgstat_init_relation(Relation rel)
struct PgStat_BackendPending PgStat_BackendPending
struct PgStat_IO PgStat_IO
TimestampTz last_failed_timestamp
TimestampTz stat_reset_timestamp
TimestampTz last_archived_timestamp
char last_failed_wal[MAX_XFN_CHARS+1]
PgStat_Counter failed_count
PgStat_Counter archived_count
char last_archived_wal[MAX_XFN_CHARS+1]
PgStat_PendingIO pending_io
PgStat_Counter apply_error_count
PgStat_Counter sync_error_count
PgStat_Counter conflict_count[CONFLICT_NUM_TYPES]
TimestampTz stat_reset_timestamp
PgStat_WalCounters wal_counters
PgStat_Counter buf_written_clean
PgStat_Counter maxwritten_clean
TimestampTz stat_reset_timestamp
PgStat_Counter times[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
uint64 bytes[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
PgStat_Counter counts[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
PgStat_Counter restartpoints_requested
PgStat_Counter write_time
PgStat_Counter num_requested
PgStat_Counter num_performed
PgStat_Counter restartpoints_timed
PgStat_Counter restartpoints_performed
PgStat_Counter buffers_written
TimestampTz stat_reset_timestamp
PgStat_Counter slru_written
PgStat_FunctionCounts * fs
instr_time save_f_total_time
PgStat_BktypeIO stats[BACKEND_NUM_TYPES]
TimestampTz stat_reset_timestamp
PgStat_Counter counts[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
uint64 bytes[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
instr_time pending_times[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
PgStat_Counter blocks_read
PgStat_Counter blocks_exists
TimestampTz stat_reset_timestamp
PgStat_Counter blocks_zeroed
PgStat_Counter blocks_written
PgStat_Counter blocks_hit
PgStat_Counter blk_write_time
PgStat_Counter xact_rollback
PgStat_Counter conflict_startup_deadlock
PgStat_Counter conflict_lock
PgStat_Counter tuples_updated
PgStat_Counter parallel_workers_to_launch
PgStat_Counter tuples_inserted
TimestampTz stat_reset_timestamp
PgStat_Counter conflict_snapshot
PgStat_Counter sessions_fatal
TimestampTz last_checksum_failure
PgStat_Counter tuples_returned
PgStat_Counter blk_read_time
PgStat_Counter parallel_workers_launched
PgStat_Counter xact_commit
TimestampTz last_autovac_time
PgStat_Counter temp_bytes
PgStat_Counter session_time
PgStat_Counter blocks_hit
PgStat_Counter temp_files
PgStat_Counter sessions_abandoned
PgStat_Counter active_time
PgStat_Counter blocks_fetched
PgStat_Counter conflict_bufferpin
PgStat_Counter idle_in_transaction_time
PgStat_Counter conflict_logicalslot
PgStat_Counter tuples_deleted
PgStat_Counter sessions_killed
PgStat_Counter tuples_fetched
PgStat_Counter checksum_failures
PgStat_Counter conflict_tablespace
PgStat_Counter total_time
TimestampTz stat_reset_timestamp
PgStat_Counter stream_count
PgStat_Counter total_txns
PgStat_Counter total_bytes
PgStat_Counter spill_txns
PgStat_Counter stream_txns
PgStat_Counter spill_count
PgStat_Counter stream_bytes
PgStat_Counter spill_bytes
PgStat_Counter apply_error_count
PgStat_Counter sync_error_count
PgStat_Counter conflict_count[CONFLICT_NUM_TYPES]
TimestampTz stat_reset_timestamp
PgStat_Counter vacuum_count
PgStat_Counter tuples_fetched
PgStat_Counter ins_since_vacuum
PgStat_Counter blocks_hit
PgStat_Counter mod_since_analyze
TimestampTz last_autovacuum_time
PgStat_Counter analyze_count
PgStat_Counter tuples_deleted
PgStat_Counter tuples_hot_updated
PgStat_Counter tuples_updated
PgStat_Counter live_tuples
PgStat_Counter autovacuum_count
PgStat_Counter total_autovacuum_time
PgStat_Counter total_analyze_time
TimestampTz last_analyze_time
PgStat_Counter dead_tuples
PgStat_Counter autoanalyze_count
PgStat_Counter blocks_fetched
PgStat_Counter tuples_returned
TimestampTz last_autoanalyze_time
PgStat_Counter total_autoanalyze_time
PgStat_Counter tuples_inserted
PgStat_Counter total_vacuum_time
PgStat_Counter tuples_newpage_updated
TimestampTz last_vacuum_time
PgStat_Counter blocks_hit
PgStat_Counter tuples_hot_updated
PgStat_Counter tuples_returned
PgStat_Counter tuples_inserted
PgStat_Counter delta_live_tuples
PgStat_Counter changed_tuples
PgStat_Counter tuples_updated
PgStat_Counter blocks_fetched
PgStat_Counter tuples_fetched
PgStat_Counter tuples_newpage_updated
PgStat_Counter delta_dead_tuples
PgStat_Counter tuples_deleted
PgStat_TableCounts counts
struct PgStat_TableXactStatus * trans
struct PgStat_TableXactStatus * next
PgStat_Counter deleted_pre_truncdrop
PgStat_TableStatus * parent
PgStat_Counter tuples_inserted
PgStat_Counter tuples_updated
PgStat_Counter inserted_pre_truncdrop
PgStat_Counter tuples_deleted
struct PgStat_TableXactStatus * upper
PgStat_Counter updated_pre_truncdrop
PgStat_Counter wal_buffers_full
PgStat_Counter wal_records
TimestampTz stat_reset_timestamp
PgStat_WalCounters wal_counters