1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-28 18:48:04 +03:00

Eliminate xmin from hash tag for predicate locks on heap tuples.

If a tuple was frozen while its predicate locks mattered,
read-write dependencies could be missed, resulting in failure to
detect conflicts which could lead to anomalies in committed
serializable transactions.

This field was added to the tag when we still thought that it was
necessary to carry locks forward to a new version of an updated
row.  That was later proven to be unnecessary, which allowed
simplification of the code, but elimination of xmin from the tag
was missed at the time.

Per report and analysis by Heikki Linnakangas.
Backpatch to 9.1.
This commit is contained in:
Kevin Grittner
2013-10-07 14:05:26 -05:00
parent 6ed3c5f7b2
commit 556e6d0ba3
2 changed files with 14 additions and 29 deletions

View File

@@ -154,9 +154,9 @@
* PredicateLockTuple(Relation relation, HeapTuple tuple,
* Snapshot snapshot)
* PredicateLockPageSplit(Relation relation, BlockNumber oldblkno,
* BlockNumber newblkno);
* BlockNumber newblkno)
* PredicateLockPageCombine(Relation relation, BlockNumber oldblkno,
* BlockNumber newblkno);
* BlockNumber newblkno)
* TransferPredicateLocksToHeapRelation(Relation relation)
* ReleasePredicateLocks(bool isCommit)
*
@@ -377,7 +377,7 @@ static SHM_QUEUE *FinishedSerializableTransactions;
* this entry, you can ensure that there's enough scratch space available for
* inserting one entry in the hash table. This is an otherwise-invalid tag.
*/
static const PREDICATELOCKTARGETTAG ScratchTargetTag = {0, 0, 0, 0, 0};
static const PREDICATELOCKTARGETTAG ScratchTargetTag = {0, 0, 0, 0};
static uint32 ScratchTargetTagHash;
static int ScratchPartitionLock;
@@ -2418,8 +2418,6 @@ PredicateLockTuple(Relation relation, HeapTuple tuple, Snapshot snapshot)
}
}
}
else
targetxmin = InvalidTransactionId;
/*
* Do quick-but-not-definitive test for a relation lock first. This will
@@ -2438,8 +2436,7 @@ PredicateLockTuple(Relation relation, HeapTuple tuple, Snapshot snapshot)
relation->rd_node.dbNode,
relation->rd_id,
ItemPointerGetBlockNumber(tid),
ItemPointerGetOffsetNumber(tid),
targetxmin);
ItemPointerGetOffsetNumber(tid));
PredicateLockAcquire(&tag);
}
@@ -4208,8 +4205,7 @@ CheckForSerializableConflictIn(Relation relation, HeapTuple tuple,
relation->rd_node.dbNode,
relation->rd_id,
ItemPointerGetBlockNumber(&(tuple->t_data->t_ctid)),
ItemPointerGetOffsetNumber(&(tuple->t_data->t_ctid)),
HeapTupleHeaderGetXmin(tuple->t_data));
ItemPointerGetOffsetNumber(&(tuple->t_data->t_ctid)));
CheckTargetForConflictsIn(&targettag);
}