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

Commit cd70dd6

Browse files
committed
Move the PredicateLockRelation() call from nodeSeqscan.c to heapam.c. It's
more consistent that way, since all the other PredicateLock* calls are made in various heapam.c and index AM functions. The call in nodeSeqscan.c was unnecessarily aggressive anyway, there's no need to try to lock the relation every time a tuple is fetched, it's enough to do it once. This has the user-visible effect that if a seq scan is initialized in the executor, but never executed, we now acquire the predicate lock on the heap relation anyway. We could avoid that by taking the lock on the first heap_getnext() call instead, but it doesn't seem worth the trouble given that it feels more natural to do it in heap_beginscan(). Also, remove the retail PredicateLockTuple() calls from heap_getnext(). In a seqscan, started with heap_begin(), we're holding a whole-relation predicate lock on the heap so there's no need to lock the tuples individually. Kevin Grittner and me
1 parent d9fe63a commit cd70dd6

File tree

3 files changed

+14
-14
lines changed

3 files changed

+14
-14
lines changed

src/backend/access/heap/heapam.c

+14-7
Original file line numberDiff line numberDiff line change
@@ -479,8 +479,6 @@ heapgettup(HeapScanDesc scan,
479479

480480
if (valid)
481481
{
482-
if (!scan->rs_relpredicatelocked)
483-
PredicateLockTuple(scan->rs_rd, tuple, snapshot);
484482
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
485483
return;
486484
}
@@ -748,16 +746,12 @@ heapgettup_pagemode(HeapScanDesc scan,
748746
nkeys, key, valid);
749747
if (valid)
750748
{
751-
if (!scan->rs_relpredicatelocked)
752-
PredicateLockTuple(scan->rs_rd, tuple, scan->rs_snapshot);
753749
scan->rs_cindex = lineindex;
754750
return;
755751
}
756752
}
757753
else
758754
{
759-
if (!scan->rs_relpredicatelocked)
760-
PredicateLockTuple(scan->rs_rd, tuple, scan->rs_snapshot);
761755
scan->rs_cindex = lineindex;
762756
return;
763757
}
@@ -1228,13 +1222,26 @@ heap_beginscan_internal(Relation relation, Snapshot snapshot,
12281222
scan->rs_strategy = NULL; /* set in initscan */
12291223
scan->rs_allow_strat = allow_strat;
12301224
scan->rs_allow_sync = allow_sync;
1231-
scan->rs_relpredicatelocked = false;
12321225

12331226
/*
12341227
* we can use page-at-a-time mode if it's an MVCC-safe snapshot
12351228
*/
12361229
scan->rs_pageatatime = IsMVCCSnapshot(snapshot);
12371230

1231+
/*
1232+
* For a seqscan in a serializable transaction, acquire a predicate lock
1233+
* on the entire relation. This is required not only to lock all the
1234+
* matching tuples, but also to conflict with new insertions into the
1235+
* table. In an indexscan, we take page locks on the index pages covering
1236+
* the range specified in the scan qual, but in a heap scan there is
1237+
* nothing more fine-grained to lock. A bitmap scan is a different story,
1238+
* there we have already scanned the index and locked the index pages
1239+
* covering the predicate. But in that case we still have to lock any
1240+
* matching heap tuples.
1241+
*/
1242+
if (!is_bitmapscan)
1243+
PredicateLockRelation(relation, snapshot);
1244+
12381245
/* we only need to set this up once */
12391246
scan->rs_ctup.t_tableOid = RelationGetRelid(relation);
12401247

src/backend/executor/nodeSeqscan.c

-6
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#include "access/relscan.h"
2929
#include "executor/execdebug.h"
3030
#include "executor/nodeSeqscan.h"
31-
#include "storage/predicate.h"
3231

3332
static void InitScanRelation(SeqScanState *node, EState *estate);
3433
static TupleTableSlot *SeqNext(SeqScanState *node);
@@ -106,16 +105,11 @@ SeqRecheck(SeqScanState *node, TupleTableSlot *slot)
106105
* tuple.
107106
* We call the ExecScan() routine and pass it the appropriate
108107
* access method functions.
109-
* For serializable transactions, we first acquire a predicate
110-
* lock on the entire relation.
111108
* ----------------------------------------------------------------
112109
*/
113110
TupleTableSlot *
114111
ExecSeqScan(SeqScanState *node)
115112
{
116-
PredicateLockRelation(node->ss_currentRelation,
117-
node->ss_currentScanDesc->rs_snapshot);
118-
node->ss_currentScanDesc->rs_relpredicatelocked = true;
119113
return ExecScan((ScanState *) node,
120114
(ExecScanAccessMtd) SeqNext,
121115
(ExecScanRecheckMtd) SeqRecheck);

src/include/access/relscan.h

-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ typedef struct HeapScanDescData
3535
BlockNumber rs_startblock; /* block # to start at */
3636
BufferAccessStrategy rs_strategy; /* access strategy for reads */
3737
bool rs_syncscan; /* report location to syncscan logic? */
38-
bool rs_relpredicatelocked; /* predicate lock on relation exists */
3938

4039
/* scan current state */
4140
bool rs_inited; /* false = scan not init'd yet */

0 commit comments

Comments
 (0)