aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2024-07-30 15:08:21 +0900
committerMichael Paquier <michael@paquier.xyz>2024-07-30 15:08:21 +0900
commitca1ba50fcb6f85ac603aecbc184c7c59886c2a7c (patch)
tree290df0d6ab628a96dd631eda5fe3b74860f021b9 /src/backend/utils
parent7f56eaff2fb0f3541c5c6ef8c1099e7f0618b461 (diff)
downloadpostgresql-ca1ba50fcb6f85ac603aecbc184c7c59886c2a7c.tar.gz
postgresql-ca1ba50fcb6f85ac603aecbc184c7c59886c2a7c.zip
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
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/activity/pgstat.c66
1 files changed, 62 insertions, 4 deletions
diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c
index 2e22bf27078..228cdf73f77 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;
}
}