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

Commit 0038110

Browse files
committed
Avoid repeated CLOG access from heap_hot_search_buffer.
At the time we check whether the tuple is dead to all running transactions, we've already verified that it isn't visible to our scan, setting hint bits if appropriate. So there's no need to recheck CLOG for the all-dead test we do just a moment later. So, add HeapTupleIsSurelyDead() to test the appropriate condition under the assumption that all relevant hit bits are already set. Review by Tom Lane.
1 parent 1b4998f commit 0038110

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

src/backend/access/heap/heapam.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,8 +1609,7 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer,
16091609
* transactions.
16101610
*/
16111611
if (all_dead && *all_dead &&
1612-
HeapTupleSatisfiesVacuum(heapTuple->t_data, RecentGlobalXmin,
1613-
buffer) != HEAPTUPLE_DEAD)
1612+
!HeapTupleIsSurelyDead(heapTuple->t_data, RecentGlobalXmin))
16141613
*all_dead = false;
16151614

16161615
/*

src/backend/utils/time/tqual.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,46 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
12191219
return HEAPTUPLE_DEAD;
12201220
}
12211221

1222+
/*
1223+
* HeapTupleIsSurelyDead
1224+
*
1225+
* Determine whether a tuple is surely dead. We sometimes use this
1226+
* in lieu of HeapTupleSatisifesVacuum when the tuple has just been
1227+
* tested by HeapTupleSatisfiesMVCC and, therefore, any hint bits that
1228+
* can be set should already be set. We assume that if no hint bits
1229+
* either for xmin or xmax, the transaction is still running. This is
1230+
* therefore faster than HeapTupleSatisfiesVacuum, because we don't
1231+
* consult CLOG (and also because we don't need to give an exact answer,
1232+
* just whether or not the tuple is surely dead).
1233+
*/
1234+
bool
1235+
HeapTupleIsSurelyDead(HeapTupleHeader tuple, TransactionId OldestXmin)
1236+
{
1237+
/*
1238+
* If the inserting transaction is marked invalid, then it aborted,
1239+
* and the tuple is definitely dead. If it's marked neither committed
1240+
* nor invalid, then we assume it's still alive (since the presumption
1241+
* is that all relevant hint bits were just set moments ago).
1242+
*/
1243+
if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
1244+
return (tuple->t_infomask & HEAP_XMIN_INVALID) != 0 ? true : false;
1245+
1246+
/*
1247+
* If the inserting transaction committed, but any deleting transaction
1248+
* aborted, the tuple is still alive. Likewise, if XMAX is a lock rather
1249+
* than a delete, the tuple is still alive.
1250+
*/
1251+
if (tuple->t_infomask &
1252+
(HEAP_XMAX_INVALID | HEAP_IS_LOCKED | HEAP_XMAX_IS_MULTI))
1253+
return false;
1254+
1255+
/* If deleter isn't known to have committed, assume it's still running. */
1256+
if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
1257+
return false;
1258+
1259+
/* Deleter committed, so tuple is dead if the XID is old enough. */
1260+
return TransactionIdPrecedes(HeapTupleHeaderGetXmax(tuple), OldestXmin);
1261+
}
12221262

12231263
/*
12241264
* XidInMVCCSnapshot

src/include/utils/tqual.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ extern HTSU_Result HeapTupleSatisfiesUpdate(HeapTupleHeader tuple,
8383
CommandId curcid, Buffer buffer);
8484
extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple,
8585
TransactionId OldestXmin, Buffer buffer);
86+
extern bool HeapTupleIsSurelyDead(HeapTupleHeader tuple,
87+
TransactionId OldestXmin);
8688

8789
extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
8890
uint16 infomask, TransactionId xid);

0 commit comments

Comments
 (0)