aboutsummaryrefslogtreecommitdiff
path: root/src/include/utils
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2024-08-04 19:41:24 +0900
committerMichael Paquier <michael@paquier.xyz>2024-08-04 19:41:24 +0900
commit7949d9594582ab49dee221e1db1aa5401ace49d4 (patch)
treead74385fbb0ef9f8b8d5a125d4b6e7ddc87ab20b /src/include/utils
parent365b5a345b2680615527b23ee6befa09a2f784f2 (diff)
downloadpostgresql-7949d9594582ab49dee221e1db1aa5401ace49d4.tar.gz
postgresql-7949d9594582ab49dee221e1db1aa5401ace49d4.zip
Introduce pluggable APIs for Cumulative Statistics
This commit adds support in the backend for $subject, allowing out-of-core extensions to plug their own custom kinds of cumulative statistics. This feature has come up a few times into the lists, and the first, original, suggestion came from Andres Freund, about pg_stat_statements to use the cumulative statistics APIs in shared memory rather than its own less efficient internals. The advantage of this implementation is that this can be extended to any kind of statistics. The stats kinds are divided into two parts: - The in-core "builtin" stats kinds, with designated initializers, able to use IDs up to 128. - The "custom" stats kinds, able to use a range of IDs from 128 to 256 (128 slots available as of this patch), with information saved in TopMemoryContext. This can be made larger, if necessary. There are two types of cumulative statistics in the backend: - For fixed-numbered objects (like WAL, archiver, etc.). These are attached to the snapshot and pgstats shmem control structures for efficiency, and built-in stats kinds still do that to avoid any redirection penalty. The data of custom kinds is stored in a first array in snapshot structure and a second array in the shmem control structure, both indexed by their ID, acting as an equivalent of the builtin stats. - For variable-numbered objects (like tables, functions, etc.). These are stored in a dshash using the stats kind ID in the hash lookup key. Internally, the handling of the builtin stats is unchanged, and both fixed and variabled-numbered objects are supported. Structure definitions for builtin stats kinds are renamed to reflect better the differences with custom kinds. Like custom RMGRs, custom cumulative statistics can only be loaded with shared_preload_libraries at startup, and must allocate a unique ID shared across all the PostgreSQL extension ecosystem with the following wiki page to avoid conflicts: https://wiki.postgresql.org/wiki/CustomCumulativeStats This makes the detection of the stats kinds and their handling when reading and writing stats much easier than, say, allocating IDs for stats kinds from a shared memory counter, that may change the ID used by a stats kind across restarts. When under development, extensions can use PGSTAT_KIND_EXPERIMENTAL. Two examples that can be used as templates for fixed-numbered and variable-numbered stats kinds will be added in some follow-up commits, with tests to provide coverage. Some documentation is added to explain how to use this plugin facility. Author: Michael Paquier Reviewed-by: Dmitry Dolgov, Bertrand Drouvot Discussion: https://postgr.es/m/Zmqm9j5EO0I4W8dx@paquier.xyz
Diffstat (limited to 'src/include/utils')
-rw-r--r--src/include/utils/pgstat_internal.h22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h
index 778f625ca1d..26b4b784060 100644
--- a/src/include/utils/pgstat_internal.h
+++ b/src/include/utils/pgstat_internal.h
@@ -195,7 +195,8 @@ typedef struct PgStat_KindInfo
/*
* The size of an entry in the shared stats hash table (pointed to by
- * PgStatShared_HashEntry->body).
+ * PgStatShared_HashEntry->body). For fixed-numbered statistics, this is
+ * the size of an entry in PgStat_ShmemControl->custom_data.
*/
uint32 shared_size;
@@ -446,6 +447,13 @@ typedef struct PgStat_ShmemControl
PgStatShared_IO io;
PgStatShared_SLRU slru;
PgStatShared_Wal wal;
+
+ /*
+ * Custom stats data with fixed-numbered objects, indexed by (PgStat_Kind
+ * - PGSTAT_KIND_CUSTOM_MIN).
+ */
+ void *custom_data[PGSTAT_KIND_CUSTOM_SIZE];
+
} PgStat_ShmemControl;
@@ -459,7 +467,7 @@ typedef struct PgStat_Snapshot
/* time at which snapshot was taken */
TimestampTz snapshot_timestamp;
- bool fixed_valid[PGSTAT_NUM_KINDS];
+ bool fixed_valid[PGSTAT_KIND_BUILTIN_SIZE];
PgStat_ArchiverStats archiver;
@@ -473,6 +481,14 @@ typedef struct PgStat_Snapshot
PgStat_WalStats wal;
+ /*
+ * Data in snapshot for custom fixed-numbered statistics, indexed by
+ * (PgStat_Kind - PGSTAT_KIND_CUSTOM_MIN). Each entry is allocated in
+ * TopMemoryContext, for a size of PgStat_KindInfo->shared_data_len.
+ */
+ bool custom_valid[PGSTAT_KIND_CUSTOM_SIZE];
+ void *custom_data[PGSTAT_KIND_CUSTOM_SIZE];
+
/* to free snapshot in bulk */
MemoryContext context;
struct pgstat_snapshot_hash *stats;
@@ -516,6 +532,8 @@ static inline void *pgstat_get_entry_data(PgStat_Kind kind, PgStatShared_Common
*/
extern const PgStat_KindInfo *pgstat_get_kind_info(PgStat_Kind kind);
+extern void pgstat_register_kind(PgStat_Kind kind,
+ const PgStat_KindInfo *kind_info);
#ifdef USE_ASSERT_CHECKING
extern void pgstat_assert_is_up(void);