]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Extend PageIsVerified() to handle more custom options
authorMichael Paquier <michael@paquier.xyz>
Mon, 2 Nov 2020 01:41:30 +0000 (10:41 +0900)
committerMichael Paquier <michael@paquier.xyz>
Mon, 2 Nov 2020 01:41:30 +0000 (10:41 +0900)
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

src/backend/catalog/storage.c
src/backend/storage/buffer/bufmgr.c
src/backend/storage/page/bufpage.c
src/include/storage/bufpage.h

index 3cc886f7fe22e5c707073a258a7c49b81ee36369..f899b25c0e52737461927f6109e446205934ad2e 100644 (file)
@@ -338,7 +338,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
 
                smgrread(src, forkNum, blkno, buf.data);
 
-               if (!PageIsVerified(page, blkno))
+               if (!PageIsVerifiedExtended(page, blkno,
+                                                                       PIV_LOG_WARNING | PIV_REPORT_STAT))
                        ereport(ERROR,
                                        (errcode(ERRCODE_DATA_CORRUPTED),
                                         errmsg("invalid page in block %u of relation %s",
index 7332e6b59034ce3b1a06c4aba91f00e7237c788f..4ceb2ce25bda8d63286a9bb87c8a20120eaf8bca 100644 (file)
@@ -613,7 +613,8 @@ ReadBuffer(Relation reln, BlockNumber blockNum)
  *
  * In RBM_NORMAL mode, the page is read from disk, and the page header is
  * validated.  An error is thrown if the page header is not valid.  (But
- * note that an all-zero page is considered "valid"; see PageIsVerified().)
+ * note that an all-zero page is considered "valid"; see
+ * PageIsVerifiedExtended().)
  *
  * RBM_ZERO_ON_ERROR is like the normal mode, but if the page header is not
  * valid, the page is zeroed instead of throwing an error. This is intended
@@ -905,7 +906,8 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum,
                        }
 
                        /* check for garbage data */
-                       if (!PageIsVerified((Page) bufBlock, blockNum))
+                       if (!PageIsVerifiedExtended((Page) bufBlock, blockNum,
+                                                                               PIV_LOG_WARNING | PIV_REPORT_STAT))
                        {
                                if (mode == RBM_ZERO_ON_ERROR || zero_damaged_pages)
                                {
index 169430835c3fa44a228aef0d4b7bcda396a0ac60..7500b9d0b57da23a31a1dbab472fb858ad726154 100644 (file)
@@ -62,6 +62,18 @@ PageInit(Page page, Size pageSize, Size specialSize)
 
 /*
  * PageIsVerified
+ *             Utility wrapper for PageIsVerifiedExtended().
+ */
+bool
+PageIsVerified(Page page, BlockNumber blkno)
+{
+       return PageIsVerifiedExtended(page, blkno,
+                                                                 PIV_LOG_WARNING | PIV_REPORT_STAT);
+}
+
+
+/*
+ * PageIsVerifiedExtended
  *             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
@@ -77,9 +89,15 @@ PageInit(Page page, Size pageSize, Size specialSize)
  * allow zeroed pages here, and are careful that the page access macros
  * treat such a page as empty and without free space.  Eventually, VACUUM
  * will clean up such a page and make it usable.
+ *
+ * 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.
  */
 bool
-PageIsVerified(Page page, BlockNumber blkno)
+PageIsVerifiedExtended(Page page, BlockNumber blkno, int flags)
 {
        PageHeader      p = (PageHeader) page;
        size_t     *pagebytes;
@@ -147,12 +165,14 @@ PageIsVerified(Page page, BlockNumber blkno)
         */
        if (checksum_failure)
        {
-               ereport(WARNING,
-                               (errcode(ERRCODE_DATA_CORRUPTED),
-                                errmsg("page verification failed, calculated checksum %u but expected %u",
-                                               checksum, p->pd_checksum)));
+               if ((flags & PIV_LOG_WARNING) != 0)
+                       ereport(WARNING,
+                                       (errcode(ERRCODE_DATA_CORRUPTED),
+                                        errmsg("page verification failed, calculated checksum %u but expected %u",
+                                                       checksum, p->pd_checksum)));
 
-               pgstat_report_checksum_failure();
+               if ((flags & PIV_REPORT_STAT) != 0)
+                       pgstat_report_checksum_failure();
 
                if (header_sane && ignore_checksum_failure)
                        return true;
index 34b68ad0e0027a117b6647a663c2575c820b6042..56ca6b6ce161d288c633947f9504d1134b050684 100644 (file)
@@ -410,9 +410,15 @@ do { \
  *             extern declarations
  * ----------------------------------------------------------------
  */
+
+/* flags for PageAddItemExtended() */
 #define PAI_OVERWRITE                  (1 << 0)
 #define PAI_IS_HEAP                            (1 << 1)
 
+/* flags for PageIsVerifiedExtended() */
+#define PIV_LOG_WARNING                        (1 << 0)
+#define PIV_REPORT_STAT                        (1 << 1)
+
 #define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap) \
        PageAddItemExtended(page, item, size, offsetNumber, \
                                                ((overwrite) ? PAI_OVERWRITE : 0) | \
@@ -420,6 +426,7 @@ do { \
 
 extern void PageInit(Page page, Size pageSize, Size specialSize);
 extern bool PageIsVerified(Page page, BlockNumber blkno);
+extern bool PageIsVerifiedExtended(Page page, BlockNumber blkno, int flags);
 extern OffsetNumber PageAddItemExtended(Page page, Item item, Size size,
                                                                                OffsetNumber offsetNumber, int flags);
 extern Page PageGetTempPage(Page page);