mirror of
https://github.com/postgres/postgres.git
synced 2025-07-12 21:01:52 +03:00
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 1bd4bc85
.
This commit is contained in:
@ -762,13 +762,15 @@ _bt_parallel_done(IndexScanDesc scan)
|
|||||||
BTParallelScanDesc btscan;
|
BTParallelScanDesc btscan;
|
||||||
bool status_changed = false;
|
bool status_changed = false;
|
||||||
|
|
||||||
|
Assert(!BTScanPosIsValid(so->currPos));
|
||||||
|
|
||||||
/* Do nothing, for non-parallel scans */
|
/* Do nothing, for non-parallel scans */
|
||||||
if (parallel_scan == NULL)
|
if (parallel_scan == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Should not mark parallel scan done when there's still a pending
|
* Should not mark parallel scan done when there's still a pending
|
||||||
* primitive index scan
|
* primitive index scan (defensive)
|
||||||
*/
|
*/
|
||||||
if (so->needPrimScan)
|
if (so->needPrimScan)
|
||||||
return;
|
return;
|
||||||
|
@ -1161,28 +1161,18 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
* If we found no usable boundary keys, we have to start from one end of
|
* If we found no usable boundary keys, we have to start from one end of
|
||||||
* the tree. Walk down that edge to the first or last key, and scan from
|
* the tree. Walk down that edge to the first or last key, and scan from
|
||||||
* there.
|
* there.
|
||||||
|
*
|
||||||
|
* Note: calls _bt_readfirstpage for us, which releases the parallel scan.
|
||||||
*/
|
*/
|
||||||
if (keysz == 0)
|
if (keysz == 0)
|
||||||
{
|
return _bt_endpoint(scan, dir);
|
||||||
bool match;
|
|
||||||
|
|
||||||
match = _bt_endpoint(scan, dir);
|
|
||||||
|
|
||||||
if (!match)
|
|
||||||
{
|
|
||||||
/* No match, so mark (parallel) scan finished */
|
|
||||||
_bt_parallel_done(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to start the scan somewhere within the index. Set up an
|
* We want to start the scan somewhere within the index. Set up an
|
||||||
* insertion scankey we can use to search for the boundary point we
|
* insertion scankey we can use to search for the boundary point we
|
||||||
* identified above. The insertion scankey is built using the keys
|
* identified above. The insertion scankey is built using the keys
|
||||||
* identified by startKeys[]. (Remaining insertion scankey fields are
|
* identified by startKeys[]. (Remaining insertion scankey fields are
|
||||||
* initialized after initial-positioning strategy is finalized.)
|
* initialized after initial-positioning scan keys are finalized.)
|
||||||
*/
|
*/
|
||||||
Assert(keysz <= INDEX_MAX_KEYS);
|
Assert(keysz <= INDEX_MAX_KEYS);
|
||||||
for (i = 0; i < keysz; i++)
|
for (i = 0; i < keysz; i++)
|
||||||
@ -1425,12 +1415,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
|
|
||||||
if (!BufferIsValid(so->currPos.buf))
|
if (!BufferIsValid(so->currPos.buf))
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* Mark parallel scan as done, so that all the workers can finish
|
|
||||||
* their scan.
|
|
||||||
*/
|
|
||||||
_bt_parallel_done(scan);
|
_bt_parallel_done(scan);
|
||||||
BTScanPosInvalidate(so->currPos);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2267,8 +2252,8 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno,
|
|||||||
!so->currPos.moreRight : !so->currPos.moreLeft))
|
!so->currPos.moreRight : !so->currPos.moreLeft))
|
||||||
{
|
{
|
||||||
/* most recent _bt_readpage call (for lastcurrblkno) ended scan */
|
/* most recent _bt_readpage call (for lastcurrblkno) ended scan */
|
||||||
_bt_parallel_done(scan);
|
|
||||||
BTScanPosInvalidate(so->currPos);
|
BTScanPosInvalidate(so->currPos);
|
||||||
|
_bt_parallel_done(scan);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2288,8 +2273,8 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno,
|
|||||||
if (so->currPos.buf == InvalidBuffer)
|
if (so->currPos.buf == InvalidBuffer)
|
||||||
{
|
{
|
||||||
/* must have been a concurrent deletion of leftmost page */
|
/* must have been a concurrent deletion of leftmost page */
|
||||||
_bt_parallel_done(scan);
|
|
||||||
BTScanPosInvalidate(so->currPos);
|
BTScanPosInvalidate(so->currPos);
|
||||||
|
_bt_parallel_done(scan);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2564,8 +2549,10 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost)
|
|||||||
*
|
*
|
||||||
* This is used by _bt_first() to set up a scan when we've determined
|
* This is used by _bt_first() to set up a scan when we've determined
|
||||||
* that the scan must start at the beginning or end of the index (for
|
* that the scan must start at the beginning or end of the index (for
|
||||||
* a forward or backward scan respectively). Exit conditions are the
|
* a forward or backward scan respectively).
|
||||||
* same as for _bt_first().
|
*
|
||||||
|
* Parallel scan callers must have seized the scan before calling here.
|
||||||
|
* Exit conditions are the same as for _bt_first().
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
_bt_endpoint(IndexScanDesc scan, ScanDirection dir)
|
_bt_endpoint(IndexScanDesc scan, ScanDirection dir)
|
||||||
@ -2577,10 +2564,11 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
|
|||||||
OffsetNumber start;
|
OffsetNumber start;
|
||||||
BTScanPosItem *currItem;
|
BTScanPosItem *currItem;
|
||||||
|
|
||||||
|
Assert(!BTScanPosIsValid(so->currPos));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan down to the leftmost or rightmost leaf page. This is a simplified
|
* Scan down to the leftmost or rightmost leaf page. This is a simplified
|
||||||
* version of _bt_search(). We don't maintain a stack since we know we
|
* version of _bt_search().
|
||||||
* won't need it.
|
|
||||||
*/
|
*/
|
||||||
so->currPos.buf = _bt_get_endpoint(rel, 0, ScanDirectionIsBackward(dir));
|
so->currPos.buf = _bt_get_endpoint(rel, 0, ScanDirectionIsBackward(dir));
|
||||||
|
|
||||||
@ -2591,7 +2579,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
|
|||||||
* exists.
|
* exists.
|
||||||
*/
|
*/
|
||||||
PredicateLockRelation(rel, scan->xs_snapshot);
|
PredicateLockRelation(rel, scan->xs_snapshot);
|
||||||
BTScanPosInvalidate(so->currPos);
|
_bt_parallel_done(scan);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user