Skip to content

Commit 264a6b1

Browse files
committed
The rolled-back flag on serializable xacts was pointless and redundant with
the marked-for-death flag. It was only set for a fleeting moment while a transaction was being cleaned up at rollback. All the places that checked for the rolled-back flag should also check the marked-for-death flag, as both flags mean that the transaction will roll back. I also renamed the marked-for-death into "doomed", which is a lot shorter name.
1 parent 0a0e2b5 commit 264a6b1

File tree

2 files changed

+29
-34
lines changed

2 files changed

+29
-34
lines changed

src/backend/storage/lmgr/predicate.c

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,9 @@
244244

245245
#define SxactIsOnFinishedList(sxact) (!SHMQueueIsDetached(&((sxact)->finishedLink)))
246246

247-
#define SxactIsPrepared(sxact) (((sxact)->flags & SXACT_FLAG_PREPARED) != 0)
248247
#define SxactIsCommitted(sxact) (((sxact)->flags & SXACT_FLAG_COMMITTED) != 0)
249-
#define SxactIsRolledBack(sxact) (((sxact)->flags & SXACT_FLAG_ROLLED_BACK) != 0)
248+
#define SxactIsPrepared(sxact) (((sxact)->flags & SXACT_FLAG_PREPARED) != 0)
249+
#define SxactIsDoomed(sxact) (((sxact)->flags & SXACT_FLAG_DOOMED) != 0)
250250
#define SxactIsReadOnly(sxact) (((sxact)->flags & SXACT_FLAG_READ_ONLY) != 0)
251251
#define SxactHasSummaryConflictIn(sxact) (((sxact)->flags & SXACT_FLAG_SUMMARY_CONFLICT_IN) != 0)
252252
#define SxactHasSummaryConflictOut(sxact) (((sxact)->flags & SXACT_FLAG_SUMMARY_CONFLICT_OUT) != 0)
@@ -259,7 +259,6 @@
259259
#define SxactIsDeferrableWaiting(sxact) (((sxact)->flags & SXACT_FLAG_DEFERRABLE_WAITING) != 0)
260260
#define SxactIsROSafe(sxact) (((sxact)->flags & SXACT_FLAG_RO_SAFE) != 0)
261261
#define SxactIsROUnsafe(sxact) (((sxact)->flags & SXACT_FLAG_RO_UNSAFE) != 0)
262-
#define SxactIsMarkedForDeath(sxact) (((sxact)->flags & SXACT_FLAG_MARKED_FOR_DEATH) != 0)
263262

264263
/*
265264
* Compute the hash code associated with a PREDICATELOCKTARGETTAG.
@@ -609,8 +608,8 @@ RWConflictExists(const SERIALIZABLEXACT *reader, const SERIALIZABLEXACT *writer)
609608
Assert(reader != writer);
610609

611610
/* Check the ends of the purported conflict first. */
612-
if (SxactIsRolledBack(reader)
613-
|| SxactIsRolledBack(writer)
611+
if (SxactIsDoomed(reader)
612+
|| SxactIsDoomed(writer)
614613
|| SHMQueueEmpty(&reader->outConflicts)
615614
|| SHMQueueEmpty(&writer->inConflicts))
616615
return false;
@@ -3048,7 +3047,7 @@ SetNewSxactGlobalXmin(void)
30483047

30493048
for (sxact = FirstPredXact(); sxact != NULL; sxact = NextPredXact(sxact))
30503049
{
3051-
if (!SxactIsRolledBack(sxact)
3050+
if (!SxactIsDoomed(sxact)
30523051
&& !SxactIsCommitted(sxact)
30533052
&& sxact != OldCommittedSxact)
30543053
{
@@ -3113,7 +3112,7 @@ ReleasePredicateLocks(const bool isCommit)
31133112
}
31143113

31153114
Assert(!isCommit || SxactIsPrepared(MySerializableXact));
3116-
Assert(!SxactIsRolledBack(MySerializableXact));
3115+
Assert(!isCommit || !SxactIsDoomed(MySerializableXact));
31173116
Assert(!SxactIsCommitted(MySerializableXact));
31183117

31193118
/* may not be serializable during COMMIT/ROLLBACK PREPARED */
@@ -3153,9 +3152,7 @@ ReleasePredicateLocks(const bool isCommit)
31533152
MySerializableXact->flags |= SXACT_FLAG_READ_ONLY;
31543153
}
31553154
else
3156-
{
3157-
MySerializableXact->flags |= SXACT_FLAG_ROLLED_BACK;
3158-
}
3155+
MySerializableXact->flags |= SXACT_FLAG_DOOMED;
31593156

31603157
if (!topLevelIsDeclaredReadOnly)
31613158
{
@@ -3531,7 +3528,7 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
35313528
nextConflict;
35323529

35333530
Assert(sxact != NULL);
3534-
Assert(SxactIsRolledBack(sxact) || SxactIsCommitted(sxact));
3531+
Assert(SxactIsDoomed(sxact) || SxactIsCommitted(sxact));
35353532
Assert(LWLockHeldByMe(SerializableFinishedListLock));
35363533

35373534
/*
@@ -3736,7 +3733,8 @@ CheckForSerializableConflictOut(const bool visible, const Relation relation,
37363733
if (!SerializationNeededForRead(relation, snapshot))
37373734
return;
37383735

3739-
if (SxactIsMarkedForDeath(MySerializableXact))
3736+
/* Check if someone else has already decided that we need to die */
3737+
if (SxactIsDoomed(MySerializableXact))
37403738
{
37413739
ereport(ERROR,
37423740
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
@@ -3850,11 +3848,9 @@ CheckForSerializableConflictOut(const bool visible, const Relation relation,
38503848
}
38513849
sxact = sxid->myXact;
38523850
Assert(TransactionIdEquals(sxact->topXid, xid));
3853-
if (sxact == MySerializableXact
3854-
|| SxactIsRolledBack(sxact)
3855-
|| SxactIsMarkedForDeath(sxact))
3851+
if (sxact == MySerializableXact || SxactIsDoomed(sxact))
38563852
{
3857-
/* We can't conflict with our own transaction or one rolled back. */
3853+
/* Can't conflict with ourself or a transaction that will roll back. */
38583854
LWLockRelease(SerializableXactHashLock);
38593855
return;
38603856
}
@@ -3869,7 +3865,7 @@ CheckForSerializableConflictOut(const bool visible, const Relation relation,
38693865
{
38703866
if (!SxactIsPrepared(sxact))
38713867
{
3872-
sxact->flags |= SXACT_FLAG_MARKED_FOR_DEATH;
3868+
sxact->flags |= SXACT_FLAG_DOOMED;
38733869
LWLockRelease(SerializableXactHashLock);
38743870
return;
38753871
}
@@ -3996,7 +3992,7 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
39963992
mypredlocktag = predlock->tag;
39973993
}
39983994
}
3999-
else if (!SxactIsRolledBack(sxact)
3995+
else if (!SxactIsDoomed(sxact)
40003996
&& (!SxactIsCommitted(sxact)
40013997
|| TransactionIdPrecedes(GetTransactionSnapshot()->xmin,
40023998
sxact->finishedBefore))
@@ -4009,7 +4005,7 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
40094005
* Re-check after getting exclusive lock because the other
40104006
* transaction may have flagged a conflict.
40114007
*/
4012-
if (!SxactIsRolledBack(sxact)
4008+
if (!SxactIsDoomed(sxact)
40134009
&& (!SxactIsCommitted(sxact)
40144010
|| TransactionIdPrecedes(GetTransactionSnapshot()->xmin,
40154011
sxact->finishedBefore))
@@ -4113,7 +4109,8 @@ CheckForSerializableConflictIn(const Relation relation, const HeapTuple tuple,
41134109
if (!SerializationNeededForWrite(relation))
41144110
return;
41154111

4116-
if (SxactIsMarkedForDeath(MySerializableXact))
4112+
/* Check if someone else has already decided that we need to die */
4113+
if (SxactIsDoomed(MySerializableXact))
41174114
ereport(ERROR,
41184115
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
41194116
errmsg("could not serialize access due to read/write dependencies among transactions"),
@@ -4417,7 +4414,7 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader,
44174414
{
44184415
SERIALIZABLEXACT *t0 = conflict->sxactOut;
44194416

4420-
if (!SxactIsRolledBack(t0)
4417+
if (!SxactIsDoomed(t0)
44214418
&& (!SxactIsCommitted(t0)
44224419
|| t0->commitSeqNo >= writer->commitSeqNo)
44234420
&& (!SxactIsReadOnly(t0)
@@ -4464,7 +4461,7 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader,
44644461
errdetail("Cancelled on conflict out to pivot %u, during read.", writer->topXid),
44654462
errhint("The transaction might succeed if retried.")));
44664463
}
4467-
writer->flags |= SXACT_FLAG_MARKED_FOR_DEATH;
4464+
writer->flags |= SXACT_FLAG_DOOMED;
44684465
}
44694466
}
44704467

@@ -4496,7 +4493,8 @@ PreCommit_CheckForSerializationFailure(void)
44964493

44974494
LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
44984495

4499-
if (SxactIsMarkedForDeath(MySerializableXact))
4496+
/* Check if someone else has already decided that we need to die */
4497+
if (SxactIsDoomed(MySerializableXact))
45004498
{
45014499
LWLockRelease(SerializableXactHashLock);
45024500
ereport(ERROR,
@@ -4513,8 +4511,7 @@ PreCommit_CheckForSerializationFailure(void)
45134511
while (nearConflict)
45144512
{
45154513
if (!SxactIsCommitted(nearConflict->sxactOut)
4516-
&& !SxactIsRolledBack(nearConflict->sxactOut)
4517-
&& !SxactIsMarkedForDeath(nearConflict->sxactOut))
4514+
&& !SxactIsDoomed(nearConflict->sxactOut))
45184515
{
45194516
RWConflict farConflict;
45204517

@@ -4527,10 +4524,9 @@ PreCommit_CheckForSerializationFailure(void)
45274524
if (farConflict->sxactOut == MySerializableXact
45284525
|| (!SxactIsCommitted(farConflict->sxactOut)
45294526
&& !SxactIsReadOnly(farConflict->sxactOut)
4530-
&& !SxactIsRolledBack(farConflict->sxactOut)
4531-
&& !SxactIsMarkedForDeath(farConflict->sxactOut)))
4527+
&& !SxactIsDoomed(farConflict->sxactOut)))
45324528
{
4533-
nearConflict->sxactOut->flags |= SXACT_FLAG_MARKED_FOR_DEATH;
4529+
nearConflict->sxactOut->flags |= SXACT_FLAG_DOOMED;
45344530
break;
45354531
}
45364532
farConflict = (RWConflict)

src/include/storage/predicate_internals.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,22 +90,21 @@ typedef struct SERIALIZABLEXACT
9090
int pid; /* pid of associated process */
9191
} SERIALIZABLEXACT;
9292

93-
#define SXACT_FLAG_ROLLED_BACK 0x00000001
94-
#define SXACT_FLAG_COMMITTED 0x00000002
93+
#define SXACT_FLAG_COMMITTED 0x00000001 /* already committed */
94+
#define SXACT_FLAG_PREPARED 0x00000002 /* about to commit */
95+
#define SXACT_FLAG_DOOMED 0x00000004 /* will roll back */
9596
/*
9697
* The following flag actually means that the flagged transaction has a
9798
* conflict out *to a transaction which committed ahead of it*. It's hard
9899
* to get that into a name of a reasonable length.
99100
*/
100-
#define SXACT_FLAG_CONFLICT_OUT 0x00000004
101-
#define SXACT_FLAG_READ_ONLY 0x00000008
102-
#define SXACT_FLAG_MARKED_FOR_DEATH 0x00000010
101+
#define SXACT_FLAG_CONFLICT_OUT 0x00000008
102+
#define SXACT_FLAG_READ_ONLY 0x00000010
103103
#define SXACT_FLAG_DEFERRABLE_WAITING 0x00000020
104104
#define SXACT_FLAG_RO_SAFE 0x00000040
105105
#define SXACT_FLAG_RO_UNSAFE 0x00000080
106106
#define SXACT_FLAG_SUMMARY_CONFLICT_IN 0x00000100
107107
#define SXACT_FLAG_SUMMARY_CONFLICT_OUT 0x00000200
108-
#define SXACT_FLAG_PREPARED 0x00000400
109108

110109
/*
111110
* The following types are used to provide an ad hoc list for holding

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy