Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0f275b0

Browse files
committed
Fix race in SSI interaction with empty btrees.
When predicate-locking btrees, we have a special case for completelyempty btrees, since there is no page to lock. This was racy, because,without buffer lock held, a matching key could be inserted between the_bt_search() and the PredicateLockRelation() calls.Fix, by rechecking _bt_search() after taking the relation-level SIREADlock, if using SERIALIZABLE isolation and an empty btree is discovered.Back-patch to all supported releases. Fixes one aspect of bug #17949.Reported-by: Artem Anisimov <artem.anisimov.255@gmail.com>Reviewed-by: Dmitry Dolgov <9erthalion6@gmail.com>Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>Discussion:https://postgr.es/m/17949-a0f17035294a55e2%40postgresql.org
1 parent23ce748 commit0f275b0

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

‎src/backend/access/nbtree/nbtsearch.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include"access/nbtree.h"
1919
#include"access/relscan.h"
20+
#include"access/xact.h"
2021
#include"miscadmin.h"
2122
#include"pgstat.h"
2223
#include"storage/predicate.h"
@@ -1372,22 +1373,34 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
13721373
{
13731374
/*
13741375
* We only get here if the index is completely empty. Lock relation
1375-
* because nothing finer to lock exists.
1376+
* because nothing finer to lock exists. Without a buffer lock, it's
1377+
* possible for another transaction to insert data between
1378+
* _bt_search() and PredicateLockRelation(). We have to try again
1379+
* after taking the relation-level predicate lock, to close a narrow
1380+
* window where we wouldn't scan concurrently inserted tuples, but the
1381+
* writer wouldn't see our predicate lock.
13761382
*/
1377-
PredicateLockRelation(rel,scan->xs_snapshot);
1378-
1379-
/*
1380-
* mark parallel scan as done, so that all the workers can finish
1381-
* their scan
1382-
*/
1383-
_bt_parallel_done(scan);
1384-
BTScanPosInvalidate(so->currPos);
1383+
if (IsolationIsSerializable())
1384+
{
1385+
PredicateLockRelation(rel,scan->xs_snapshot);
1386+
stack=_bt_search(rel,&inskey,&buf,BT_READ,
1387+
scan->xs_snapshot);
1388+
_bt_freestack(stack);
1389+
}
13851390

1386-
return false;
1391+
if (!BufferIsValid(buf))
1392+
{
1393+
/*
1394+
* Mark parallel scan as done, so that all the workers can finish
1395+
* their scan.
1396+
*/
1397+
_bt_parallel_done(scan);
1398+
BTScanPosInvalidate(so->currPos);
1399+
return false;
1400+
}
13871401
}
1388-
else
1389-
PredicateLockPage(rel,BufferGetBlockNumber(buf),
1390-
scan->xs_snapshot);
1402+
1403+
PredicateLockPage(rel,BufferGetBlockNumber(buf),scan->xs_snapshot);
13911404

13921405
_bt_initialize_more_data(so,dir);
13931406

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp