mirror of
https://github.com/postgres/postgres.git
synced 2026-03-02 13:24:01 -05:00
Commits041b9680and6377e12achanged the interface of scan_analyze_next_block() to take a ReadStream instead of a BlockNumber and a BufferAccessStrategy, and to return a value to indicate when the stream has run out of blocks. This caused integration problems for at least one known extension that uses specially encoded BlockNumber values that map to different underlying storage, because acquire_sample_rows() sets up the stream so that read_stream_next_buffer() reads blocks from the main fork of the relation's SMgrRelation. Provide read_stream_next_block(), as a way for such an extension to access the stream of raw BlockNumbers directly and forward them to its own ReadBuffer() calls after decoding, as it could in earlier releases. The new function returns the BlockNumber and BufferAccessStrategy that were previously passed directly to scan_analyze_next_block(). Alternatively, an extension could wrap the stream of BlockNumbers in another ReadStream with a callback that performs any decoding required to arrive at real storage manager BlockNumber values, so that it could benefit from the I/O combining and concurrency provided by read_stream.c. Another class of table access method that does nothing in scan_analyze_next_block() because it is not block-oriented could use this function to control the number of block sampling loops. It could match the previous behavior with "return read_stream_next_block(stream, &bas) != InvalidBlockNumber". Ongoing work is expected to provide better ANALYZE support for table access methods that don't behave like heapam with respect to storage blocks, but that will be for future releases. Back-patch to 17. Reported-by: Mats Kindahl <mats@timescale.com> Reviewed-by: Mats Kindahl <mats@timescale.com> Discussion: https://postgr.es/m/CA%2B14425%2BCcm07ocG97Fp%2BFrD9xUXqmBKFvecp0p%2BgV2YYR258Q%40mail.gmail.com
65 lines
2.3 KiB
C
65 lines
2.3 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_data);
|
|
extern BlockNumber read_stream_next_block(ReadStream *stream,
|
|
BufferAccessStrategy *strategy);
|
|
extern void read_stream_reset(ReadStream *stream);
|
|
extern void read_stream_end(ReadStream *stream);
|
|
|
|
#endif /* READ_STREAM_H */
|