From 508decc1c057a6656f3c13ca2238bd9036c9a838 Mon Sep 17 00:00:00 2001 From: Mikhail Litsarev Date: Mon, 20 Jan 2025 15:40:12 +0300 Subject: [PATCH] pg_stat_statements: improve loading and saving routines for the dump file. Exclude reading/writing pgssEntry mutex from/into the dump file. Update the magic number identifying the stats file format. --- contrib/pg_stat_statements/pg_stat_statements.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 9778407cba30..7b3fd7875122 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -85,7 +85,7 @@ PG_MODULE_MAGIC_EXT( #define PGSS_TEXT_FILE PG_STAT_TMP_DIR "/pgss_query_texts.stat" /* Magic number identifying the stats file format */ -static const uint32 PGSS_FILE_HEADER = 0x20220408; +static const uint32 PGSS_FILE_HEADER = 0x20250120; /* PostgreSQL major version number, changes in which invalidate all entries */ static const uint32 PGSS_PG_MAJOR_VERSION = PG_VERSION_NUM / 100; @@ -237,7 +237,11 @@ typedef struct pgssEntry int encoding; /* query text encoding */ TimestampTz stats_since; /* timestamp of entry allocation */ TimestampTz minmax_stats_since; /* timestamp of last min/max values reset */ - slock_t mutex; /* protects the counters only */ + /* + * protects the counters only. Should be the very last field, as this field + * isn't copied to PGSS_DUMP_FILE + */ + slock_t mutex; } pgssEntry; /* @@ -628,7 +632,8 @@ pgss_shmem_startup(void) pgssEntry *entry; Size query_offset; - if (fread(&temp, sizeof(pgssEntry), 1, file) != 1) + /* Read whole pgssEntry excluding very last mutex field */ + if (fread(&temp, offsetof(pgssEntry, mutex), 1, file) != 1) goto read_error; /* Encoding is the only field we can easily sanity-check */ @@ -785,7 +790,8 @@ pgss_shmem_shutdown(int code, Datum arg) if (qstr == NULL) continue; /* Ignore any entries with bogus texts */ - if (fwrite(entry, sizeof(pgssEntry), 1, file) != 1 || + /* Write whole pgssEntry excluding very last mutex field */ + if (fwrite(entry, offsetof(pgssEntry, mutex), 1, file) != 1 || fwrite(qstr, 1, len + 1, file) != len + 1) { /* note: we assume hash_seq_term won't change errno */