From 84221895fdcaa13b51f7839def1347924cab4246 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Sun, 23 Jul 2023 08:53:15 +1200 Subject: [PATCH v4 4/8] Provide multi-block smgrprefetch(). Previously smgrprefetch() would issue POSIX_FADV_WILLNEED advice for a single block at a time. Add an nblocks argument so that we can do the same for a range of blocks. Reviewed-by: Heikki Linnakangas Author: Thomas Munro Discussion: https://postgr.es/m/CA+hUKGJkOiOCa+mag4BF+zHo7qo=o9CFheB8=g6uT5TUm2gkvA@mail.gmail.com --- src/backend/storage/buffer/bufmgr.c | 2 +- src/backend/storage/buffer/localbuf.c | 2 +- src/backend/storage/smgr/md.c | 36 +++++++++++++++++++-------- src/backend/storage/smgr/smgr.c | 7 +++--- src/include/storage/md.h | 2 +- src/include/storage/smgr.h | 2 +- 6 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index f7c67d504c..de8b5edbfb 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -569,7 +569,7 @@ PrefetchSharedBuffer(SMgrRelation smgr_reln, * recovery if the relation file doesn't exist. */ if ((io_direct_flags & IO_DIRECT_DATA) == 0 && - smgrprefetch(smgr_reln, forkNum, blockNum)) + smgrprefetch(smgr_reln, forkNum, blockNum, 1)) { result.initiated_io = true; } diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c index aebcf146b4..c75ed184e0 100644 --- a/src/backend/storage/buffer/localbuf.c +++ b/src/backend/storage/buffer/localbuf.c @@ -94,7 +94,7 @@ PrefetchLocalBuffer(SMgrRelation smgr, ForkNumber forkNum, #ifdef USE_PREFETCH /* Not in buffers, so initiate prefetch */ if ((io_direct_flags & IO_DIRECT_DATA) == 0 && - smgrprefetch(smgr, forkNum, blockNum)) + smgrprefetch(smgr, forkNum, blockNum, 1)) { result.initiated_io = true; } diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 8e58637792..48e86b38c6 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -711,27 +711,41 @@ mdclose(SMgrRelation reln, ForkNumber forknum) } /* - * mdprefetch() -- Initiate asynchronous read of the specified block of a relation + * mdprefetch() -- Initiate asynchronous read of the specified blocks of a relation */ bool -mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum) +mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, + int nblocks) { #ifdef USE_PREFETCH - off_t seekpos; - MdfdVec *v; Assert((io_direct_flags & IO_DIRECT_DATA) == 0); - v = _mdfd_getseg(reln, forknum, blocknum, false, - InRecovery ? EXTENSION_RETURN_NULL : EXTENSION_FAIL); - if (v == NULL) - return false; + while (nblocks > 0) + { + off_t seekpos; + MdfdVec *v; + int nblocks_this_segment; - seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE)); + v = _mdfd_getseg(reln, forknum, blocknum, false, + InRecovery ? EXTENSION_RETURN_NULL : EXTENSION_FAIL); + if (v == NULL) + return false; - Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE); + seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE)); - (void) FilePrefetch(v->mdfd_vfd, seekpos, BLCKSZ, WAIT_EVENT_DATA_FILE_PREFETCH); + Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE); + + nblocks_this_segment = + Min(nblocks, + RELSEG_SIZE - (blocknum % ((BlockNumber) RELSEG_SIZE))); + + (void) FilePrefetch(v->mdfd_vfd, seekpos, BLCKSZ * nblocks_this_segment, + WAIT_EVENT_DATA_FILE_PREFETCH); + + blocknum += nblocks_this_segment; + nblocks -= nblocks_this_segment; + } #endif /* USE_PREFETCH */ return true; diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index 15633838c9..7ce31fd30a 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -54,7 +54,7 @@ typedef struct f_smgr void (*smgr_zeroextend) (SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks, bool skipFsync); bool (*smgr_prefetch) (SMgrRelation reln, ForkNumber forknum, - BlockNumber blocknum); + BlockNumber blocknum, int nblocks); void (*smgr_readv) (SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, void **buffers, BlockNumber nblocks); @@ -550,9 +550,10 @@ smgrzeroextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, * record). */ bool -smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum) +smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, + int nblocks) { - return smgrsw[reln->smgr_which].smgr_prefetch(reln, forknum, blocknum); + return smgrsw[reln->smgr_which].smgr_prefetch(reln, forknum, blocknum, nblocks); } /* diff --git a/src/include/storage/md.h b/src/include/storage/md.h index 0f73d9af49..3dc651ec17 100644 --- a/src/include/storage/md.h +++ b/src/include/storage/md.h @@ -31,7 +31,7 @@ extern void mdextend(SMgrRelation reln, ForkNumber forknum, extern void mdzeroextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks, bool skipFsync); extern bool mdprefetch(SMgrRelation reln, ForkNumber forknum, - BlockNumber blocknum); + BlockNumber blocknum, int nblocks); extern void mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, void **buffers, BlockNumber nblocks); extern void mdwritev(SMgrRelation reln, ForkNumber forknum, diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index ae93910132..6e62dc053c 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.h @@ -95,7 +95,7 @@ extern void smgrextend(SMgrRelation reln, ForkNumber forknum, extern void smgrzeroextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks, bool skipFsync); extern bool smgrprefetch(SMgrRelation reln, ForkNumber forknum, - BlockNumber blocknum); + BlockNumber blocknum, int nblocks); extern void smgrreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, void **buffer, BlockNumber nblocks); -- 2.39.3 (Apple Git-145)