From ca1ba50fcb6f85ac603aecbc184c7c59886c2a7c Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 30 Jul 2024 15:08:21 +0900 Subject: [PATCH] Add more debugging information when failing to read pgstats files 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 | 66 +++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c index 2e22bf2707..228cdf73f7 100644 --- a/src/backend/utils/activity/pgstat.c +++ b/src/backend/utils/activity/pgstat.c @@ -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; } }