LCOV - code coverage report
Current view: top level - src/include/utils - pgstat_internal.h (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 35 36 97.2 %
Date: 2024-04-19 19:11:30 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* ----------
       2             :  * pgstat_internal.h
       3             :  *
       4             :  * Definitions for the PostgreSQL cumulative statistics system that should
       5             :  * only be needed by files implementing statistics support (rather than ones
       6             :  * reporting / querying stats).
       7             :  *
       8             :  * Copyright (c) 2001-2024, PostgreSQL Global Development Group
       9             :  *
      10             :  * src/include/utils/pgstat_internal.h
      11             :  * ----------
      12             :  */
      13             : #ifndef PGSTAT_INTERNAL_H
      14             : #define PGSTAT_INTERNAL_H
      15             : 
      16             : 
      17             : #include "common/hashfn_unstable.h"
      18             : #include "lib/dshash.h"
      19             : #include "lib/ilist.h"
      20             : #include "pgstat.h"
      21             : #include "storage/lwlock.h"
      22             : #include "utils/dsa.h"
      23             : 
      24             : 
      25             : /*
      26             :  * Types related to shared memory storage of statistics.
      27             :  *
      28             :  * Per-object statistics are stored in the "shared stats" hashtable. That
      29             :  * table's entries (PgStatShared_HashEntry) contain a pointer to the actual stats
      30             :  * data for the object (the size of the stats data varies depending on the
      31             :  * kind of stats). The table is keyed by PgStat_HashKey.
      32             :  *
      33             :  * Once a backend has a reference to a shared stats entry, it increments the
      34             :  * entry's refcount. Even after stats data is dropped (e.g., due to a DROP
      35             :  * TABLE), the entry itself can only be deleted once all references have been
      36             :  * released.
      37             :  *
      38             :  * These refcounts, in combination with a backend local hashtable
      39             :  * (pgStatEntryRefHash, with entries pointing to PgStat_EntryRef) in front of
      40             :  * the shared hash table, mean that most stats work can happen without
      41             :  * touching the shared hash table, reducing contention.
      42             :  *
      43             :  * Once there are pending stats updates for a table PgStat_EntryRef->pending
      44             :  * is allocated to contain a working space for as-of-yet-unapplied stats
      45             :  * updates. Once the stats are flushed, PgStat_EntryRef->pending is freed.
      46             :  *
      47             :  * Each stat kind in the shared hash table has a fixed member
      48             :  * PgStatShared_Common as the first element.
      49             :  */
      50             : 
      51             : /* struct for shared statistics hash entry key. */
      52             : typedef struct PgStat_HashKey
      53             : {
      54             :     PgStat_Kind kind;           /* statistics entry kind */
      55             :     Oid         dboid;          /* database ID. InvalidOid for shared objects. */
      56             :     Oid         objoid;         /* object ID, either table or function. */
      57             : } PgStat_HashKey;
      58             : 
      59             : /*
      60             :  * Shared statistics hash entry. Doesn't itself contain any stats, but points
      61             :  * to them (with ->body). That allows the stats entries themselves to be of
      62             :  * variable size.
      63             :  */
      64             : typedef struct PgStatShared_HashEntry
      65             : {
      66             :     PgStat_HashKey key;         /* hash key */
      67             : 
      68             :     /*
      69             :      * If dropped is set, backends need to release their references so that
      70             :      * the memory for the entry can be freed. No new references may be made
      71             :      * once marked as dropped.
      72             :      */
      73             :     bool        dropped;
      74             : 
      75             :     /*
      76             :      * Refcount managing lifetime of the entry itself (as opposed to the
      77             :      * dshash entry pointing to it). The stats lifetime has to be separate
      78             :      * from the hash table entry lifetime because we allow backends to point
      79             :      * to a stats entry without holding a hash table lock (and some other
      80             :      * reasons).
      81             :      *
      82             :      * As long as the entry is not dropped, 1 is added to the refcount
      83             :      * representing that the entry should not be dropped. In addition each
      84             :      * backend that has a reference to the entry needs to increment the
      85             :      * refcount as long as it does.
      86             :      *
      87             :      * May only be incremented / decremented while holding at least a shared
      88             :      * lock on the dshash partition containing the entry. It needs to be an
      89             :      * atomic variable because multiple backends can increment the refcount
      90             :      * with just a shared lock.
      91             :      *
      92             :      * When the refcount reaches 0 the entry needs to be freed.
      93             :      */
      94             :     pg_atomic_uint32 refcount;
      95             : 
      96             :     /*
      97             :      * Pointer to shared stats. The stats entry always starts with
      98             :      * PgStatShared_Common, embedded in a larger struct containing the
      99             :      * PgStat_Kind specific stats fields.
     100             :      */
     101             :     dsa_pointer body;
     102             : } PgStatShared_HashEntry;
     103             : 
     104             : /*
     105             :  * Common header struct for PgStatShared_*.
     106             :  */
     107             : typedef struct PgStatShared_Common
     108             : {
     109             :     uint32      magic;          /* just a validity cross-check */
     110             :     /* lock protecting stats contents (i.e. data following the header) */
     111             :     LWLock      lock;
     112             : } PgStatShared_Common;
     113             : 
     114             : /*
     115             :  * A backend local reference to a shared stats entry. As long as at least one
     116             :  * such reference exists, the shared stats entry will not be released.
     117             :  *
     118             :  * If there are pending stats update to the shared stats, these are stored in
     119             :  * ->pending.
     120             :  */
     121             : typedef struct PgStat_EntryRef
     122             : {
     123             :     /*
     124             :      * Pointer to the PgStatShared_HashEntry entry in the shared stats
     125             :      * hashtable.
     126             :      */
     127             :     PgStatShared_HashEntry *shared_entry;
     128             : 
     129             :     /*
     130             :      * Pointer to the stats data (i.e. PgStatShared_HashEntry->body), resolved
     131             :      * as a local pointer, to avoid repeated dsa_get_address() calls.
     132             :      */
     133             :     PgStatShared_Common *shared_stats;
     134             : 
     135             :     /*
     136             :      * Pending statistics data that will need to be flushed to shared memory
     137             :      * stats eventually. Each stats kind utilizing pending data defines what
     138             :      * format its pending data has and needs to provide a
     139             :      * PgStat_KindInfo->flush_pending_cb callback to merge pending into shared
     140             :      * stats.
     141             :      */
     142             :     void       *pending;
     143             :     dlist_node  pending_node;   /* membership in pgStatPending list */
     144             : } PgStat_EntryRef;
     145             : 
     146             : 
     147             : /*
     148             :  * Some stats changes are transactional. To maintain those, a stack of
     149             :  * PgStat_SubXactStatus entries is maintained, which contain data pertaining
     150             :  * to the current transaction and its active subtransactions.
     151             :  */
     152             : typedef struct PgStat_SubXactStatus
     153             : {
     154             :     int         nest_level;     /* subtransaction nest level */
     155             : 
     156             :     struct PgStat_SubXactStatus *prev;  /* higher-level subxact if any */
     157             : 
     158             :     /*
     159             :      * Statistics for transactionally dropped objects need to be
     160             :      * transactionally dropped as well. Collect the stats dropped in the
     161             :      * current (sub-)transaction and only execute the stats drop when we know
     162             :      * if the transaction commits/aborts. To handle replicas and crashes,
     163             :      * stats drops are included in commit / abort records.
     164             :      */
     165             :     dclist_head pending_drops;
     166             : 
     167             :     /*
     168             :      * Tuple insertion/deletion counts for an open transaction can't be
     169             :      * propagated into PgStat_TableStatus counters until we know if it is
     170             :      * going to commit or abort.  Hence, we keep these counts in per-subxact
     171             :      * structs that live in TopTransactionContext.  This data structure is
     172             :      * designed on the assumption that subxacts won't usually modify very many
     173             :      * tables.
     174             :      */
     175             :     PgStat_TableXactStatus *first;  /* head of list for this subxact */
     176             : } PgStat_SubXactStatus;
     177             : 
     178             : 
     179             : /*
     180             :  * Metadata for a specific kind of statistics.
     181             :  */
     182             : typedef struct PgStat_KindInfo
     183             : {
     184             :     /*
     185             :      * Do a fixed number of stats objects exist for this kind of stats (e.g.
     186             :      * bgwriter stats) or not (e.g. tables).
     187             :      */
     188             :     bool        fixed_amount:1;
     189             : 
     190             :     /*
     191             :      * Can stats of this kind be accessed from another database? Determines
     192             :      * whether a stats object gets included in stats snapshots.
     193             :      */
     194             :     bool        accessed_across_databases:1;
     195             : 
     196             :     /*
     197             :      * For variable-numbered stats: Identified on-disk using a name, rather
     198             :      * than PgStat_HashKey. Probably only needed for replication slot stats.
     199             :      */
     200             :     bool        named_on_disk:1;
     201             : 
     202             :     /*
     203             :      * The size of an entry in the shared stats hash table (pointed to by
     204             :      * PgStatShared_HashEntry->body).
     205             :      */
     206             :     uint32      shared_size;
     207             : 
     208             :     /*
     209             :      * The offset/size of statistics inside the shared stats entry. Used when
     210             :      * [de-]serializing statistics to / from disk respectively. Separate from
     211             :      * shared_size because [de-]serialization may not include in-memory state
     212             :      * like lwlocks.
     213             :      */
     214             :     uint32      shared_data_off;
     215             :     uint32      shared_data_len;
     216             : 
     217             :     /*
     218             :      * The size of the pending data for this kind. E.g. how large
     219             :      * PgStat_EntryRef->pending is. Used for allocations.
     220             :      *
     221             :      * 0 signals that an entry of this kind should never have a pending entry.
     222             :      */
     223             :     uint32      pending_size;
     224             : 
     225             :     /*
     226             :      * For variable-numbered stats: flush pending stats. Required if pending
     227             :      * data is used.
     228             :      */
     229             :     bool        (*flush_pending_cb) (PgStat_EntryRef *sr, bool nowait);
     230             : 
     231             :     /*
     232             :      * For variable-numbered stats: delete pending stats. Optional.
     233             :      */
     234             :     void        (*delete_pending_cb) (PgStat_EntryRef *sr);
     235             : 
     236             :     /*
     237             :      * For variable-numbered stats: reset the reset timestamp. Optional.
     238             :      */
     239             :     void        (*reset_timestamp_cb) (PgStatShared_Common *header, TimestampTz ts);
     240             : 
     241             :     /*
     242             :      * For variable-numbered stats with named_on_disk. Optional.
     243             :      */
     244             :     void        (*to_serialized_name) (const PgStat_HashKey *key,
     245             :                                        const PgStatShared_Common *header, NameData *name);
     246             :     bool        (*from_serialized_name) (const NameData *name, PgStat_HashKey *key);
     247             : 
     248             :     /*
     249             :      * For fixed-numbered statistics: Reset All.
     250             :      */
     251             :     void        (*reset_all_cb) (TimestampTz ts);
     252             : 
     253             :     /*
     254             :      * For fixed-numbered statistics: Build snapshot for entry
     255             :      */
     256             :     void        (*snapshot_cb) (void);
     257             : 
     258             :     /* name of the kind of stats */
     259             :     const char *const name;
     260             : } PgStat_KindInfo;
     261             : 
     262             : 
     263             : /*
     264             :  * List of SLRU names that we keep stats for.  There is no central registry of
     265             :  * SLRUs, so we use this fixed list instead.  The "other" entry is used for
     266             :  * all SLRUs without an explicit entry (e.g. SLRUs in extensions).
     267             :  *
     268             :  * This is only defined here so that SLRU_NUM_ELEMENTS is known for later type
     269             :  * definitions.
     270             :  */
     271             : static const char *const slru_names[] = {
     272             :     "commit_timestamp",
     273             :     "multixact_member",
     274             :     "multixact_offset",
     275             :     "notify",
     276             :     "serializable",
     277             :     "subtransaction",
     278             :     "transaction",
     279             :     "other"                       /* has to be last */
     280             : };
     281             : 
     282             : #define SLRU_NUM_ELEMENTS   lengthof(slru_names)
     283             : 
     284             : 
     285             : /* ----------
     286             :  * Types and definitions for different kinds of fixed-amount stats.
     287             :  *
     288             :  * Single-writer stats use the changecount mechanism to achieve low-overhead
     289             :  * writes - they're obviously more performance critical than reads. Check the
     290             :  * definition of struct PgBackendStatus for some explanation of the
     291             :  * changecount mechanism.
     292             :  *
     293             :  * Because the obvious implementation of resetting single-writer stats isn't
     294             :  * compatible with that (another backend needs to write), we don't scribble on
     295             :  * shared stats while resetting. Instead, just record the current counter
     296             :  * values in a copy of the stats data, which is protected by ->lock. See
     297             :  * pgstat_fetch_stat_(archiver|bgwriter|checkpointer) for the reader side.
     298             :  *
     299             :  * The only exception to that is the stat_reset_timestamp in these structs,
     300             :  * which is protected by ->lock, because it has to be written by another
     301             :  * backend while resetting.
     302             :  * ----------
     303             :  */
     304             : 
     305             : typedef struct PgStatShared_Archiver
     306             : {
     307             :     /* lock protects ->reset_offset as well as stats->stat_reset_timestamp */
     308             :     LWLock      lock;
     309             :     uint32      changecount;
     310             :     PgStat_ArchiverStats stats;
     311             :     PgStat_ArchiverStats reset_offset;
     312             : } PgStatShared_Archiver;
     313             : 
     314             : typedef struct PgStatShared_BgWriter
     315             : {
     316             :     /* lock protects ->reset_offset as well as stats->stat_reset_timestamp */
     317             :     LWLock      lock;
     318             :     uint32      changecount;
     319             :     PgStat_BgWriterStats stats;
     320             :     PgStat_BgWriterStats reset_offset;
     321             : } PgStatShared_BgWriter;
     322             : 
     323             : typedef struct PgStatShared_Checkpointer
     324             : {
     325             :     /* lock protects ->reset_offset as well as stats->stat_reset_timestamp */
     326             :     LWLock      lock;
     327             :     uint32      changecount;
     328             :     PgStat_CheckpointerStats stats;
     329             :     PgStat_CheckpointerStats reset_offset;
     330             : } PgStatShared_Checkpointer;
     331             : 
     332             : /* Shared-memory ready PgStat_IO */
     333             : typedef struct PgStatShared_IO
     334             : {
     335             :     /*
     336             :      * locks[i] protects stats.stats[i]. locks[0] also protects
     337             :      * stats.stat_reset_timestamp.
     338             :      */
     339             :     LWLock      locks[BACKEND_NUM_TYPES];
     340             :     PgStat_IO   stats;
     341             : } PgStatShared_IO;
     342             : 
     343             : typedef struct PgStatShared_SLRU
     344             : {
     345             :     /* lock protects ->stats */
     346             :     LWLock      lock;
     347             :     PgStat_SLRUStats stats[SLRU_NUM_ELEMENTS];
     348             : } PgStatShared_SLRU;
     349             : 
     350             : typedef struct PgStatShared_Wal
     351             : {
     352             :     /* lock protects ->stats */
     353             :     LWLock      lock;
     354             :     PgStat_WalStats stats;
     355             : } PgStatShared_Wal;
     356             : 
     357             : 
     358             : 
     359             : /* ----------
     360             :  * Types and definitions for different kinds of variable-amount stats.
     361             :  *
     362             :  * Each struct has to start with PgStatShared_Common, containing information
     363             :  * common across the different types of stats. Kind-specific data follows.
     364             :  * ----------
     365             :  */
     366             : 
     367             : typedef struct PgStatShared_Database
     368             : {
     369             :     PgStatShared_Common header;
     370             :     PgStat_StatDBEntry stats;
     371             : } PgStatShared_Database;
     372             : 
     373             : typedef struct PgStatShared_Relation
     374             : {
     375             :     PgStatShared_Common header;
     376             :     PgStat_StatTabEntry stats;
     377             : } PgStatShared_Relation;
     378             : 
     379             : typedef struct PgStatShared_Function
     380             : {
     381             :     PgStatShared_Common header;
     382             :     PgStat_StatFuncEntry stats;
     383             : } PgStatShared_Function;
     384             : 
     385             : typedef struct PgStatShared_Subscription
     386             : {
     387             :     PgStatShared_Common header;
     388             :     PgStat_StatSubEntry stats;
     389             : } PgStatShared_Subscription;
     390             : 
     391             : typedef struct PgStatShared_ReplSlot
     392             : {
     393             :     PgStatShared_Common header;
     394             :     PgStat_StatReplSlotEntry stats;
     395             : } PgStatShared_ReplSlot;
     396             : 
     397             : 
     398             : /*
     399             :  * Central shared memory entry for the cumulative stats system.
     400             :  *
     401             :  * Fixed amount stats, the dynamic shared memory hash table for
     402             :  * non-fixed-amount stats, as well as remaining bits and pieces are all
     403             :  * reached from here.
     404             :  */
     405             : typedef struct PgStat_ShmemControl
     406             : {
     407             :     void       *raw_dsa_area;
     408             : 
     409             :     /*
     410             :      * Stats for variable-numbered objects are kept in this shared hash table.
     411             :      * See comment above PgStat_Kind for details.
     412             :      */
     413             :     dshash_table_handle hash_handle;    /* shared dbstat hash */
     414             : 
     415             :     /* Has the stats system already been shut down? Just a debugging check. */
     416             :     bool        is_shutdown;
     417             : 
     418             :     /*
     419             :      * Whenever statistics for dropped objects could not be freed - because
     420             :      * backends still have references - the dropping backend calls
     421             :      * pgstat_request_entry_refs_gc() incrementing this counter. Eventually
     422             :      * that causes backends to run pgstat_gc_entry_refs(), allowing memory to
     423             :      * be reclaimed.
     424             :      */
     425             :     pg_atomic_uint64 gc_request_count;
     426             : 
     427             :     /*
     428             :      * Stats data for fixed-numbered objects.
     429             :      */
     430             :     PgStatShared_Archiver archiver;
     431             :     PgStatShared_BgWriter bgwriter;
     432             :     PgStatShared_Checkpointer checkpointer;
     433             :     PgStatShared_IO io;
     434             :     PgStatShared_SLRU slru;
     435             :     PgStatShared_Wal wal;
     436             : } PgStat_ShmemControl;
     437             : 
     438             : 
     439             : /*
     440             :  * Cached statistics snapshot
     441             :  */
     442             : typedef struct PgStat_Snapshot
     443             : {
     444             :     PgStat_FetchConsistency mode;
     445             : 
     446             :     /* time at which snapshot was taken */
     447             :     TimestampTz snapshot_timestamp;
     448             : 
     449             :     bool        fixed_valid[PGSTAT_NUM_KINDS];
     450             : 
     451             :     PgStat_ArchiverStats archiver;
     452             : 
     453             :     PgStat_BgWriterStats bgwriter;
     454             : 
     455             :     PgStat_CheckpointerStats checkpointer;
     456             : 
     457             :     PgStat_IO   io;
     458             : 
     459             :     PgStat_SLRUStats slru[SLRU_NUM_ELEMENTS];
     460             : 
     461             :     PgStat_WalStats wal;
     462             : 
     463             :     /* to free snapshot in bulk */
     464             :     MemoryContext context;
     465             :     struct pgstat_snapshot_hash *stats;
     466             : } PgStat_Snapshot;
     467             : 
     468             : 
     469             : /*
     470             :  * Collection of backend-local stats state.
     471             :  */
     472             : typedef struct PgStat_LocalState
     473             : {
     474             :     PgStat_ShmemControl *shmem;
     475             :     dsa_area   *dsa;
     476             :     dshash_table *shared_hash;
     477             : 
     478             :     /* the current statistics snapshot */
     479             :     PgStat_Snapshot snapshot;
     480             : } PgStat_LocalState;
     481             : 
     482             : 
     483             : /*
     484             :  * Inline functions defined further below.
     485             :  */
     486             : 
     487             : static inline void pgstat_begin_changecount_write(uint32 *cc);
     488             : static inline void pgstat_end_changecount_write(uint32 *cc);
     489             : static inline uint32 pgstat_begin_changecount_read(uint32 *cc);
     490             : static inline bool pgstat_end_changecount_read(uint32 *cc, uint32 cc_before);
     491             : 
     492             : static inline void pgstat_copy_changecounted_stats(void *dst, void *src, size_t len,
     493             :                                                    uint32 *cc);
     494             : 
     495             : static inline int pgstat_cmp_hash_key(const void *a, const void *b, size_t size, void *arg);
     496             : static inline uint32 pgstat_hash_hash_key(const void *d, size_t size, void *arg);
     497             : static inline size_t pgstat_get_entry_len(PgStat_Kind kind);
     498             : static inline void *pgstat_get_entry_data(PgStat_Kind kind, PgStatShared_Common *entry);
     499             : 
     500             : 
     501             : /*
     502             :  * Functions in pgstat.c
     503             :  */
     504             : 
     505             : extern const PgStat_KindInfo *pgstat_get_kind_info(PgStat_Kind kind);
     506             : 
     507             : #ifdef USE_ASSERT_CHECKING
     508             : extern void pgstat_assert_is_up(void);
     509             : #else
     510             : #define pgstat_assert_is_up() ((void)true)
     511             : #endif
     512             : 
     513             : extern void pgstat_delete_pending_entry(PgStat_EntryRef *entry_ref);
     514             : extern PgStat_EntryRef *pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, Oid objoid, bool *created_entry);
     515             : extern PgStat_EntryRef *pgstat_fetch_pending_entry(PgStat_Kind kind, Oid dboid, Oid objoid);
     516             : 
     517             : extern void *pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, Oid objoid);
     518             : extern void pgstat_snapshot_fixed(PgStat_Kind kind);
     519             : 
     520             : 
     521             : /*
     522             :  * Functions in pgstat_archiver.c
     523             :  */
     524             : 
     525             : extern void pgstat_archiver_reset_all_cb(TimestampTz ts);
     526             : extern void pgstat_archiver_snapshot_cb(void);
     527             : 
     528             : 
     529             : /*
     530             :  * Functions in pgstat_bgwriter.c
     531             :  */
     532             : 
     533             : extern void pgstat_bgwriter_reset_all_cb(TimestampTz ts);
     534             : extern void pgstat_bgwriter_snapshot_cb(void);
     535             : 
     536             : 
     537             : /*
     538             :  * Functions in pgstat_checkpointer.c
     539             :  */
     540             : 
     541             : extern void pgstat_checkpointer_reset_all_cb(TimestampTz ts);
     542             : extern void pgstat_checkpointer_snapshot_cb(void);
     543             : 
     544             : 
     545             : /*
     546             :  * Functions in pgstat_database.c
     547             :  */
     548             : 
     549             : extern void pgstat_report_disconnect(Oid dboid);
     550             : extern void pgstat_update_dbstats(TimestampTz ts);
     551             : extern void AtEOXact_PgStat_Database(bool isCommit, bool parallel);
     552             : 
     553             : extern PgStat_StatDBEntry *pgstat_prep_database_pending(Oid dboid);
     554             : extern void pgstat_reset_database_timestamp(Oid dboid, TimestampTz ts);
     555             : extern bool pgstat_database_flush_cb(PgStat_EntryRef *entry_ref, bool nowait);
     556             : extern void pgstat_database_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts);
     557             : 
     558             : 
     559             : /*
     560             :  * Functions in pgstat_function.c
     561             :  */
     562             : 
     563             : extern bool pgstat_function_flush_cb(PgStat_EntryRef *entry_ref, bool nowait);
     564             : 
     565             : 
     566             : /*
     567             :  * Functions in pgstat_io.c
     568             :  */
     569             : 
     570             : extern bool pgstat_flush_io(bool nowait);
     571             : extern void pgstat_io_reset_all_cb(TimestampTz ts);
     572             : extern void pgstat_io_snapshot_cb(void);
     573             : 
     574             : 
     575             : /*
     576             :  * Functions in pgstat_relation.c
     577             :  */
     578             : 
     579             : extern void AtEOXact_PgStat_Relations(PgStat_SubXactStatus *xact_state, bool isCommit);
     580             : extern void AtEOSubXact_PgStat_Relations(PgStat_SubXactStatus *xact_state, bool isCommit, int nestDepth);
     581             : extern void AtPrepare_PgStat_Relations(PgStat_SubXactStatus *xact_state);
     582             : extern void PostPrepare_PgStat_Relations(PgStat_SubXactStatus *xact_state);
     583             : 
     584             : extern bool pgstat_relation_flush_cb(PgStat_EntryRef *entry_ref, bool nowait);
     585             : extern void pgstat_relation_delete_pending_cb(PgStat_EntryRef *entry_ref);
     586             : 
     587             : 
     588             : /*
     589             :  * Functions in pgstat_replslot.c
     590             :  */
     591             : 
     592             : extern void pgstat_replslot_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts);
     593             : extern void pgstat_replslot_to_serialized_name_cb(const PgStat_HashKey *key, const PgStatShared_Common *header, NameData *name);
     594             : extern bool pgstat_replslot_from_serialized_name_cb(const NameData *name, PgStat_HashKey *key);
     595             : 
     596             : 
     597             : /*
     598             :  * Functions in pgstat_shmem.c
     599             :  */
     600             : 
     601             : extern void pgstat_attach_shmem(void);
     602             : extern void pgstat_detach_shmem(void);
     603             : 
     604             : extern PgStat_EntryRef *pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, Oid objoid,
     605             :                                              bool create, bool *created_entry);
     606             : extern bool pgstat_lock_entry(PgStat_EntryRef *entry_ref, bool nowait);
     607             : extern bool pgstat_lock_entry_shared(PgStat_EntryRef *entry_ref, bool nowait);
     608             : extern void pgstat_unlock_entry(PgStat_EntryRef *entry_ref);
     609             : extern bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, Oid objoid);
     610             : extern void pgstat_drop_all_entries(void);
     611             : extern PgStat_EntryRef *pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, Oid objoid,
     612             :                                                     bool nowait);
     613             : extern void pgstat_reset_entry(PgStat_Kind kind, Oid dboid, Oid objoid, TimestampTz ts);
     614             : extern void pgstat_reset_entries_of_kind(PgStat_Kind kind, TimestampTz ts);
     615             : extern void pgstat_reset_matching_entries(bool (*do_reset) (PgStatShared_HashEntry *, Datum),
     616             :                                           Datum match_data,
     617             :                                           TimestampTz ts);
     618             : 
     619             : extern void pgstat_request_entry_refs_gc(void);
     620             : extern PgStatShared_Common *pgstat_init_entry(PgStat_Kind kind,
     621             :                                               PgStatShared_HashEntry *shhashent);
     622             : 
     623             : 
     624             : /*
     625             :  * Functions in pgstat_slru.c
     626             :  */
     627             : 
     628             : extern bool pgstat_slru_flush(bool nowait);
     629             : extern void pgstat_slru_reset_all_cb(TimestampTz ts);
     630             : extern void pgstat_slru_snapshot_cb(void);
     631             : 
     632             : 
     633             : /*
     634             :  * Functions in pgstat_wal.c
     635             :  */
     636             : 
     637             : extern bool pgstat_flush_wal(bool nowait);
     638             : extern void pgstat_init_wal(void);
     639             : extern bool pgstat_have_pending_wal(void);
     640             : 
     641             : extern void pgstat_wal_reset_all_cb(TimestampTz ts);
     642             : extern void pgstat_wal_snapshot_cb(void);
     643             : 
     644             : 
     645             : /*
     646             :  * Functions in pgstat_subscription.c
     647             :  */
     648             : 
     649             : extern bool pgstat_subscription_flush_cb(PgStat_EntryRef *entry_ref, bool nowait);
     650             : extern void pgstat_subscription_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts);
     651             : 
     652             : 
     653             : /*
     654             :  * Functions in pgstat_xact.c
     655             :  */
     656             : 
     657             : extern PgStat_SubXactStatus *pgstat_get_xact_stack_level(int nest_level);
     658             : extern void pgstat_drop_transactional(PgStat_Kind kind, Oid dboid, Oid objoid);
     659             : extern void pgstat_create_transactional(PgStat_Kind kind, Oid dboid, Oid objoid);
     660             : 
     661             : 
     662             : /*
     663             :  * Variables in pgstat.c
     664             :  */
     665             : 
     666             : extern PGDLLIMPORT PgStat_LocalState pgStatLocal;
     667             : 
     668             : 
     669             : /*
     670             :  * Variables in pgstat_io.c
     671             :  */
     672             : 
     673             : extern PGDLLIMPORT bool have_iostats;
     674             : 
     675             : 
     676             : /*
     677             :  * Variables in pgstat_slru.c
     678             :  */
     679             : 
     680             : extern PGDLLIMPORT bool have_slrustats;
     681             : 
     682             : 
     683             : /*
     684             :  * Implementation of inline functions declared above.
     685             :  */
     686             : 
     687             : /*
     688             :  * Helpers for changecount manipulation. See comments around struct
     689             :  * PgBackendStatus for details.
     690             :  */
     691             : 
     692             : static inline void
     693       11386 : pgstat_begin_changecount_write(uint32 *cc)
     694             : {
     695             :     Assert((*cc & 1) == 0);
     696             : 
     697       11386 :     START_CRIT_SECTION();
     698       11386 :     (*cc)++;
     699       11386 :     pg_write_barrier();
     700       11386 : }
     701             : 
     702             : static inline void
     703       11386 : pgstat_end_changecount_write(uint32 *cc)
     704             : {
     705             :     Assert((*cc & 1) == 1);
     706             : 
     707       11386 :     pg_write_barrier();
     708             : 
     709       11386 :     (*cc)++;
     710             : 
     711       11386 :     END_CRIT_SECTION();
     712       11386 : }
     713             : 
     714             : static inline uint32
     715        4488 : pgstat_begin_changecount_read(uint32 *cc)
     716             : {
     717        4488 :     uint32      before_cc = *cc;
     718             : 
     719        4488 :     CHECK_FOR_INTERRUPTS();
     720             : 
     721        4488 :     pg_read_barrier();
     722             : 
     723        4488 :     return before_cc;
     724             : }
     725             : 
     726             : /*
     727             :  * Returns true if the read succeeded, false if it needs to be repeated.
     728             :  */
     729             : static inline bool
     730        4488 : pgstat_end_changecount_read(uint32 *cc, uint32 before_cc)
     731             : {
     732             :     uint32      after_cc;
     733             : 
     734        4488 :     pg_read_barrier();
     735             : 
     736        4488 :     after_cc = *cc;
     737             : 
     738             :     /* was a write in progress when we started? */
     739        4488 :     if (before_cc & 1)
     740           0 :         return false;
     741             : 
     742             :     /* did writes start and complete while we read? */
     743        4488 :     return before_cc == after_cc;
     744             : }
     745             : 
     746             : 
     747             : /*
     748             :  * helper function for PgStat_KindInfo->snapshot_cb
     749             :  * PgStat_KindInfo->reset_all_cb callbacks.
     750             :  *
     751             :  * Copies out the specified memory area following change-count protocol.
     752             :  */
     753             : static inline void
     754        4488 : pgstat_copy_changecounted_stats(void *dst, void *src, size_t len,
     755             :                                 uint32 *cc)
     756             : {
     757             :     uint32      cc_before;
     758             : 
     759             :     do
     760             :     {
     761        4488 :         cc_before = pgstat_begin_changecount_read(cc);
     762             : 
     763        4488 :         memcpy(dst, src, len);
     764             :     }
     765        4488 :     while (!pgstat_end_changecount_read(cc, cc_before));
     766        4488 : }
     767             : 
     768             : /* helpers for dshash / simplehash hashtables */
     769             : static inline int
     770     5907114 : pgstat_cmp_hash_key(const void *a, const void *b, size_t size, void *arg)
     771             : {
     772             :     Assert(size == sizeof(PgStat_HashKey) && arg == NULL);
     773     5907114 :     return memcmp(a, b, sizeof(PgStat_HashKey));
     774             : }
     775             : 
     776             : static inline uint32
     777     7583512 : pgstat_hash_hash_key(const void *d, size_t size, void *arg)
     778             : {
     779     7583512 :     const char *key = (const char *) d;
     780             : 
     781             :     Assert(size == sizeof(PgStat_HashKey) && arg == NULL);
     782     7583512 :     return fasthash32(key, size, 0);
     783             : }
     784             : 
     785             : /*
     786             :  * The length of the data portion of a shared memory stats entry (i.e. without
     787             :  * transient data such as refcounts, lwlocks, ...).
     788             :  */
     789             : static inline size_t
     790      603734 : pgstat_get_entry_len(PgStat_Kind kind)
     791             : {
     792      603734 :     return pgstat_get_kind_info(kind)->shared_data_len;
     793             : }
     794             : 
     795             : /*
     796             :  * Returns a pointer to the data portion of a shared memory stats entry.
     797             :  */
     798             : static inline void *
     799      662240 : pgstat_get_entry_data(PgStat_Kind kind, PgStatShared_Common *entry)
     800             : {
     801      662240 :     size_t      off = pgstat_get_kind_info(kind)->shared_data_off;
     802             : 
     803             :     Assert(off != 0 && off < PG_UINT32_MAX);
     804             : 
     805      662240 :     return ((char *) (entry)) + off;
     806             : }
     807             : 
     808             : #endif                          /* PGSTAT_INTERNAL_H */

Generated by: LCOV version 1.14