From 9e4664d950c125a1ff7bb29cd1593ca37f8b0c01 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Thu, 11 Jul 2024 16:12:04 +0900 Subject: [PATCH] Add a new 'F' entry type for fixed-numbered stats in pgstats file This new entry type is used for all the fixed-numbered statistics, making possible support for custom pluggable stats. In short, we need to be able to detect more easily if a stats kind exists or not when reading back its data from the pgstats file without a dependency on the order of the entries read. The kind ID of the stats is added to the data written. The data is written in the same fashion as previously, with the fixed-numbered stats first and the dshash entries next. The read part becomes more flexible, loading fixed-numbered stats into shared memory based on the new entry type found. Bump PGSTAT_FILE_FORMAT_ID. Reviewed-by: Bertrand Drouvot Discussion: https://postgr.es/m/Zot5bxoPYdS7yaoy@paquier.xyz --- src/backend/utils/activity/pgstat.c | 51 +++++++++++++++++++---------- src/include/pgstat.h | 2 +- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c index ef435167f7f..c0ec9e8195a 100644 --- a/src/backend/utils/activity/pgstat.c +++ b/src/backend/utils/activity/pgstat.c @@ -132,6 +132,7 @@ * --------- */ #define PGSTAT_FILE_ENTRY_END 'E' /* end of file */ +#define PGSTAT_FILE_ENTRY_FIXED 'F' /* fixed-numbered stats entry */ #define PGSTAT_FILE_ENTRY_NAME 'N' /* stats entry identified by name */ #define PGSTAT_FILE_ENTRY_HASH 'S' /* stats entry identified by * PgStat_HashKey */ @@ -1396,6 +1397,9 @@ pgstat_write_statsfile(void) pgstat_build_snapshot_fixed(kind); ptr = ((char *) &pgStatLocal.snapshot) + info->snapshot_ctl_off; + + fputc(PGSTAT_FILE_ENTRY_FIXED, fpout); + write_chunk_s(fpout, &kind); write_chunk(fpout, ptr, info->shared_data_len); } @@ -1537,25 +1541,9 @@ pgstat_read_statsfile(void) format_id != PGSTAT_FILE_FORMAT_ID) goto error; - /* Read various stats structs with fixed number of objects */ - for (int kind = PGSTAT_KIND_FIRST_VALID; kind <= PGSTAT_KIND_LAST; kind++) - { - char *ptr; - const PgStat_KindInfo *info = pgstat_get_kind_info(kind); - - if (!info->fixed_amount) - continue; - - Assert(info->shared_ctl_off != 0); - - ptr = ((char *) shmem) + info->shared_ctl_off + info->shared_data_off; - if (!read_chunk(fpin, ptr, info->shared_data_len)) - goto error; - } - /* - * We found an existing statistics file. Read it and put all the hash - * table entries into place. + * We found an existing statistics file. Read it and put all the stats + * data into place. */ for (;;) { @@ -1563,6 +1551,33 @@ pgstat_read_statsfile(void) switch (t) { + case PGSTAT_FILE_ENTRY_FIXED: + { + PgStat_Kind kind; + const PgStat_KindInfo *info; + char *ptr; + + /* entry for fixed-numbered stats */ + if (!read_chunk_s(fpin, &kind)) + goto error; + + if (!pgstat_is_kind_valid(kind)) + goto error; + + info = pgstat_get_kind_info(kind); + + if (!info->fixed_amount) + goto error; + + /* Load back stats into shared memory */ + ptr = ((char *) shmem) + info->shared_ctl_off + + info->shared_data_off; + + if (!read_chunk(fpin, ptr, info->shared_data_len)) + goto error; + + break; + } case PGSTAT_FILE_ENTRY_HASH: case PGSTAT_FILE_ENTRY_NAME: { diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 2136239710e..6b99bb8aadf 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -235,7 +235,7 @@ typedef struct PgStat_TableXactStatus * ------------------------------------------------------------ */ -#define PGSTAT_FILE_FORMAT_ID 0x01A5BCAC +#define PGSTAT_FILE_FORMAT_ID 0x01A5BCAD typedef struct PgStat_ArchiverStats {