Add a new 'F' entry type for fixed-numbered stats in pgstats file
authorMichael Paquier <[email protected]>
Thu, 11 Jul 2024 07:12:04 +0000 (16:12 +0900)
committerMichael Paquier <[email protected]>
Thu, 11 Jul 2024 07:12:44 +0000 (16:12 +0900)
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/[email protected]

src/backend/utils/activity/pgstat.c
src/include/pgstat.h

index ef435167f7f0dcb6101080ae64b1dae8a974121a..c0ec9e8195a2f931710cd201199d73b44ec8b4e6 100644 (file)
  * ---------
  */
 #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:
                {
index 2136239710e33d8acc3c2929f9f73c202e8de13c..6b99bb8aadfca4495ae6e9ca3fc8624436f24399 100644 (file)
@@ -235,7 +235,7 @@ typedef struct PgStat_TableXactStatus
  * ------------------------------------------------------------
  */
 
-#define PGSTAT_FILE_FORMAT_ID  0x01A5BCAC
+#define PGSTAT_FILE_FORMAT_ID  0x01A5BCAD
 
 typedef struct PgStat_ArchiverStats
 {