Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 62620b6

Browse files
Clarify nbtree parallel scan _bt_endpoint contract.
_bt_endpoint is a helper function for _bt_first that's called whenever no useful insertion scan key can be used, and we need to lock and read either the leftmost or rightmost leaf page in the index. Simplify and document its preconditions, relieving its _bt_first caller from having to end the parallel scan when it returns false. Also stop unnecessarily invalidating the current scan position in nearby code in both _bt_first and _bt_endpoint. This seems to have been copy-pasted from _bt_readnextpage, where invalidating the scan's current position really is necessary. Follow-up to the refactoring work in commit 1bd4bc8.
1 parent 1fe0466 commit 62620b6

File tree

2 files changed

+17
-27
lines changed

2 files changed

+17
-27
lines changed

src/backend/access/nbtree/nbtree.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -762,13 +762,15 @@ _bt_parallel_done(IndexScanDesc scan)
762762
BTParallelScanDesc btscan;
763763
bool status_changed = false;
764764

765+
Assert(!BTScanPosIsValid(so->currPos));
766+
765767
/* Do nothing, for non-parallel scans */
766768
if (parallel_scan == NULL)
767769
return;
768770

769771
/*
770772
* Should not mark parallel scan done when there's still a pending
771-
* primitive index scan
773+
* primitive index scan (defensive)
772774
*/
773775
if (so->needPrimScan)
774776
return;

src/backend/access/nbtree/nbtsearch.c

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,28 +1161,18 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
11611161
* If we found no usable boundary keys, we have to start from one end of
11621162
* the tree. Walk down that edge to the first or last key, and scan from
11631163
* there.
1164+
*
1165+
* Note: calls _bt_readfirstpage for us, which releases the parallel scan.
11641166
*/
11651167
if (keysz == 0)
1166-
{
1167-
bool match;
1168-
1169-
match = _bt_endpoint(scan, dir);
1170-
1171-
if (!match)
1172-
{
1173-
/* No match, so mark (parallel) scan finished */
1174-
_bt_parallel_done(scan);
1175-
}
1176-
1177-
return match;
1178-
}
1168+
return _bt_endpoint(scan, dir);
11791169

11801170
/*
11811171
* We want to start the scan somewhere within the index. Set up an
11821172
* insertion scankey we can use to search for the boundary point we
11831173
* identified above. The insertion scankey is built using the keys
11841174
* identified by startKeys[]. (Remaining insertion scankey fields are
1185-
* initialized after initial-positioning strategy is finalized.)
1175+
* initialized after initial-positioning scan keys are finalized.)
11861176
*/
11871177
Assert(keysz <= INDEX_MAX_KEYS);
11881178
for (i = 0; i < keysz; i++)
@@ -1425,12 +1415,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
14251415

14261416
if (!BufferIsValid(so->currPos.buf))
14271417
{
1428-
/*
1429-
* Mark parallel scan as done, so that all the workers can finish
1430-
* their scan.
1431-
*/
14321418
_bt_parallel_done(scan);
1433-
BTScanPosInvalidate(so->currPos);
14341419
return false;
14351420
}
14361421
}
@@ -2267,8 +2252,8 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno,
22672252
!so->currPos.moreRight : !so->currPos.moreLeft))
22682253
{
22692254
/* most recent _bt_readpage call (for lastcurrblkno) ended scan */
2270-
_bt_parallel_done(scan);
22712255
BTScanPosInvalidate(so->currPos);
2256+
_bt_parallel_done(scan);
22722257
return false;
22732258
}
22742259

@@ -2288,8 +2273,8 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno,
22882273
if (so->currPos.buf == InvalidBuffer)
22892274
{
22902275
/* must have been a concurrent deletion of leftmost page */
2291-
_bt_parallel_done(scan);
22922276
BTScanPosInvalidate(so->currPos);
2277+
_bt_parallel_done(scan);
22932278
return false;
22942279
}
22952280
}
@@ -2564,8 +2549,10 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost)
25642549
*
25652550
* This is used by _bt_first() to set up a scan when we've determined
25662551
* that the scan must start at the beginning or end of the index (for
2567-
* a forward or backward scan respectively). Exit conditions are the
2568-
* same as for _bt_first().
2552+
* a forward or backward scan respectively).
2553+
*
2554+
* Parallel scan callers must have seized the scan before calling here.
2555+
* Exit conditions are the same as for _bt_first().
25692556
*/
25702557
static bool
25712558
_bt_endpoint(IndexScanDesc scan, ScanDirection dir)
@@ -2577,10 +2564,11 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
25772564
OffsetNumber start;
25782565
BTScanPosItem *currItem;
25792566

2567+
Assert(!BTScanPosIsValid(so->currPos));
2568+
25802569
/*
25812570
* Scan down to the leftmost or rightmost leaf page. This is a simplified
2582-
* version of _bt_search(). We don't maintain a stack since we know we
2583-
* won't need it.
2571+
* version of _bt_search().
25842572
*/
25852573
so->currPos.buf = _bt_get_endpoint(rel, 0, ScanDirectionIsBackward(dir));
25862574

@@ -2591,7 +2579,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
25912579
* exists.
25922580
*/
25932581
PredicateLockRelation(rel, scan->xs_snapshot);
2594-
BTScanPosInvalidate(so->currPos);
2582+
_bt_parallel_done(scan);
25952583
return false;
25962584
}
25972585

0 commit comments

Comments
 (0)