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
This commit is contained in:
parent
7f56eaff2f
commit
ca1ba50fcb
@ -1537,9 +1537,18 @@ pgstat_read_statsfile(void)
|
|||||||
/*
|
/*
|
||||||
* Verify it's of the expected format.
|
* Verify it's of the expected format.
|
||||||
*/
|
*/
|
||||||
if (!read_chunk_s(fpin, &format_id) ||
|
if (!read_chunk_s(fpin, &format_id))
|
||||||
format_id != PGSTAT_FILE_FORMAT_ID)
|
{
|
||||||
|
elog(WARNING, "could not read format ID");
|
||||||
goto error;
|
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
|
* 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 */
|
/* entry for fixed-numbered stats */
|
||||||
if (!read_chunk_s(fpin, &kind))
|
if (!read_chunk_s(fpin, &kind))
|
||||||
|
{
|
||||||
|
elog(WARNING, "could not read stats kind for entry of type %c", t);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pgstat_is_kind_valid(kind))
|
if (!pgstat_is_kind_valid(kind))
|
||||||
|
{
|
||||||
|
elog(WARNING, "invalid stats kind %d for entry of type %c",
|
||||||
|
kind, t);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
info = pgstat_get_kind_info(kind);
|
info = pgstat_get_kind_info(kind);
|
||||||
|
|
||||||
if (!info->fixed_amount)
|
if (!info->fixed_amount)
|
||||||
|
{
|
||||||
|
elog(WARNING, "invalid fixed_amount in stats kind %d for entry of type %c",
|
||||||
|
kind, t);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Load back stats into shared memory */
|
/* Load back stats into shared memory */
|
||||||
ptr = ((char *) shmem) + info->shared_ctl_off +
|
ptr = ((char *) shmem) + info->shared_ctl_off +
|
||||||
info->shared_data_off;
|
info->shared_data_off;
|
||||||
|
|
||||||
if (!read_chunk(fpin, ptr, info->shared_data_len))
|
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;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1591,10 +1615,17 @@ pgstat_read_statsfile(void)
|
|||||||
{
|
{
|
||||||
/* normal stats entry, identified by PgStat_HashKey */
|
/* normal stats entry, identified by PgStat_HashKey */
|
||||||
if (!read_chunk_s(fpin, &key))
|
if (!read_chunk_s(fpin, &key))
|
||||||
|
{
|
||||||
|
elog(WARNING, "could not read key for entry of type %c", t);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pgstat_is_kind_valid(key.kind))
|
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;
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1604,22 +1635,41 @@ pgstat_read_statsfile(void)
|
|||||||
NameData name;
|
NameData name;
|
||||||
|
|
||||||
if (!read_chunk_s(fpin, &kind))
|
if (!read_chunk_s(fpin, &kind))
|
||||||
|
{
|
||||||
|
elog(WARNING, "could not read stats kind for entry of type %c", t);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
if (!read_chunk_s(fpin, &name))
|
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;
|
goto error;
|
||||||
|
}
|
||||||
if (!pgstat_is_kind_valid(kind))
|
if (!pgstat_is_kind_valid(kind))
|
||||||
|
{
|
||||||
|
elog(WARNING, "invalid stats kind %d for entry of type %c",
|
||||||
|
kind, t);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
kind_info = pgstat_get_kind_info(kind);
|
kind_info = pgstat_get_kind_info(kind);
|
||||||
|
|
||||||
if (!kind_info->from_serialized_name)
|
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;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (!kind_info->from_serialized_name(&name, &key))
|
if (!kind_info->from_serialized_name(&name, &key))
|
||||||
{
|
{
|
||||||
/* skip over data for entry we don't care about */
|
/* skip over data for entry we don't care about */
|
||||||
if (fseek(fpin, pgstat_get_entry_len(kind), SEEK_CUR) != 0)
|
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;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1638,8 +1688,8 @@ pgstat_read_statsfile(void)
|
|||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
dshash_release_lock(pgStatLocal.shared_hash, p);
|
dshash_release_lock(pgStatLocal.shared_hash, p);
|
||||||
elog(WARNING, "found duplicate stats entry %d/%u/%u",
|
elog(WARNING, "found duplicate stats entry %d/%u/%u of type %c",
|
||||||
key.kind, key.dboid, key.objoid);
|
key.kind, key.dboid, key.objoid, t);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1649,7 +1699,11 @@ pgstat_read_statsfile(void)
|
|||||||
if (!read_chunk(fpin,
|
if (!read_chunk(fpin,
|
||||||
pgstat_get_entry_data(key.kind, header),
|
pgstat_get_entry_data(key.kind, header),
|
||||||
pgstat_get_entry_len(key.kind)))
|
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;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1660,11 +1714,15 @@ pgstat_read_statsfile(void)
|
|||||||
* file
|
* file
|
||||||
*/
|
*/
|
||||||
if (fgetc(fpin) != EOF)
|
if (fgetc(fpin) != EOF)
|
||||||
|
{
|
||||||
|
elog(WARNING, "could not read end-of-file");
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
elog(WARNING, "could not read entry of type %c", t);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user