Provide multi-block smgrprefetch().

Previously smgrprefetch() could 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.  This usually produces a single system call,
but might need to loop if it crosses a segment boundary.  Initially it
is only called with nblocks == 1, but proposed patches will make wider
calls.

Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> (earlier version)
Discussion: https://postgr.es/m/CA+hUKGJkOiOCa+mag4BF+zHo7qo=o9CFheB8=g6uT5TUm2gkvA@mail.gmail.com
This commit is contained in:
Thomas Munro 2023-12-16 16:14:47 +13:00
parent 59bd34c2fa
commit b485ad7f07
6 changed files with 35 additions and 17 deletions

View File

@ -569,7 +569,7 @@ PrefetchSharedBuffer(SMgrRelation smgr_reln,
* recovery if the relation file doesn't exist. * recovery if the relation file doesn't exist.
*/ */
if ((io_direct_flags & IO_DIRECT_DATA) == 0 && if ((io_direct_flags & IO_DIRECT_DATA) == 0 &&
smgrprefetch(smgr_reln, forkNum, blockNum)) smgrprefetch(smgr_reln, forkNum, blockNum, 1))
{ {
result.initiated_io = true; result.initiated_io = true;
} }

View File

@ -94,7 +94,7 @@ PrefetchLocalBuffer(SMgrRelation smgr, ForkNumber forkNum,
#ifdef USE_PREFETCH #ifdef USE_PREFETCH
/* Not in buffers, so initiate prefetch */ /* Not in buffers, so initiate prefetch */
if ((io_direct_flags & IO_DIRECT_DATA) == 0 && if ((io_direct_flags & IO_DIRECT_DATA) == 0 &&
smgrprefetch(smgr, forkNum, blockNum)) smgrprefetch(smgr, forkNum, blockNum, 1))
{ {
result.initiated_io = true; result.initiated_io = true;
} }

View File

@ -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 bool
mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum) mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
int nblocks)
{ {
#ifdef USE_PREFETCH #ifdef USE_PREFETCH
off_t seekpos;
MdfdVec *v;
Assert((io_direct_flags & IO_DIRECT_DATA) == 0); Assert((io_direct_flags & IO_DIRECT_DATA) == 0);
v = _mdfd_getseg(reln, forknum, blocknum, false, if ((uint64) blocknum + nblocks > (uint64) MaxBlockNumber + 1)
InRecovery ? EXTENSION_RETURN_NULL : EXTENSION_FAIL);
if (v == NULL)
return false; 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 */ #endif /* USE_PREFETCH */
return true; return true;

View File

@ -54,7 +54,7 @@ typedef struct f_smgr
void (*smgr_zeroextend) (SMgrRelation reln, ForkNumber forknum, void (*smgr_zeroextend) (SMgrRelation reln, ForkNumber forknum,
BlockNumber blocknum, int nblocks, bool skipFsync); BlockNumber blocknum, int nblocks, bool skipFsync);
bool (*smgr_prefetch) (SMgrRelation reln, ForkNumber forknum, bool (*smgr_prefetch) (SMgrRelation reln, ForkNumber forknum,
BlockNumber blocknum); BlockNumber blocknum, int nblocks);
void (*smgr_read) (SMgrRelation reln, ForkNumber forknum, void (*smgr_read) (SMgrRelation reln, ForkNumber forknum,
BlockNumber blocknum, void *buffer); BlockNumber blocknum, void *buffer);
void (*smgr_write) (SMgrRelation reln, ForkNumber forknum, void (*smgr_write) (SMgrRelation reln, ForkNumber forknum,
@ -547,9 +547,10 @@ smgrzeroextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
* record). * record).
*/ */
bool 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);
} }
/* /*

View File

@ -31,7 +31,7 @@ extern void mdextend(SMgrRelation reln, ForkNumber forknum,
extern void mdzeroextend(SMgrRelation reln, ForkNumber forknum, extern void mdzeroextend(SMgrRelation reln, ForkNumber forknum,
BlockNumber blocknum, int nblocks, bool skipFsync); BlockNumber blocknum, int nblocks, bool skipFsync);
extern bool mdprefetch(SMgrRelation reln, ForkNumber forknum, extern bool mdprefetch(SMgrRelation reln, ForkNumber forknum,
BlockNumber blocknum); BlockNumber blocknum, int nblocks);
extern void mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, extern void mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
void *buffer); void *buffer);
extern void mdwrite(SMgrRelation reln, ForkNumber forknum, extern void mdwrite(SMgrRelation reln, ForkNumber forknum,

View File

@ -95,7 +95,7 @@ extern void smgrextend(SMgrRelation reln, ForkNumber forknum,
extern void smgrzeroextend(SMgrRelation reln, ForkNumber forknum, extern void smgrzeroextend(SMgrRelation reln, ForkNumber forknum,
BlockNumber blocknum, int nblocks, bool skipFsync); BlockNumber blocknum, int nblocks, bool skipFsync);
extern bool smgrprefetch(SMgrRelation reln, ForkNumber forknum, extern bool smgrprefetch(SMgrRelation reln, ForkNumber forknum,
BlockNumber blocknum); BlockNumber blocknum, int nblocks);
extern void smgrread(SMgrRelation reln, ForkNumber forknum, extern void smgrread(SMgrRelation reln, ForkNumber forknum,
BlockNumber blocknum, void *buffer); BlockNumber blocknum, void *buffer);
extern void smgrwrite(SMgrRelation reln, ForkNumber forknum, extern void smgrwrite(SMgrRelation reln, ForkNumber forknum,