mirror of
https://github.com/postgres/postgres.git
synced 2025-10-27 00:12:01 +03:00
Fix mis-attribution of checksum failure stats to the wrong database
Checksum failure stats could be attributed to the wrong database in two cases: - when a read of a shared relation encountered a checksum error , it would be attributed to the current database, instead of the "database" representing shared relations - when using CREATE DATABASE ... STRATEGY WAL_LOG checksum errors in the source database would be attributed to the current database The checksum stats reporting via PageIsVerifiedExtended(PIV_REPORT_STAT) does not have access to the information about what database a page belongs to. This fixes the issue by removing PIV_REPORT_STAT and delegating the responsibility to report stats to the caller, which now can learn about the number of stats via a new optional argument. As this changes the signature of PageIsVerifiedExtended() and all callers should adapt to the new signature, use the occasion to rename the function to PageIsVerified() and remove the compatibility macro. We could instead have fixed this by adding information about the database to the args of PageIsVerified(), but there are soon-to-be-applied patches that need to separate the stats reporting from the PageIsVerified() call anyway. Those patches also include testing for the failure paths, something we inexplicably have not had. As there is no caller of pgstat_report_checksum_failure() left, remove it. It'd be possible, but awkward to fix this in the back branches. We considered doing the work not quite worth it, as mis-attributed stats should still elicit concern. The emitted error messages do allow to attribute the errors correctly. Discussion: https://postgr.es/m/5tyic6epvdlmd6eddgelv47syg2b5cpwffjam54axp25xyq2ga@ptwkinxqo3az Discussion: https://postgr.es/m/mglpvvbhighzuwudjxzu4br65qqcxsnyvio3nl4fbog3qknwhg@e4gt7npsohuz
This commit is contained in:
@@ -61,7 +61,7 @@ PageInit(Page page, Size pageSize, Size specialSize)
|
||||
|
||||
|
||||
/*
|
||||
* PageIsVerifiedExtended
|
||||
* PageIsVerified
|
||||
* Check that the page header and checksum (if any) appear valid.
|
||||
*
|
||||
* This is called when a page has just been read in from disk. The idea is
|
||||
@@ -81,11 +81,13 @@ PageInit(Page page, Size pageSize, Size specialSize)
|
||||
* If flag PIV_LOG_WARNING is set, a WARNING is logged in the event of
|
||||
* a checksum failure.
|
||||
*
|
||||
* If flag PIV_REPORT_STAT is set, a checksum failure is reported directly
|
||||
* to pgstat.
|
||||
* To allow the caller to report statistics about checksum failures,
|
||||
* *checksum_failure_p can be passed in. Note that there may be checksum
|
||||
* failures even if this function returns true, due to
|
||||
* ignore_checksum_failure.
|
||||
*/
|
||||
bool
|
||||
PageIsVerifiedExtended(PageData *page, BlockNumber blkno, int flags)
|
||||
PageIsVerified(PageData *page, BlockNumber blkno, int flags, bool *checksum_failure_p)
|
||||
{
|
||||
const PageHeaderData *p = (const PageHeaderData *) page;
|
||||
size_t *pagebytes;
|
||||
@@ -93,6 +95,9 @@ PageIsVerifiedExtended(PageData *page, BlockNumber blkno, int flags)
|
||||
bool header_sane = false;
|
||||
uint16 checksum = 0;
|
||||
|
||||
if (checksum_failure_p)
|
||||
*checksum_failure_p = false;
|
||||
|
||||
/*
|
||||
* Don't verify page data unless the page passes basic non-zero test
|
||||
*/
|
||||
@@ -103,7 +108,11 @@ PageIsVerifiedExtended(PageData *page, BlockNumber blkno, int flags)
|
||||
checksum = pg_checksum_page(page, blkno);
|
||||
|
||||
if (checksum != p->pd_checksum)
|
||||
{
|
||||
checksum_failure = true;
|
||||
if (checksum_failure_p)
|
||||
*checksum_failure_p = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -141,9 +150,6 @@ PageIsVerifiedExtended(PageData *page, BlockNumber blkno, int flags)
|
||||
errmsg("page verification failed, calculated checksum %u but expected %u",
|
||||
checksum, p->pd_checksum)));
|
||||
|
||||
if ((flags & PIV_REPORT_STAT) != 0)
|
||||
pgstat_report_checksum_failure();
|
||||
|
||||
if (header_sane && ignore_checksum_failure)
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user