Let caller of PageIsVerified() control ignore_checksum_failure
authorAndres Freund <[email protected]>
Sun, 30 Mar 2025 20:10:51 +0000 (16:10 -0400)
committerAndres Freund <[email protected]>
Sun, 30 Mar 2025 20:27:10 +0000 (16:27 -0400)
For AIO the completion of a read into shared buffers (i.e. verifying the page
including the checksum, updating the BufferDesc to reflect the IO) can happen
in a different backend than the backend that started the IO. As
ignore_checksum_failure can differ between backends, we need to allow the
caller of PageIsVerified() control whether to ignore checksum failures.

The commit leaves a gap in the PIV_* values, as an upcoming commit, which
depends on this commit, will add PIV_LOG_LOG, which better fits just after
PIV_LOG_WARNING.

Reviewed-by: Noah Misch <[email protected]>
Discussion: https://postgr.es/m/20250329212929[email protected]

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

index 2577f69cbde8e50852cdc94ccb2bb8036e641ffe..227df90f89c97fb20e263cbe9a1e28c28c1f480b 100644 (file)
@@ -508,6 +508,7 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
    for (blkno = 0; blkno < nblocks; blkno++)
    {
        BulkWriteBuffer buf;
+       int         piv_flags;
        bool        checksum_failure;
        bool        verified;
 
@@ -517,9 +518,11 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
        buf = smgr_bulk_get_buf(bulkstate);
        smgrread(src, forkNum, blkno, (Page) buf);
 
-       verified = PageIsVerified((Page) buf, blkno, PIV_LOG_WARNING,
+       piv_flags = PIV_LOG_WARNING;
+       if (ignore_checksum_failure)
+           piv_flags |= PIV_IGNORE_CHECKSUM_FAILURE;
+       verified = PageIsVerified((Page) buf, blkno, piv_flags,
                                  &checksum_failure);
-
        if (checksum_failure)
        {
            RelFileLocatorBackend rloc = src->smgr_rlocator;
index 16b5b69efdaaf5b1300ad40cf18e8b7d7d42f6f6..3b66c5c6b4c85386ba02434340fff4447fcae819 100644 (file)
@@ -1569,6 +1569,7 @@ WaitReadBuffers(ReadBuffersOperation *operation)
        {
            BufferDesc *bufHdr;
            Block       bufBlock;
+           int         piv_flags;
            bool        verified;
            bool        checksum_failure;
 
@@ -1584,8 +1585,11 @@ WaitReadBuffers(ReadBuffersOperation *operation)
            }
 
            /* check for garbage data */
+           piv_flags = PIV_LOG_WARNING;
+           if (ignore_checksum_failure)
+               piv_flags |= PIV_IGNORE_CHECKSUM_FAILURE;
            verified = PageIsVerified((Page) bufBlock, io_first_block + j,
-                                     PIV_LOG_WARNING, &checksum_failure);
+                                     piv_flags, &checksum_failure);
            if (checksum_failure)
            {
                RelFileLocatorBackend rloc = operation->smgr->smgr_rlocator;
index 5d1b039fcbb52d6728f5e91a8362fcf65ca49067..0afeab5140c5d948a1b8b05ee480a69cf608ac9e 100644 (file)
@@ -81,10 +81,14 @@ 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_IGNORE_CHECKSUM_FAILURE is set, checksum failures will cause a
+ * message about the failure to be emitted, but will not cause
+ * PageIsVerified() to return false.
+ *
  * 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.
+ * IGNORE_CHECKSUM_FAILURE.
  */
 bool
 PageIsVerified(PageData *page, BlockNumber blkno, int flags, bool *checksum_failure_p)
@@ -150,7 +154,7 @@ PageIsVerified(PageData *page, BlockNumber blkno, int flags, bool *checksum_fail
                     errmsg("page verification failed, calculated checksum %u but expected %u",
                            checksum, p->pd_checksum)));
 
-       if (header_sane && ignore_checksum_failure)
+       if (header_sane && (flags & PIV_IGNORE_CHECKSUM_FAILURE))
            return true;
    }
 
index b943db707db66c6174a67328266fc309bf6e4084..26d0a551fc990e1ceb929da57a36f0104b11c176 100644 (file)
@@ -467,6 +467,7 @@ do { \
 
 /* flags for PageIsVerified() */
 #define PIV_LOG_WARNING            (1 << 0)
+#define PIV_IGNORE_CHECKSUM_FAILURE (1 << 2)
 
 #define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap) \
    PageAddItemExtended(page, item, size, offsetNumber, \