]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Add more debugging information when failing to read pgstats files
authorMichael Paquier <michael@paquier.xyz>
Tue, 30 Jul 2024 06:08:21 +0000 (15:08 +0900)
committerMichael Paquier <michael@paquier.xyz>
Tue, 30 Jul 2024 06:08:21 +0000 (15:08 +0900)
This is useful to know which part of a stats file is corrupted when
reading it, adding to the server logs a WARNING with details about what
could not be read before giving up with the remaining data in the file.

Author: Michael Paquier
Reviewed-by: Bertrand Drouvot
Discussion: https://postgr.es/m/Zp8o6_cl0KSgsnvS@paquier.xyz

src/backend/utils/activity/pgstat.c

index 2e22bf270781ae5b1cee0f83da7de673e67a726d..228cdf73f775ba15baccf5cdea4af264fe8d491c 100644 (file)
@@ -1537,9 +1537,18 @@ pgstat_read_statsfile(void)
        /*
         * Verify it's of the expected format.
         */
-       if (!read_chunk_s(fpin, &format_id) ||
-               format_id != PGSTAT_FILE_FORMAT_ID)
+       if (!read_chunk_s(fpin, &format_id))
+       {
+               elog(WARNING, "could not read format ID");
+               goto error;
+       }
+
+       if (format_id != PGSTAT_FILE_FORMAT_ID)
+       {
+               elog(WARNING, "found incorrect format ID %d (expected %d)",
+                        format_id, PGSTAT_FILE_FORMAT_ID);
                goto error;
+       }
 
        /*
         * We found an existing statistics file. Read it and put all the stats
@@ -1559,22 +1568,37 @@ pgstat_read_statsfile(void)
 
                                        /* entry for fixed-numbered stats */
                                        if (!read_chunk_s(fpin, &kind))
+                                       {
+                                               elog(WARNING, "could not read stats kind for entry of type %c", t);
                                                goto error;
+                                       }
 
                                        if (!pgstat_is_kind_valid(kind))
+                                       {
+                                               elog(WARNING, "invalid stats kind %d for entry of type %c",
+                                                        kind, t);
                                                goto error;
+                                       }
 
                                        info = pgstat_get_kind_info(kind);
 
                                        if (!info->fixed_amount)
+                                       {
+                                               elog(WARNING, "invalid fixed_amount in stats kind %d for entry of type %c",
+                                                        kind, t);
                                                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))
+                                       {
+                                               elog(WARNING, "could not read data of stats kind %d for entry of type %c with size %u",
+                                                        kind, t, info->shared_data_len);
                                                goto error;
+                                       }
 
                                        break;
                                }
@@ -1591,10 +1615,17 @@ pgstat_read_statsfile(void)
                                        {
                                                /* normal stats entry, identified by PgStat_HashKey */
                                                if (!read_chunk_s(fpin, &key))
+                                               {
+                                                       elog(WARNING, "could not read key for entry of type %c", t);
                                                        goto error;
+                                               }
 
                                                if (!pgstat_is_kind_valid(key.kind))
+                                               {
+                                                       elog(WARNING, "invalid stats kind for entry %d/%u/%u of type %c",
+                                                                key.kind, key.dboid, key.objoid, t);
                                                        goto error;
+                                               }
                                        }
                                        else
                                        {
@@ -1604,22 +1635,41 @@ pgstat_read_statsfile(void)
                                                NameData        name;
 
                                                if (!read_chunk_s(fpin, &kind))
+                                               {
+                                                       elog(WARNING, "could not read stats kind for entry of type %c", t);
                                                        goto error;
+                                               }
                                                if (!read_chunk_s(fpin, &name))
+                                               {
+                                                       elog(WARNING, "could not read name of stats kind %d for entry of type %c",
+                                                                kind, t);
                                                        goto error;
+                                               }
                                                if (!pgstat_is_kind_valid(kind))
+                                               {
+                                                       elog(WARNING, "invalid stats kind %d for entry of type %c",
+                                                                kind, t);
                                                        goto error;
+                                               }
 
                                                kind_info = pgstat_get_kind_info(kind);
 
                                                if (!kind_info->from_serialized_name)
+                                               {
+                                                       elog(WARNING, "invalid from_serialized_name in stats kind %d for entry of type %c",
+                                                                kind, t);
                                                        goto error;
+                                               }
 
                                                if (!kind_info->from_serialized_name(&name, &key))
                                                {
                                                        /* skip over data for entry we don't care about */
                                                        if (fseek(fpin, pgstat_get_entry_len(kind), SEEK_CUR) != 0)
+                                                       {
+                                                               elog(WARNING, "could not seek \"%s\" of stats kind %d for entry of type %c",
+                                                                        NameStr(name), kind, t);
                                                                goto error;
+                                                       }
 
                                                        continue;
                                                }
@@ -1638,8 +1688,8 @@ pgstat_read_statsfile(void)
                                        if (found)
                                        {
                                                dshash_release_lock(pgStatLocal.shared_hash, p);
-                                               elog(WARNING, "found duplicate stats entry %d/%u/%u",
-                                                        key.kind, key.dboid, key.objoid);
+                                               elog(WARNING, "found duplicate stats entry %d/%u/%u of type %c",
+                                                        key.kind, key.dboid, key.objoid, t);
                                                goto error;
                                        }
 
@@ -1649,7 +1699,11 @@ pgstat_read_statsfile(void)
                                        if (!read_chunk(fpin,
                                                                        pgstat_get_entry_data(key.kind, header),
                                                                        pgstat_get_entry_len(key.kind)))
+                                       {
+                                               elog(WARNING, "could not read data for entry %d/%u/%u of type %c",
+                                                        key.kind, key.dboid, key.objoid, t);
                                                goto error;
+                                       }
 
                                        break;
                                }
@@ -1660,11 +1714,15 @@ pgstat_read_statsfile(void)
                                 * file
                                 */
                                if (fgetc(fpin) != EOF)
+                               {
+                                       elog(WARNING, "could not read end-of-file");
                                        goto error;
+                               }
 
                                goto done;
 
                        default:
+                               elog(WARNING, "could not read entry of type %c", t);
                                goto error;
                }
        }