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

Commit 0a0e2b5

Browse files
committed
Make non-MVCC snapshots exempt from predicate locking. Scans with non-MVCC
snapshots, like in REINDEX, are basically non-transactional operations. The DDL operation itself might participate in SSI, but there's separate functions for that. Kevin Grittner and Dan Ports, with some changes by me.
1 parent 707195c commit 0a0e2b5

File tree

6 files changed

+151
-100
lines changed

6 files changed

+151
-100
lines changed

src/backend/access/heap/heapam.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,8 @@ heapgetpage(HeapScanDesc scan, BlockNumber page)
274274
else
275275
valid = HeapTupleSatisfiesVisibility(&loctup, snapshot, buffer);
276276

277-
CheckForSerializableConflictOut(valid, scan->rs_rd, &loctup, buffer);
277+
CheckForSerializableConflictOut(valid, scan->rs_rd, &loctup,
278+
buffer, snapshot);
278279

279280
if (valid)
280281
scan->rs_vistuples[ntup++] = lineoff;
@@ -469,7 +470,8 @@ heapgettup(HeapScanDesc scan,
469470
snapshot,
470471
scan->rs_cbuf);
471472

472-
CheckForSerializableConflictOut(valid, scan->rs_rd, tuple, scan->rs_cbuf);
473+
CheckForSerializableConflictOut(valid, scan->rs_rd, tuple,
474+
scan->rs_cbuf, snapshot);
473475

474476
if (valid && key != NULL)
475477
HeapKeyTest(tuple, RelationGetDescr(scan->rs_rd),
@@ -478,7 +480,7 @@ heapgettup(HeapScanDesc scan,
478480
if (valid)
479481
{
480482
if (!scan->rs_relpredicatelocked)
481-
PredicateLockTuple(scan->rs_rd, tuple);
483+
PredicateLockTuple(scan->rs_rd, tuple, snapshot);
482484
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
483485
return;
484486
}
@@ -747,15 +749,15 @@ heapgettup_pagemode(HeapScanDesc scan,
747749
if (valid)
748750
{
749751
if (!scan->rs_relpredicatelocked)
750-
PredicateLockTuple(scan->rs_rd, tuple);
752+
PredicateLockTuple(scan->rs_rd, tuple, scan->rs_snapshot);
751753
scan->rs_cindex = lineindex;
752754
return;
753755
}
754756
}
755757
else
756758
{
757759
if (!scan->rs_relpredicatelocked)
758-
PredicateLockTuple(scan->rs_rd, tuple);
760+
PredicateLockTuple(scan->rs_rd, tuple, scan->rs_snapshot);
759761
scan->rs_cindex = lineindex;
760762
return;
761763
}
@@ -1470,9 +1472,9 @@ heap_fetch(Relation relation,
14701472
valid = HeapTupleSatisfiesVisibility(tuple, snapshot, buffer);
14711473

14721474
if (valid)
1473-
PredicateLockTuple(relation, tuple);
1475+
PredicateLockTuple(relation, tuple, snapshot);
14741476

1475-
CheckForSerializableConflictOut(valid, relation, tuple, buffer);
1477+
CheckForSerializableConflictOut(valid, relation, tuple, buffer, snapshot);
14761478

14771479
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
14781480

@@ -1588,11 +1590,12 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer,
15881590

15891591
/* If it's visible per the snapshot, we must return it */
15901592
valid = HeapTupleSatisfiesVisibility(&heapTuple, snapshot, buffer);
1591-
CheckForSerializableConflictOut(valid, relation, &heapTuple, buffer);
1593+
CheckForSerializableConflictOut(valid, relation, &heapTuple, buffer,
1594+
snapshot);
15921595
if (valid)
15931596
{
15941597
ItemPointerSetOffsetNumber(tid, offnum);
1595-
PredicateLockTuple(relation, &heapTuple);
1598+
PredicateLockTuple(relation, &heapTuple, snapshot);
15961599
if (all_dead)
15971600
*all_dead = false;
15981601
return true;
@@ -1750,7 +1753,7 @@ heap_get_latest_tid(Relation relation,
17501753
* result candidate.
17511754
*/
17521755
valid = HeapTupleSatisfiesVisibility(&tp, snapshot, buffer);
1753-
CheckForSerializableConflictOut(valid, relation, &tp, buffer);
1756+
CheckForSerializableConflictOut(valid, relation, &tp, buffer, snapshot);
17541757
if (valid)
17551758
*tid = ctid;
17561759

src/backend/access/index/indexam.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ do { \
126126
} while(0)
127127

128128
static IndexScanDesc index_beginscan_internal(Relation indexRelation,
129-
int nkeys, int norderbys);
129+
int nkeys, int norderbys, Snapshot snapshot);
130130

131131

132132
/* ----------------------------------------------------------------
@@ -234,7 +234,7 @@ index_beginscan(Relation heapRelation,
234234
{
235235
IndexScanDesc scan;
236236

237-
scan = index_beginscan_internal(indexRelation, nkeys, norderbys);
237+
scan = index_beginscan_internal(indexRelation, nkeys, norderbys, snapshot);
238238

239239
/*
240240
* Save additional parameters into the scandesc. Everything else was set
@@ -259,7 +259,7 @@ index_beginscan_bitmap(Relation indexRelation,
259259
{
260260
IndexScanDesc scan;
261261

262-
scan = index_beginscan_internal(indexRelation, nkeys, 0);
262+
scan = index_beginscan_internal(indexRelation, nkeys, 0, snapshot);
263263

264264
/*
265265
* Save additional parameters into the scandesc. Everything else was set
@@ -275,7 +275,7 @@ index_beginscan_bitmap(Relation indexRelation,
275275
*/
276276
static IndexScanDesc
277277
index_beginscan_internal(Relation indexRelation,
278-
int nkeys, int norderbys)
278+
int nkeys, int norderbys, Snapshot snapshot)
279279
{
280280
IndexScanDesc scan;
281281
FmgrInfo *procedure;
@@ -284,7 +284,7 @@ index_beginscan_internal(Relation indexRelation,
284284
GET_REL_PROCEDURE(ambeginscan);
285285

286286
if (!(indexRelation->rd_am->ampredlocks))
287-
PredicateLockRelation(indexRelation);
287+
PredicateLockRelation(indexRelation, snapshot);
288288

289289
/*
290290
* We hold a reference count to the relcache entry throughout the scan.
@@ -602,7 +602,8 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
602602
scan->xs_cbuf);
603603

604604
CheckForSerializableConflictOut(valid, scan->heapRelation,
605-
heapTuple, scan->xs_cbuf);
605+
heapTuple, scan->xs_cbuf,
606+
scan->xs_snapshot);
606607

607608
if (valid)
608609
{
@@ -624,7 +625,7 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
624625
else
625626
scan->xs_next_hot = InvalidOffsetNumber;
626627

627-
PredicateLockTuple(scan->heapRelation, heapTuple);
628+
PredicateLockTuple(scan->heapRelation, heapTuple, scan->xs_snapshot);
628629

629630
LockBuffer(scan->xs_cbuf, BUFFER_LOCK_UNLOCK);
630631

src/backend/access/nbtree/nbtsearch.c

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,7 @@ _bt_search(Relation rel, int keysz, ScanKey scankey, bool nextkey,
6464

6565
/* If index is empty and access = BT_READ, no root page is created. */
6666
if (!BufferIsValid(*bufP))
67-
{
68-
PredicateLockRelation(rel); /* Nothing finer to lock exists. */
6967
return (BTStack) NULL;
70-
}
7168

7269
/* Loop iterates once per level descended in the tree */
7370
for (;;)
@@ -92,11 +89,7 @@ _bt_search(Relation rel, int keysz, ScanKey scankey, bool nextkey,
9289
page = BufferGetPage(*bufP);
9390
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
9491
if (P_ISLEAF(opaque))
95-
{
96-
if (access == BT_READ)
97-
PredicateLockPage(rel, BufferGetBlockNumber(*bufP));
9892
break;
99-
}
10093

10194
/*
10295
* Find the appropriate item on the internal page, and get the child
@@ -855,9 +848,16 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
855848

856849
if (!BufferIsValid(buf))
857850
{
858-
/* Only get here if index is completely empty */
851+
/*
852+
* We only get here if the index is completely empty.
853+
* Lock relation because nothing finer to lock exists.
854+
*/
855+
PredicateLockRelation(rel, scan->xs_snapshot);
859856
return false;
860857
}
858+
else
859+
PredicateLockPage(rel, BufferGetBlockNumber(buf),
860+
scan->xs_snapshot);
861861

862862
/* initialize moreLeft/moreRight appropriately for scan direction */
863863
if (ScanDirectionIsForward(dir))
@@ -1153,7 +1153,7 @@ _bt_steppage(IndexScanDesc scan, ScanDirection dir)
11531153
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
11541154
if (!P_IGNORE(opaque))
11551155
{
1156-
PredicateLockPage(rel, blkno);
1156+
PredicateLockPage(rel, blkno, scan->xs_snapshot);
11571157
/* see if there are any matches on this page */
11581158
/* note that this will clear moreRight if we can stop */
11591159
if (_bt_readpage(scan, dir, P_FIRSTDATAKEY(opaque)))
@@ -1201,7 +1201,7 @@ _bt_steppage(IndexScanDesc scan, ScanDirection dir)
12011201
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
12021202
if (!P_IGNORE(opaque))
12031203
{
1204-
PredicateLockPage(rel, BufferGetBlockNumber(so->currPos.buf));
1204+
PredicateLockPage(rel, BufferGetBlockNumber(so->currPos.buf), scan->xs_snapshot);
12051205
/* see if there are any matches on this page */
12061206
/* note that this will clear moreLeft if we can stop */
12071207
if (_bt_readpage(scan, dir, PageGetMaxOffsetNumber(page)))
@@ -1363,11 +1363,7 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost)
13631363
buf = _bt_gettrueroot(rel);
13641364

13651365
if (!BufferIsValid(buf))
1366-
{
1367-
/* empty index... */
1368-
PredicateLockRelation(rel); /* Nothing finer to lock exists. */
13691366
return InvalidBuffer;
1370-
}
13711367

13721368
page = BufferGetPage(buf);
13731369
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
@@ -1444,13 +1440,16 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
14441440

14451441
if (!BufferIsValid(buf))
14461442
{
1447-
/* empty index... */
1448-
PredicateLockRelation(rel); /* Nothing finer to lock exists. */
1443+
/*
1444+
* Empty index. Lock the whole relation, as nothing finer to lock
1445+
* exists.
1446+
*/
1447+
PredicateLockRelation(rel, scan->xs_snapshot);
14491448
so->currPos.buf = InvalidBuffer;
14501449
return false;
14511450
}
14521451

1453-
PredicateLockPage(rel, BufferGetBlockNumber(buf));
1452+
PredicateLockPage(rel, BufferGetBlockNumber(buf), scan->xs_snapshot);
14541453
page = BufferGetPage(buf);
14551454
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
14561455
Assert(P_ISLEAF(opaque));

src/backend/executor/nodeSeqscan.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ SeqRecheck(SeqScanState *node, TupleTableSlot *slot)
113113
TupleTableSlot *
114114
ExecSeqScan(SeqScanState *node)
115115
{
116-
PredicateLockRelation(node->ss_currentRelation);
116+
PredicateLockRelation(node->ss_currentRelation,
117+
node->ss_currentScanDesc->rs_snapshot);
117118
node->ss_currentScanDesc->rs_relpredicatelocked = true;
118119
return ExecScan((ScanState *) node,
119120
(ExecScanAccessMtd) SeqNext,

0 commit comments

Comments
 (0)