summaryrefslogtreecommitdiff
path: root/src/backend/storage/smgr/md.c
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2023-12-16 16:14:47 +1300
committerThomas Munro <tmunro@postgresql.org>2023-12-16 17:51:21 +1300
commitb485ad7f07c80efbfd47329f138f0fe3a5acf013 (patch)
tree033c507f439b762b4f6ee6db9d034733706fd4c3 /src/backend/storage/smgr/md.c
parent59bd34c2fa02b005dc33190245b2bffc6a08c0b9 (diff)
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
Diffstat (limited to 'src/backend/storage/smgr/md.c')
-rw-r--r--src/backend/storage/smgr/md.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index fdecbad1709..091993ea45b 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;
+
+ 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;