Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaa1e8c2

Browse files
committed
Improve read_stream.c's fast path.
The "fast path" for well cached scans that don't do any I/O wasaccidentally coded in a way that could only be triggered by pg_prewarm'susage pattern, which starts out with a higher distance because of theflags it passes in. We want it to work for streaming sequential scanstoo, once that patch is committed. Adjust.Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>Discussion:https://postgr.es/m/CA%2BhUKGKXZALJ%3D6aArUsXRJzBm%3Dqvc4AWp7%3DiJNXJQqpbRLnD_w%40mail.gmail.com
1 parent9e73869 commitaa1e8c2

File tree

1 file changed

+31
-44
lines changed

1 file changed

+31
-44
lines changed

‎src/backend/storage/aio/read_stream.c

Lines changed: 31 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ get_per_buffer_data(ReadStream *stream, int16 buffer_index)
169169
/*
170170
* Ask the callback which block it would like us to read next, with a small
171171
* buffer in front to allow read_stream_unget_block() to work and to allow the
172-
* fast path to workin batches.
172+
* fast path toskip this function andworkdirectly from the array.
173173
*/
174174
staticinlineBlockNumber
175175
read_stream_get_block(ReadStream*stream,void*per_buffer_data)
@@ -578,13 +578,12 @@ read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
578578
if (likely(stream->fast_path))
579579
{
580580
BlockNumbernext_blocknum;
581-
boolneed_wait;
582581

583582
/* Fast path assumptions. */
584583
Assert(stream->ios_in_progress==0);
585584
Assert(stream->pinned_buffers==1);
586585
Assert(stream->distance==1);
587-
Assert(stream->pending_read_nblocks==1);
586+
Assert(stream->pending_read_nblocks==0);
588587
Assert(stream->per_buffer_data_size==0);
589588

590589
/* We're going to return the buffer we pinned last time. */
@@ -594,58 +593,45 @@ read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
594593
buffer=stream->buffers[oldest_buffer_index];
595594
Assert(buffer!=InvalidBuffer);
596595

597-
/*
598-
* Pin a buffer for the next call. Same buffer entry, and arbitrary
599-
* I/O entry (they're all free).
600-
*/
601-
need_wait=StartReadBuffer(&stream->ios[0].op,
602-
&stream->buffers[oldest_buffer_index],
603-
stream->pending_read_blocknum,
604-
stream->advice_enabled ?
605-
READ_BUFFERS_ISSUE_ADVICE :0);
606-
607-
/* Choose the block the next call will pin. */
596+
/* Choose the next block to pin. */
608597
if (unlikely(stream->blocknums_next==stream->blocknums_count))
609598
read_stream_fill_blocknums(stream);
610599
next_blocknum=stream->blocknums[stream->blocknums_next++];
611600

612-
/*
613-
* Fast return if the next call doesn't require I/O for the buffer we
614-
* just pinned, and we have a block number to give it as a pending
615-
* read.
616-
*/
617-
if (likely(!need_wait&&next_blocknum!=InvalidBlockNumber))
601+
if (likely(next_blocknum!=InvalidBlockNumber))
618602
{
619-
stream->pending_read_blocknum=next_blocknum;
620-
returnbuffer;
621-
}
622-
623-
/*
624-
* For anything more complex, set up some more state and take the slow
625-
* path next time.
626-
*/
627-
stream->fast_path= false;
603+
/*
604+
* Pin a buffer for the next call. Same buffer entry, and
605+
* arbitrary I/O entry (they're all free). We don't have to
606+
* adjust pinned_buffers because we're transferring one to caller
607+
* but pinning one more.
608+
*/
609+
if (likely(!StartReadBuffer(&stream->ios[0].op,
610+
&stream->buffers[oldest_buffer_index],
611+
next_blocknum,
612+
stream->advice_enabled ?
613+
READ_BUFFERS_ISSUE_ADVICE :0)))
614+
{
615+
/* Fast return. */
616+
returnbuffer;
617+
}
628618

629-
if (need_wait)
630-
{
631619
/* Next call must wait for I/O for the newly pinned buffer. */
632620
stream->oldest_io_index=0;
633621
stream->next_io_index=stream->max_ios>1 ?1 :0;
634622
stream->ios_in_progress=1;
635623
stream->ios[0].buffer_index=oldest_buffer_index;
636624
stream->seq_blocknum=next_blocknum+1;
637625
}
638-
if (next_blocknum==InvalidBlockNumber)
639-
{
640-
/* Next call hits end of stream and can't pin anything more. */
641-
stream->distance=0;
642-
stream->pending_read_nblocks=0;
643-
}
644626
else
645627
{
646-
/* Set up the pending read. */
647-
stream->pending_read_blocknum=next_blocknum;
628+
/* No more blocks, end of stream. */
629+
stream->distance=0;
630+
stream->oldest_buffer_index=stream->next_buffer_index;
631+
stream->pinned_buffers=0;
648632
}
633+
634+
stream->fast_path= false;
649635
returnbuffer;
650636
}
651637
#endif
@@ -762,15 +748,11 @@ read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
762748
if (stream->ios_in_progress==0&&
763749
stream->pinned_buffers==1&&
764750
stream->distance==1&&
765-
stream->pending_read_nblocks==1&&
751+
stream->pending_read_nblocks==0&&
766752
stream->per_buffer_data_size==0)
767753
{
768754
stream->fast_path= true;
769755
}
770-
else
771-
{
772-
stream->fast_path= false;
773-
}
774756
#endif
775757

776758
returnbuffer;
@@ -790,6 +772,11 @@ read_stream_reset(ReadStream *stream)
790772
/* Stop looking ahead. */
791773
stream->distance=0;
792774

775+
/* Forget buffered block numbers and fast path state. */
776+
stream->blocknums_next=0;
777+
stream->blocknums_count=0;
778+
stream->fast_path= false;
779+
793780
/* Unpin anything that wasn't consumed. */
794781
while ((buffer=read_stream_next_buffer(stream,NULL))!=InvalidBuffer)
795782
ReleaseBuffer(buffer);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp