Skip to content

Commit dd66f67

Browse files
knizhniktristan957
authored andcommitted
Heap bitmap scan prefetch fix2 v14 (#275)
* Copy iterator result in BitmapHeapNext * Restore initial -1 value for prefetch_target * Add tbmres_copy to BitmapHeapScanState
1 parent 65391d7 commit dd66f67

File tree

2 files changed

+27
-26
lines changed

2 files changed

+27
-26
lines changed

src/backend/executor/nodeBitmapHeapscan.c

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -149,19 +149,15 @@ BitmapHeapNext(BitmapHeapScanState *node)
149149
* multiple processes to iterate jointly.
150150
*/
151151
pstate->tbmiterator = tbm_prepare_shared_iterate(tbm);
152-
#ifdef USE_PREFETCH
153-
node->n_prefetch_requests = 0;
154-
node->prefetch_request_pos = 0;
155-
if (node->prefetch_maximum > 0)
156-
{
157-
node->prefetch_pages = 0;
158-
node->prefetch_target = -1;
159-
}
160-
#endif
161152

162153
/* We have initialized the shared state so wake up others. */
163154
BitmapDoneInitializingSharedState(pstate);
164155
}
156+
#ifdef USE_PREFETCH
157+
node->prefetch_head = 0;
158+
node->prefetch_pages = 0;
159+
node->prefetch_target = -1;
160+
#endif
165161

166162
/* Allocate a private iterator and attach the shared state to it */
167163
node->shared_tbmiterator = shared_tbmiterator =
@@ -184,20 +180,25 @@ BitmapHeapNext(BitmapHeapScanState *node)
184180
if (tbmres == NULL)
185181
{
186182
if (!pstate)
187-
node->tbmres = tbmres = tbm_iterate(tbmiterator);
183+
tbmres = tbm_iterate(tbmiterator);
188184
else
189185
{
190-
if (node->n_prefetch_requests != 0)
186+
if (node->prefetch_pages != 0)
191187
{
192-
node->tbmres = tbmres = (TBMIterateResult *)&node->prefetch_requests[node->prefetch_request_pos];
193-
node->n_prefetch_requests -= 1;
194-
node->prefetch_request_pos = (node->prefetch_request_pos + 1) % MAX_IO_CONCURRENCY;
195-
if (node->prefetch_pages != 0)
196-
node->prefetch_pages -= 1;
188+
tbmres = (TBMIterateResult *)&node->prefetch_requests[node->prefetch_head];
189+
node->prefetch_pages -= 1;
190+
node->prefetch_head = (node->prefetch_head + 1) % MAX_IO_CONCURRENCY;
197191
}
198192
else
199-
node->tbmres = tbmres = tbm_shared_iterate(shared_tbmiterator);
193+
tbmres = tbm_shared_iterate(shared_tbmiterator);
194+
if (tbmres)
195+
{
196+
/* Need to copy result because iterator can be used for prefetch and vocant position in prefetch ring buffer can also be reused */
197+
memcpy(&node->tbmres_copy, tbmres, offsetof(TBMIterateResult, offsets) + sizeof(OffsetNumber)*Max(tbmres->ntuples, 0));
198+
tbmres = (TBMIterateResult *)&node->tbmres_copy;
199+
}
200200
}
201+
node->tbmres = tbmres;
201202
if (tbmres == NULL)
202203
{
203204
/* no more entries in the bitmap */
@@ -455,8 +456,7 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
455456

456457
if (node->prefetch_pages < node->prefetch_target)
457458
{
458-
Assert(node->n_prefetch_requests < MAX_IO_CONCURRENCY);
459-
node->prefetch_pages++;
459+
Assert(node->prefetch_pages < MAX_IO_CONCURRENCY);
460460
do_prefetch = true;
461461
}
462462

@@ -466,8 +466,10 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
466466
tbmpre = tbm_shared_iterate(node->shared_tbmiterator);
467467
if (tbmpre != NULL)
468468
{
469-
memcpy(&node->prefetch_requests[(node->prefetch_request_pos + node->n_prefetch_requests) % MAX_IO_CONCURRENCY], tbmpre, sizeof(TBMIteratePrefetchResult));
470-
node->n_prefetch_requests += 1;
469+
memcpy(&node->prefetch_requests[(node->prefetch_head + node->prefetch_pages) % MAX_IO_CONCURRENCY],
470+
tbmpre,
471+
offsetof(TBMIterateResult, offsets) + sizeof(OffsetNumber)*Max(tbmpre->ntuples, 0));
472+
node->prefetch_pages += 1;
471473
}
472474
else
473475
{
@@ -477,7 +479,7 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
477479

478480
/* As above, skip prefetch if we expect not to need page */
479481
skip_fetch = (node->can_skip_fetch &&
480-
(node->tbmres ? !node->tbmres->recheck : false) &&
482+
!tbmpre->recheck &&
481483
VM_ALL_VISIBLE(node->ss.ss_currentRelation,
482484
tbmpre->blockno,
483485
&node->pvmbuffer));
@@ -715,8 +717,7 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
715717
* Maximum number of prefetches for the tablespace if configured,
716718
* otherwise the current value of the effective_io_concurrency GUC.
717719
*/
718-
scanstate->prefetch_maximum =
719-
get_tablespace_io_concurrency(currentRelation->rd_rel->reltablespace);
720+
scanstate->prefetch_maximum = get_tablespace_io_concurrency(currentRelation->rd_rel->reltablespace);
720721

721722
scanstate->ss.ss_currentRelation = currentRelation;
722723

src/include/nodes/execnodes.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,8 +1703,8 @@ typedef struct BitmapHeapScanState
17031703
TBMSharedIterator *shared_tbmiterator;
17041704
/* parallel worker private ring buffer with prefetch requests: it allows to access prefetch result from the same worker */
17051705
TBMIteratePrefetchResult prefetch_requests[MAX_IO_CONCURRENCY];
1706-
int n_prefetch_requests; /* number of used elements in prefetch_requests ring buffer */
1707-
int prefetch_request_pos; /* head position in ring buffer */
1706+
TBMIteratePrefetchResult tbmres_copy; /* copy of current iterator result */
1707+
int prefetch_head; /* head position in ring buffer */
17081708
ParallelBitmapHeapState *pstate;
17091709
} BitmapHeapScanState;
17101710

0 commit comments

Comments
 (0)