On Mon, May 20, 2024 at 10:46 PM Melanie Plageman <melanieplage...@gmail.com>
wrote:

> On Wed, May 15, 2024 at 2:18 PM Nazir Bilal Yavuz <byavu...@gmail.com>
> wrote:
> >
> > On Mon, 29 Apr 2024 at 18:41, Nazir Bilal Yavuz <byavu...@gmail.com>
> wrote:
> > >
> > > On Mon, 8 Apr 2024 at 04:21, Thomas Munro <thomas.mu...@gmail.com>
> wrote:
> > > I wanted to discuss what will happen to this patch now that
> > > 27bc1772fc8 is reverted. I am continuing this thread but I can create
> > > another thread if you prefer so.
> >
> > 041b96802ef is discussed in the 'Table AM Interface Enhancements'
> > thread [1]. The main problems discussed about this commit is that the
> > read stream API is not pushed to the heap-specific code and, because
> > of that, the other AM implementations need to use read streams. To
> > push read stream API to the heap-specific code, it is pretty much
> > required to pass BufferAccessStrategy and BlockSamplerData to the
> > initscan().
> >
> > I am sharing the alternative version of this patch. The first patch
> > just reverts 041b96802ef and the second patch is the alternative
> > version.
> >
> > In this alternative version, the read stream API is not pushed to the
> > heap-specific code, but it is controlled by the heap-specific code.
> > The SO_USE_READ_STREAMS_IN_ANALYZE flag is introduced and set in the
> > heap-specific code if the scan type is 'ANALYZE'. This flag is used to
> > decide whether streaming API in ANALYZE will be used or not. If this
> > flag is set, this means heap AMs and read stream API will be used. If
> > it is not set, this means heap AMs will not be used and code falls
> > back to the version before read streams.
>
> Personally, I think the alternative version here is the best option
> other than leaving what is in master. However, I would vote for
> keeping what is in master because 1) where we are in the release
> timeline and 2) the acquire_sample_rows() code, before streaming read,
> was totally block-based anyway.
>
> If we kept what was in master, do we need to document for table AMs
> how to use read_stream_next_buffer() or can we assume they will look
> at the heap AM implementation?
>

Hi all,

I ran into this with the PG17 beta3 and for our use-case we need to set up
another stream (using a different relation and/or fork, but using the same
strategy) in addition to the one that is passed in to the
scan_analyze_next_block(), so to be able to do that it is necessary to have
the block sampler and the strategy from the original stream. Given that
this makes it very difficult (see below) to set up a different ReadStream
inside the TAM unless you have the BlockSampler and the BufferReadStrategy,
and the old interface did not have this problem, I would consider this a
regression.

This would be possible to solve in a few different ways:

   1. The alternate version proposed by Nazir allows you to decide which
   interface to use.
   2. Reverting the patch entirely would also solve the problem.
   3. Passing down the block sampler and the strategy to scan_begin() and
   move the ReadStream setup in analyze.c into initscan() in heapam.c, but
   this requires adding new parameters to this function.
   4. Having accessors that allow you to get the block sampler and strategy
   from the ReadStream object.

The proposed solution 1 above would still not solve the problem of allowing
a user to set up a different or extra ReadStream if they want to use the
new ReadStream interface. Reverting the ReadStream patch entirely would
also deal with the regression, but I find the ReadStream interface very
elegant since it moves the block sampling into a separate abstraction and
would like to use it, but right now there are some limitations if you want
to use it fully. The third solution above would allow that, but it requires
a change in the signature of scan_begin(), which might not be the best at
this stage of development. Proposal 4 would allow you to construct a new
stream based on the old one and might be a simple alternative solution as
well with less changes to the current code.

It is possible to capture the information in ProcessUtility() and
re-compute all the parameters, but that is quite a lot of work to get
right, especially considering that these computations are all over the
place and part of different functions at different stages (For example,
variable ring_size, needed to set up the buffer access strategy is computed
in ExecVacuum(); variable targrows, used to set up the buffer sampler, is
computed inside acquire_sample_rows(), which in turn requires to decide
what attributes to analyze, which is computed in do_analyze_rel().)

It would be great if this could be fixed before the PG17 release now that
27bc1772fc8 was reverted.
--
Best wishes,
Mats Kindahl, Timescale
From f684ba1a941912bfe57c256a080cb8f6e49e8871 Mon Sep 17 00:00:00 2001
From: Mats Kindahl <m...@timescale.com>
Date: Thu, 22 Aug 2024 09:25:30 +0200
Subject: Add accessors for ReadStream

Add accessors to be able to retrieve the buffer access strategy as well
as the callback with its private data.
---
 src/backend/storage/aio/read_stream.c | 19 +++++++++++++++++++
 src/include/storage/read_stream.h     |  4 ++++
 2 files changed, 23 insertions(+)

diff --git a/src/backend/storage/aio/read_stream.c b/src/backend/storage/aio/read_stream.c
index 684b6d6fc0..02c9ad229f 100644
--- a/src/backend/storage/aio/read_stream.c
+++ b/src/backend/storage/aio/read_stream.c
@@ -852,3 +852,22 @@ read_stream_end(ReadStream *stream)
 	read_stream_reset(stream);
 	pfree(stream);
 }
+
+BufferAccessStrategy
+read_stream_get_access_strategy(ReadStream *stream)
+{
+	/*
+	 * All the streams have the same strategy and there is at least one, so we
+	 * can safely get the first one.
+	 */
+	return stream->ios[0].op.strategy;
+}
+
+void
+read_stream_get_callback(ReadStream *stream,
+						 ReadStreamBlockNumberCB *callback,
+						 void **callback_private_data)
+{
+	*callback = stream->callback;
+	*callback_private_data = stream->callback_private_data;
+}
diff --git a/src/include/storage/read_stream.h b/src/include/storage/read_stream.h
index 4e599904f2..0da73719e5 100644
--- a/src/include/storage/read_stream.h
+++ b/src/include/storage/read_stream.h
@@ -69,5 +69,9 @@ extern ReadStream *read_stream_begin_smgr_relation(int flags,
 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);
+extern BufferAccessStrategy read_stream_get_access_strategy(ReadStream *stream);
+extern void read_stream_get_callback(ReadStream *stream,
+									 ReadStreamBlockNumberCB *callback,
+									 void **callback_private_data);
 
 #endif							/* READ_STREAM_H */
-- 
2.34.1

Reply via email to