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 fdecbad170..091993ea45 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -710,27 +710,44 @@ 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) + if ((uint64) blocknum + nblocks > (uint64) MaxBlockNumber + 1) return false; - seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE)); + while (nblocks > 0) + { + off_t seekpos; + MdfdVec *v; + int nblocks_this_segment; - Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE); + v = _mdfd_getseg(reln, forknum, blocknum, false, + InRecovery ? EXTENSION_RETURN_NULL : EXTENSION_FAIL); + if (v == NULL) + return false; - (void) FilePrefetch(v->mdfd_vfd, seekpos, BLCKSZ, WAIT_EVENT_DATA_FILE_PREFETCH); + seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE)); + + 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 4c55264933..003a55a592 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_read) (SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, void *buffer); void (*smgr_write) (SMgrRelation reln, ForkNumber forknum, @@ -547,9 +547,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 941879ee6a..091784c171 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 mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, void *buffer); extern void mdwrite(SMgrRelation reln, ForkNumber forknum, diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index a9a179aaba..da7e7c5a2e 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 smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, void *buffer); extern void smgrwrite(SMgrRelation reln, ForkNumber forknum,