mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-30 05:41:29 +02:00
b5a9b18cd0
Introduce an abstraction allowing relation data to be accessed as a stream of buffers, with an implementation that is more efficient than the equivalent sequence of ReadBuffer() calls. Client code supplies a callback that can say which block number it wants next, and then consumes individual buffers one at a time from the stream. This division puts read_stream.c in control of how far ahead it can see and allows it to read clusters of neighboring blocks with StartReadBuffers(). It also issues POSIX_FADV_WILLNEED advice ahead of time when random access is detected. Other variants of I/O stream will be proposed in future work (for example to support recovery, whose LsnReadQueue device in xlogprefetcher.c is a distant cousin of this code and should eventually be replaced by this), but this basic API is sufficient for many common executor usage patterns involving predictable access to a single fork of a single relation. Several patches using this API are proposed separately. This stream concept is loosely based on ideas from Andres Freund on how we should pave the way for later work on asynchronous I/O. Author: Thomas Munro <thomas.munro@gmail.com> Author: Heikki Linnakangas <hlinnaka@iki.fi> (contributions) Author: Melanie Plageman <melanieplageman@gmail.com> (contributions) Suggested-by: Andres Freund <andres@anarazel.de> Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Reviewed-by: Melanie Plageman <melanieplageman@gmail.com> Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Tested-by: Tomas Vondra <tomas.vondra@enterprisedb.com> Discussion: https://postgr.es/m/CA+hUKGJkOiOCa+mag4BF+zHo7qo=o9CFheB8=g6uT5TUm2gkvA@mail.gmail.com
64 lines
2.2 KiB
C
64 lines
2.2 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* read_stream.h
|
|
* Mechanism for accessing buffered relation data with look-ahead
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/storage/read_stream.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef READ_STREAM_H
|
|
#define READ_STREAM_H
|
|
|
|
#include "storage/bufmgr.h"
|
|
|
|
/* Default tuning, reasonable for many users. */
|
|
#define READ_STREAM_DEFAULT 0x00
|
|
|
|
/*
|
|
* I/O streams that are performing maintenance work on behalf of potentially
|
|
* many users, and thus should be governed by maintenance_io_concurrency
|
|
* instead of effective_io_concurrency. For example, VACUUM or CREATE INDEX.
|
|
*/
|
|
#define READ_STREAM_MAINTENANCE 0x01
|
|
|
|
/*
|
|
* We usually avoid issuing prefetch advice automatically when sequential
|
|
* access is detected, but this flag explicitly disables it, for cases that
|
|
* might not be correctly detected. Explicit advice is known to perform worse
|
|
* than letting the kernel (at least Linux) detect sequential access.
|
|
*/
|
|
#define READ_STREAM_SEQUENTIAL 0x02
|
|
|
|
/*
|
|
* We usually ramp up from smaller reads to larger ones, to support users who
|
|
* don't know if it's worth reading lots of buffers yet. This flag disables
|
|
* that, declaring ahead of time that we'll be reading all available buffers.
|
|
*/
|
|
#define READ_STREAM_FULL 0x04
|
|
|
|
struct ReadStream;
|
|
typedef struct ReadStream ReadStream;
|
|
|
|
/* Callback that returns the next block number to read. */
|
|
typedef BlockNumber (*ReadStreamBlockNumberCB) (ReadStream *stream,
|
|
void *callback_private_data,
|
|
void *per_buffer_data);
|
|
|
|
extern ReadStream *read_stream_begin_relation(int flags,
|
|
BufferAccessStrategy strategy,
|
|
Relation rel,
|
|
ForkNumber forknum,
|
|
ReadStreamBlockNumberCB callback,
|
|
void *callback_private_data,
|
|
size_t per_buffer_data_size);
|
|
extern Buffer read_stream_next_buffer(ReadStream *stream, void **per_buffer_private);
|
|
extern void read_stream_reset(ReadStream *stream);
|
|
extern void read_stream_end(ReadStream *stream);
|
|
|
|
#endif /* READ_STREAM_H */
|