Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 017e78a

Browse files
committed
Extend PageIsVerified() to handle more custom options
This is useful for checks of relation pages without having to load the pages into the shared buffers, and two cases can make use of that: page verification in base backups and the online, lock-safe, flavor. Compatibility is kept with past versions using a routine that calls the new extended routine with the set of options compatible with the original version. Contrary to d401c576, a macro cannot be used as there may be external code relying on the presence of the original routine. This is applied down to 11, where this will be used by a follow-up commit addressing a set of issues with page verification in base backups. Extracted from a larger patch by the same author. Author: Anastasia Lubennikova Reviewed-by: Michael Paquier, Julien Rouhaud Discussion: https://postgr.es/m/608f3476-0598-2514-2c03-e05c7d2b0cbd@postgrespro.ru Backpatch-through: 11
1 parent 2330f4d commit 017e78a

File tree

4 files changed

+44
-14
lines changed

4 files changed

+44
-14
lines changed

src/backend/catalog/storage.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
443443

444444
smgrread(src, forkNum, blkno, buf.data);
445445

446-
if (!PageIsVerified(page, blkno))
446+
if (!PageIsVerifiedExtended(page, blkno,
447+
PIV_LOG_WARNING | PIV_REPORT_STAT))
447448
ereport(ERROR,
448449
(errcode(ERRCODE_DATA_CORRUPTED),
449450
errmsg("invalid page in block %u of relation %s",

src/backend/storage/buffer/bufmgr.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,8 @@ ReadBuffer(Relation reln, BlockNumber blockNum)
624624
*
625625
* In RBM_NORMAL mode, the page is read from disk, and the page header is
626626
* validated. An error is thrown if the page header is not valid. (But
627-
* note that an all-zero page is considered "valid"; see PageIsVerified().)
627+
* note that an all-zero page is considered "valid"; see
628+
* PageIsVerifiedExtended().)
628629
*
629630
* RBM_ZERO_ON_ERROR is like the normal mode, but if the page header is not
630631
* valid, the page is zeroed instead of throwing an error. This is intended
@@ -916,7 +917,8 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum,
916917
}
917918

918919
/* check for garbage data */
919-
if (!PageIsVerified((Page) bufBlock, blockNum))
920+
if (!PageIsVerifiedExtended((Page) bufBlock, blockNum,
921+
PIV_LOG_WARNING | PIV_REPORT_STAT))
920922
{
921923
if (mode == RBM_ZERO_ON_ERROR || zero_damaged_pages)
922924
{

src/backend/storage/page/bufpage.c

+26-6
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ PageInit(Page page, Size pageSize, Size specialSize)
6262

6363
/*
6464
* PageIsVerified
65+
* Utility wrapper for PageIsVerifiedExtended().
66+
*/
67+
bool
68+
PageIsVerified(Page page, BlockNumber blkno)
69+
{
70+
return PageIsVerifiedExtended(page, blkno,
71+
PIV_LOG_WARNING | PIV_REPORT_STAT);
72+
}
73+
74+
75+
/*
76+
* PageIsVerifiedExtended
6577
* Check that the page header and checksum (if any) appear valid.
6678
*
6779
* This is called when a page has just been read in from disk. The idea is
@@ -77,9 +89,15 @@ PageInit(Page page, Size pageSize, Size specialSize)
7789
* allow zeroed pages here, and are careful that the page access macros
7890
* treat such a page as empty and without free space. Eventually, VACUUM
7991
* will clean up such a page and make it usable.
92+
*
93+
* If flag PIV_LOG_WARNING is set, a WARNING is logged in the event of
94+
* a checksum failure.
95+
*
96+
* If flag PIV_REPORT_STAT is set, a checksum failure is reported directly
97+
* to pgstat.
8098
*/
8199
bool
82-
PageIsVerified(Page page, BlockNumber blkno)
100+
PageIsVerifiedExtended(Page page, BlockNumber blkno, int flags)
83101
{
84102
PageHeader p = (PageHeader) page;
85103
size_t *pagebytes;
@@ -140,12 +158,14 @@ PageIsVerified(Page page, BlockNumber blkno)
140158
*/
141159
if (checksum_failure)
142160
{
143-
ereport(WARNING,
144-
(errcode(ERRCODE_DATA_CORRUPTED),
145-
errmsg("page verification failed, calculated checksum %u but expected %u",
146-
checksum, p->pd_checksum)));
161+
if ((flags & PIV_LOG_WARNING) != 0)
162+
ereport(WARNING,
163+
(errcode(ERRCODE_DATA_CORRUPTED),
164+
errmsg("page verification failed, calculated checksum %u but expected %u",
165+
checksum, p->pd_checksum)));
147166

148-
pgstat_report_checksum_failure();
167+
if ((flags & PIV_REPORT_STAT) != 0)
168+
pgstat_report_checksum_failure();
149169

150170
if (header_sane && ignore_checksum_failure)
151171
return true;

src/include/storage/bufpage.h

+12-5
Original file line numberDiff line numberDiff line change
@@ -410,26 +410,33 @@ do { \
410410
* extern declarations
411411
* ----------------------------------------------------------------
412412
*/
413+
414+
/* flags for PageAddItemExtended() */
413415
#define PAI_OVERWRITE (1 << 0)
414416
#define PAI_IS_HEAP (1 << 1)
415417

418+
/* flags for PageIsVerifiedExtended() */
419+
#define PIV_LOG_WARNING (1 << 0)
420+
#define PIV_REPORT_STAT (1 << 1)
421+
416422
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap) \
417423
PageAddItemExtended(page, item, size, offsetNumber, \
418424
((overwrite) ? PAI_OVERWRITE : 0) | \
419425
((is_heap) ? PAI_IS_HEAP : 0))
420426

421427
/*
422-
* Check that BLCKSZ is a multiple of sizeof(size_t). In PageIsVerified(),
423-
* it is much faster to check if a page is full of zeroes using the native
424-
* word size. Note that this assertion is kept within a header to make
425-
* sure that StaticAssertDecl() works across various combinations of
426-
* platforms and compilers.
428+
* Check that BLCKSZ is a multiple of sizeof(size_t). In
429+
* PageIsVerifiedExtended(), it is much faster to check if a page is
430+
* full of zeroes using the native word size. Note that this assertion
431+
* is kept within a header to make sure that StaticAssertDecl() works
432+
* across various combinations of platforms and compilers.
427433
*/
428434
StaticAssertDecl(BLCKSZ == ((BLCKSZ / sizeof(size_t)) * sizeof(size_t)),
429435
"BLCKSZ has to be a multiple of sizeof(size_t)");
430436

431437
extern void PageInit(Page page, Size pageSize, Size specialSize);
432438
extern bool PageIsVerified(Page page, BlockNumber blkno);
439+
extern bool PageIsVerifiedExtended(Page page, BlockNumber blkno, int flags);
433440
extern OffsetNumber PageAddItemExtended(Page page, Item item, Size size,
434441
OffsetNumber offsetNumber, int flags);
435442
extern Page PageGetTempPage(Page page);

0 commit comments

Comments
 (0)