mirror of
https://github.com/postgres/postgres.git
synced 2026-04-15 22:10:45 -04:00
heapam: Track heap block in IndexFetchHeapData.
Add an explicit BlockNumber field (xs_blk) to IndexFetchHeapData that tracks which heap block is currently pinned in xs_cbuf. heapam_index_fetch_tuple now uses xs_blk to determine when buffer switching is needed, replacing the previous approach that compared buffer identities via ReleaseAndReadBuffer on every non-HOT-chain call. This is preparatory work for an upcoming commit that will add index prefetching using a read stream. Delegating the release of a currently pinned buffer to ReleaseAndReadBuffer won't work anymore -- at least not when the next buffer that the scan needs to pin is one returned by read_stream_next_buffer (not a buffer returned by ReadBuffer). Author: Peter Geoghegan <pg@bowt.ie> Reviewed-By: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/CAH2-Wz=g=JTSyDB4UtB5su2ZcvsS7VbP+ZMvvaG6ABoCb+s8Lw@mail.gmail.com
This commit is contained in:
parent
a29fdd6c8d
commit
c7d09595e4
2 changed files with 22 additions and 14 deletions
|
|
@ -32,6 +32,7 @@ heapam_index_fetch_begin(Relation rel, uint32 flags)
|
|||
hscan->xs_base.rel = rel;
|
||||
hscan->xs_base.flags = flags;
|
||||
hscan->xs_cbuf = InvalidBuffer;
|
||||
hscan->xs_blk = InvalidBlockNumber;
|
||||
hscan->xs_vmbuffer = InvalidBuffer;
|
||||
|
||||
return &hscan->xs_base;
|
||||
|
|
@ -46,6 +47,7 @@ heapam_index_fetch_reset(IndexFetchTableData *scan)
|
|||
{
|
||||
ReleaseBuffer(hscan->xs_cbuf);
|
||||
hscan->xs_cbuf = InvalidBuffer;
|
||||
hscan->xs_blk = InvalidBlockNumber;
|
||||
}
|
||||
|
||||
if (BufferIsValid(hscan->xs_vmbuffer))
|
||||
|
|
@ -240,25 +242,30 @@ heapam_index_fetch_tuple(struct IndexFetchTableData *scan,
|
|||
|
||||
Assert(TTS_IS_BUFFERTUPLE(slot));
|
||||
|
||||
/* We can skip the buffer-switching logic if we're in mid-HOT chain. */
|
||||
if (!*heap_continue)
|
||||
/* We can skip the buffer-switching logic if we're on the same page. */
|
||||
if (hscan->xs_blk != ItemPointerGetBlockNumber(tid))
|
||||
{
|
||||
/* Switch to correct buffer if we don't have it already */
|
||||
Buffer prev_buf = hscan->xs_cbuf;
|
||||
Assert(!*heap_continue);
|
||||
|
||||
hscan->xs_cbuf = ReleaseAndReadBuffer(hscan->xs_cbuf,
|
||||
hscan->xs_base.rel,
|
||||
ItemPointerGetBlockNumber(tid));
|
||||
/* Remember this buffer's block number for next time */
|
||||
hscan->xs_blk = ItemPointerGetBlockNumber(tid);
|
||||
|
||||
if (BufferIsValid(hscan->xs_cbuf))
|
||||
ReleaseBuffer(hscan->xs_cbuf);
|
||||
|
||||
hscan->xs_cbuf = ReadBuffer(hscan->xs_base.rel, hscan->xs_blk);
|
||||
|
||||
/*
|
||||
* Prune page, but only if we weren't already on this page
|
||||
* Prune page when it is pinned for the first time
|
||||
*/
|
||||
if (prev_buf != hscan->xs_cbuf)
|
||||
heap_page_prune_opt(hscan->xs_base.rel, hscan->xs_cbuf,
|
||||
&hscan->xs_vmbuffer,
|
||||
hscan->xs_base.flags & SO_HINT_REL_READ_ONLY);
|
||||
heap_page_prune_opt(hscan->xs_base.rel, hscan->xs_cbuf,
|
||||
&hscan->xs_vmbuffer,
|
||||
hscan->xs_base.flags & SO_HINT_REL_READ_ONLY);
|
||||
}
|
||||
|
||||
Assert(BufferGetBlockNumber(hscan->xs_cbuf) == hscan->xs_blk);
|
||||
Assert(hscan->xs_blk == ItemPointerGetBlockNumber(tid));
|
||||
|
||||
/* Obtain share-lock on the buffer so we can examine visibility */
|
||||
LockBuffer(hscan->xs_cbuf, BUFFER_LOCK_SHARE);
|
||||
got_heap_tuple = heap_hot_search_buffer(tid,
|
||||
|
|
|
|||
|
|
@ -122,10 +122,11 @@ typedef struct IndexFetchHeapData
|
|||
IndexFetchTableData xs_base; /* AM independent part of the descriptor */
|
||||
|
||||
/*
|
||||
* Current heap buffer in scan, if any. NB: if xs_cbuf is not
|
||||
* InvalidBuffer, we hold a pin on that buffer.
|
||||
* Current heap buffer in scan (and its block number), if any. NB: if
|
||||
* xs_blk is not InvalidBlockNumber, we hold a pin in xs_cbuf.
|
||||
*/
|
||||
Buffer xs_cbuf;
|
||||
BlockNumber xs_blk;
|
||||
|
||||
/* Current heap block's corresponding page in the visibility map */
|
||||
Buffer xs_vmbuffer;
|
||||
|
|
|
|||
Loading…
Reference in a new issue