mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Fix another empty nbtree index SSI race.
Commitf9b7fc65fixed a race when predicate-locking completely empty btrees: without a buffer lock held, a matching key could be inserted between _bt_search and the PredicateLockRelation call, so the scan would miss concurrently inserted tuples while the writer wouldn't see the reader's predicate lock. That commit only fixed _bt_first's _bt_search path, though. Scans without useful insertion scan keys return early from _bt_first via _bt_endpoint, which still didn't recheck if the relation was empty. To fix, add handling to _bt_endpoint that is analogous to the handling added to _bt_search by commitf9b7fc65. Author: Peter Geoghegan <pg@bowt.ie> Discussion: https://postgr.es/m/CAH2-WzkNoTn3yXY0iGkSuavJ+sL8EROf+kitW+_2v2tJVWuKmA@mail.gmail.com Backpatch-through: 14
This commit is contained in:
@@ -2426,12 +2426,21 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
|
||||
if (!BufferIsValid(buf))
|
||||
{
|
||||
/*
|
||||
* Empty index. Lock the whole relation, as nothing finer to lock
|
||||
* exists.
|
||||
* Empty index. Lock the whole relation using the approach explained
|
||||
* at the same point in the _bt_first path.
|
||||
*/
|
||||
PredicateLockRelation(rel, scan->xs_snapshot);
|
||||
BTScanPosInvalidate(so->currPos);
|
||||
return false;
|
||||
if (IsolationIsSerializable())
|
||||
{
|
||||
PredicateLockRelation(rel, scan->xs_snapshot);
|
||||
buf = _bt_get_endpoint(rel, 0, ScanDirectionIsBackward(dir),
|
||||
scan->xs_snapshot);
|
||||
}
|
||||
|
||||
if (!BufferIsValid(buf))
|
||||
{
|
||||
BTScanPosInvalidate(so->currPos);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PredicateLockPage(rel, BufferGetBlockNumber(buf), scan->xs_snapshot);
|
||||
|
||||
Reference in New Issue
Block a user