From 7ec86c54dc032c1e66da53e8d5fda8b53255cc2d Mon Sep 17 00:00:00 2001 From: Peipei Yin Date: Wed, 12 Aug 2026 09:52:31 -0700 Subject: [PATCH] Use smgrzeroextend() for zero-filled relation extension Replace memset()+smgrextend() patterns that extended relations with all-zero pages. smgrzeroextend() can extend multiple blocks in one call and uses mdzeroextend() underneath, which may use posix_fallocate() or FileZero() instead of relying on sparse-file hole semantics. Update RelationCopyStorageUsingBuffer() to zero-extend the destination fork before copying, smgr_bulk_flush() to fill non-sequential write gaps in one call, and segment padding in _mdfd_getseg() to use mdzeroextend() when opening a new segment leaves the previous one short of RELSEG_SIZE. --- src/backend/storage/buffer/bufmgr.c | 6 ++---- src/backend/storage/smgr/bulk_write.c | 16 +++++++--------- src/backend/storage/smgr/md.c | 11 ++++------- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 169829eb020..729b65fcac5 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -5379,7 +5379,6 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator, bool use_wal; BlockNumber nblocks; BlockNumber blkno; - PGIOAlignedBlock buf; BufferAccessStrategy bstrategy_src; BufferAccessStrategy bstrategy_dst; BlockRangeReadStreamPrivate p; @@ -5405,9 +5404,8 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator, * Bulk extend the destination relation of the same size as the source * relation before starting to copy block by block. */ - memset(buf.data, 0, BLCKSZ); - smgrextend(smgropen(dstlocator, INVALID_PROC_NUMBER), forkNum, nblocks - 1, - buf.data, true); + smgrzeroextend(smgropen(dstlocator, INVALID_PROC_NUMBER), forkNum, 0, + nblocks, true); /* This is a bulk operation, so use buffer access strategies. */ bstrategy_src = GetAccessStrategy(BAS_BULKREAD); diff --git a/src/backend/storage/smgr/bulk_write.c b/src/backend/storage/smgr/bulk_write.c index f3c24082a69..a7f27fb41d3 100644 --- a/src/backend/storage/smgr/bulk_write.c +++ b/src/backend/storage/smgr/bulk_write.c @@ -46,8 +46,6 @@ #define MAX_PENDING_WRITES XLR_MAX_BLOCK_ID -static const PGIOAlignedBlock zero_buffer = {0}; /* worth BLCKSZ */ - typedef struct PendingWrite { BulkWriteBuffer buf; @@ -290,14 +288,14 @@ smgr_bulk_flush(BulkWriteState *bulkstate) * space will read as zeroes anyway), but it should help to avoid * fragmentation. The dummy pages aren't WAL-logged though. */ - while (blkno > bulkstate->relsize) + if (blkno > bulkstate->relsize) { - /* don't set checksum for all-zero page */ - smgrextend(bulkstate->smgr, bulkstate->forknum, - bulkstate->relsize, - &zero_buffer, - true); - bulkstate->relsize++; + /* don't set checksum for all-zero pages */ + smgrzeroextend(bulkstate->smgr, bulkstate->forknum, + bulkstate->relsize, + blkno - bulkstate->relsize, + true); + bulkstate->relsize = blkno; } smgrextend(bulkstate->smgr, bulkstate->forknum, blkno, page, true); diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 9f96d9cbbfc..216c5a6846e 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -1825,13 +1825,10 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno, */ if (nblocks < ((BlockNumber) RELSEG_SIZE)) { - char *zerobuf = palloc_aligned(BLCKSZ, PG_IO_ALIGN_SIZE, - MCXT_ALLOC_ZERO); - - mdextend(reln, forknum, - nextsegno * ((BlockNumber) RELSEG_SIZE) - 1, - zerobuf, skipFsync); - pfree(zerobuf); + mdzeroextend(reln, forknum, + (nextsegno - 1) * ((BlockNumber) RELSEG_SIZE) + nblocks, + RELSEG_SIZE - nblocks, + skipFsync); } flags = O_CREAT; } -- 2.50.1 (Apple Git-155)