Skip to content

Commit 7cb2ff9

Browse files
committed
Fix bug introduced by recent SSI patch to merge ROLLED_BACK and
MARKED_FOR_DEATH flags into one. We still need the ROLLED_BACK flag to mark transactions that are in the process of being rolled back. To be precise, ROLLED_BACK now means that a transaction has already been discounted from the count of transactions with the oldest xmin, but not yet removed from the list of active transactions. Dan Ports
1 parent 31e8ab4 commit 7cb2ff9

File tree

2 files changed

+30
-12
lines changed

2 files changed

+30
-12
lines changed

src/backend/storage/lmgr/predicate.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@
246246

247247
#define SxactIsCommitted(sxact) (((sxact)->flags & SXACT_FLAG_COMMITTED) != 0)
248248
#define SxactIsPrepared(sxact) (((sxact)->flags & SXACT_FLAG_PREPARED) != 0)
249+
#define SxactIsRolledBack(sxact) (((sxact)->flags & SXACT_FLAG_ROLLED_BACK) != 0)
249250
#define SxactIsDoomed(sxact) (((sxact)->flags & SXACT_FLAG_DOOMED) != 0)
250251
#define SxactIsReadOnly(sxact) (((sxact)->flags & SXACT_FLAG_READ_ONLY) != 0)
251252
#define SxactHasSummaryConflictIn(sxact) (((sxact)->flags & SXACT_FLAG_SUMMARY_CONFLICT_IN) != 0)
@@ -3046,7 +3047,7 @@ SetNewSxactGlobalXmin(void)
30463047

30473048
for (sxact = FirstPredXact(); sxact != NULL; sxact = NextPredXact(sxact))
30483049
{
3049-
if (!SxactIsDoomed(sxact)
3050+
if (!SxactIsRolledBack(sxact)
30503051
&& !SxactIsCommitted(sxact)
30513052
&& sxact != OldCommittedSxact)
30523053
{
@@ -3113,6 +3114,7 @@ ReleasePredicateLocks(const bool isCommit)
31133114
Assert(!isCommit || SxactIsPrepared(MySerializableXact));
31143115
Assert(!isCommit || !SxactIsDoomed(MySerializableXact));
31153116
Assert(!SxactIsCommitted(MySerializableXact));
3117+
Assert(!SxactIsRolledBack(MySerializableXact));
31163118

31173119
/* may not be serializable during COMMIT/ROLLBACK PREPARED */
31183120
if (MySerializableXact->pid != 0)
@@ -3151,7 +3153,22 @@ ReleasePredicateLocks(const bool isCommit)
31513153
MySerializableXact->flags |= SXACT_FLAG_READ_ONLY;
31523154
}
31533155
else
3156+
{
3157+
/*
3158+
* The DOOMED flag indicates that we intend to roll back this
3159+
* transaction and so it should not cause serialization failures for
3160+
* other transactions that conflict with it. Note that this flag might
3161+
* already be set, if another backend marked this transaction for
3162+
* abort.
3163+
*
3164+
* The ROLLED_BACK flag further indicates that ReleasePredicateLocks
3165+
* has been called, and so the SerializableXact is eligible for
3166+
* cleanup. This means it should not be considered when calculating
3167+
* SxactGlobalXmin.
3168+
*/
31543169
MySerializableXact->flags |= SXACT_FLAG_DOOMED;
3170+
MySerializableXact->flags |= SXACT_FLAG_ROLLED_BACK;
3171+
}
31553172

31563173
if (!topLevelIsDeclaredReadOnly)
31573174
{
@@ -3527,7 +3544,7 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
35273544
nextConflict;
35283545

35293546
Assert(sxact != NULL);
3530-
Assert(SxactIsDoomed(sxact) || SxactIsCommitted(sxact));
3547+
Assert(SxactIsRolledBack(sxact) || SxactIsCommitted(sxact));
35313548
Assert(LWLockHeldByMe(SerializableFinishedListLock));
35323549

35333550
/*

src/include/storage/predicate_internals.h

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

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 */
93+
#define SXACT_FLAG_COMMITTED 0x00000001 /* already committed */
94+
#define SXACT_FLAG_PREPARED 0x00000002 /* about to commit */
95+
#define SXACT_FLAG_ROLLED_BACK 0x00000004 /* already rolled back */
96+
#define SXACT_FLAG_DOOMED 0x00000008 /* will roll back */
9697
/*
9798
* The following flag actually means that the flagged transaction has a
9899
* conflict out *to a transaction which committed ahead of it*. It's hard
99100
* to get that into a name of a reasonable length.
100101
*/
101-
#define SXACT_FLAG_CONFLICT_OUT 0x00000008
102-
#define SXACT_FLAG_READ_ONLY 0x00000010
103-
#define SXACT_FLAG_DEFERRABLE_WAITING 0x00000020
104-
#define SXACT_FLAG_RO_SAFE 0x00000040
105-
#define SXACT_FLAG_RO_UNSAFE 0x00000080
106-
#define SXACT_FLAG_SUMMARY_CONFLICT_IN 0x00000100
107-
#define SXACT_FLAG_SUMMARY_CONFLICT_OUT 0x00000200
102+
#define SXACT_FLAG_CONFLICT_OUT 0x00000010
103+
#define SXACT_FLAG_READ_ONLY 0x00000020
104+
#define SXACT_FLAG_DEFERRABLE_WAITING 0x00000040
105+
#define SXACT_FLAG_RO_SAFE 0x00000080
106+
#define SXACT_FLAG_RO_UNSAFE 0x00000100
107+
#define SXACT_FLAG_SUMMARY_CONFLICT_IN 0x00000200
108+
#define SXACT_FLAG_SUMMARY_CONFLICT_OUT 0x00000400
108109

109110
/*
110111
* 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