From 2319943ec40499898dfd92f95e11fe326c8fa8d9 Mon Sep 17 00:00:00 2001 From: Konstantin Knizhnik Date: Tue, 9 Dec 2025 13:22:47 +0200 Subject: [PATCH] OPtimize storing zero page image in WAL as FPI --- src/backend/access/transam/xloginsert.c | 32 +++++++++++++++---------- src/backend/access/transam/xlogreader.c | 4 +++- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c index a28607682c1..8db6221b11e 100644 --- a/src/backend/access/transam/xloginsert.c +++ b/src/backend/access/transam/xloginsert.c @@ -614,22 +614,30 @@ XLogRecordAssemble(RmgrId rmid, uint8 info, */ if (regbuf->flags & REGBUF_STANDARD) { - /* Assume we can omit data between pd_lower and pd_upper */ - uint16 lower = ((PageHeader) page)->pd_lower; - uint16 upper = ((PageHeader) page)->pd_upper; - - if (lower >= SizeOfPageHeaderData && - upper > lower && - upper <= BLCKSZ) + if (PageIsNew(page)) { - bimg.hole_offset = lower; - cbimg.hole_length = upper - lower; + bimg.hole_offset = 0; + cbimg.hole_length = BLCKSZ; } else { - /* No "hole" to remove */ - bimg.hole_offset = 0; - cbimg.hole_length = 0; + /* Assume we can omit data between pd_lower and pd_upper */ + uint16 lower = ((PageHeader) page)->pd_lower; + uint16 upper = ((PageHeader) page)->pd_upper; + + if (lower >= SizeOfPageHeaderData && + upper > lower && + upper <= BLCKSZ) + { + bimg.hole_offset = lower; + cbimg.hole_length = upper - lower; + } + else + { + /* No "hole" to remove */ + bimg.hole_offset = 0; + cbimg.hole_length = 0; + } } } else diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c index 02a22c92cfd..15e2d687dc6 100644 --- a/src/backend/access/transam/xlogreader.c +++ b/src/backend/access/transam/xlogreader.c @@ -1395,7 +1395,9 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg) if ((blk->bimg_info & BKPIMAGE_HAS_HOLE) && (blk->hole_offset == 0 || blk->hole_length == 0 || - blk->bimg_len == BLCKSZ)) + blk->bimg_len == BLCKSZ) && + !(blk->hole_offset == 0 && + blk->hole_length == BLCKSZ)) /* null page */ { report_invalid_record(state, "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X",