diff options
author | Thomas Munro <tmunro@postgresql.org> | 2023-12-16 16:14:47 +1300 |
---|---|---|
committer | Thomas Munro <tmunro@postgresql.org> | 2023-12-16 17:51:21 +1300 |
commit | b485ad7f07c80efbfd47329f138f0fe3a5acf013 (patch) | |
tree | 033c507f439b762b4f6ee6db9d034733706fd4c3 /src/backend/storage/smgr/md.c | |
parent | 59bd34c2fa02b005dc33190245b2bffc6a08c0b9 (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.c | 37 |
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; |