From 5dc0418fab281d017a61a5756240467af982bdfd Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Thu, 7 Apr 2022 19:28:40 +1200 Subject: Prefetch data referenced by the WAL, take II. Introduce a new GUC recovery_prefetch. When enabled, look ahead in the WAL and try to initiate asynchronous reading of referenced data blocks that are not yet cached in our buffer pool. For now, this is done with posix_fadvise(), which has several caveats. Since not all OSes have that system call, "try" is provided so that it can be enabled where available. Better mechanisms for asynchronous I/O are possible in later work. Set to "try" for now for test coverage. Default setting to be finalized before release. The GUC wal_decode_buffer_size limits the distance we can look ahead in bytes of decoded data. The existing GUC maintenance_io_concurrency is used to limit the number of concurrent I/Os allowed, based on pessimistic heuristics used to infer that I/Os have begun and completed. We'll also not look more than maintenance_io_concurrency * 4 block references ahead. Reviewed-by: Julien Rouhaud Reviewed-by: Tomas Vondra Reviewed-by: Alvaro Herrera (earlier version) Reviewed-by: Andres Freund (earlier version) Reviewed-by: Justin Pryzby (earlier version) Tested-by: Tomas Vondra (earlier version) Tested-by: Jakub Wartak (earlier version) Tested-by: Dmitry Dolgov <9erthalion6@gmail.com> (earlier version) Tested-by: Sait Talha Nisanci (earlier version) Discussion: https://postgr.es/m/CA%2BhUKGJ4VJN8ttxScUFM8dOKX0BrBiboo5uz1cq%3DAovOddfHpA%40mail.gmail.com --- src/backend/access/transam/xlogreader.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'src/backend/access/transam/xlogreader.c') diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c index e612aa933a..5862d9dc75 100644 --- a/src/backend/access/transam/xlogreader.c +++ b/src/backend/access/transam/xlogreader.c @@ -1727,6 +1727,8 @@ DecodeXLogRecord(XLogReaderState *state, blk->has_image = ((fork_flags & BKPBLOCK_HAS_IMAGE) != 0); blk->has_data = ((fork_flags & BKPBLOCK_HAS_DATA) != 0); + blk->prefetch_buffer = InvalidBuffer; + COPY_HEADER_FIELD(&blk->data_len, sizeof(uint16)); /* cross-check that the HAS_DATA flag is set iff data_length > 0 */ if (blk->has_data && blk->data_len == 0) @@ -1925,14 +1927,29 @@ err: /* * Returns information about the block that a block reference refers to. - * - * If the WAL record contains a block reference with the given ID, *rnode, - * *forknum, and *blknum are filled in (if not NULL), and returns true. - * Otherwise returns false. + * See XLogRecGetBlockTagExtended(). */ bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum) +{ + return XLogRecGetBlockTagExtended(record, block_id, rnode, forknum, blknum, + NULL); +} + +/* + * Returns information about the block that a block reference refers to, + * optionally including the buffer that the block may already be in. + * + * If the WAL record contains a block reference with the given ID, *rnode, + * *forknum, *blknum and *prefetch_buffer are filled in (if not NULL), and + * returns true. Otherwise returns false. + */ +bool +XLogRecGetBlockTagExtended(XLogReaderState *record, uint8 block_id, + RelFileNode *rnode, ForkNumber *forknum, + BlockNumber *blknum, + Buffer *prefetch_buffer) { DecodedBkpBlock *bkpb; @@ -1947,6 +1964,8 @@ XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, *forknum = bkpb->forknum; if (blknum) *blknum = bkpb->blkno; + if (prefetch_buffer) + *prefetch_buffer = bkpb->prefetch_buffer; return true; } -- cgit v1.2.1