Commit 7cb2ff96 authored by Heikki Linnakangas's avatar Heikki Linnakangas

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
parent 31e8ab4d
...@@ -246,6 +246,7 @@ ...@@ -246,6 +246,7 @@
#define SxactIsCommitted(sxact) (((sxact)->flags & SXACT_FLAG_COMMITTED) != 0) #define SxactIsCommitted(sxact) (((sxact)->flags & SXACT_FLAG_COMMITTED) != 0)
#define SxactIsPrepared(sxact) (((sxact)->flags & SXACT_FLAG_PREPARED) != 0) #define SxactIsPrepared(sxact) (((sxact)->flags & SXACT_FLAG_PREPARED) != 0)
#define SxactIsRolledBack(sxact) (((sxact)->flags & SXACT_FLAG_ROLLED_BACK) != 0)
#define SxactIsDoomed(sxact) (((sxact)->flags & SXACT_FLAG_DOOMED) != 0) #define SxactIsDoomed(sxact) (((sxact)->flags & SXACT_FLAG_DOOMED) != 0)
#define SxactIsReadOnly(sxact) (((sxact)->flags & SXACT_FLAG_READ_ONLY) != 0) #define SxactIsReadOnly(sxact) (((sxact)->flags & SXACT_FLAG_READ_ONLY) != 0)
#define SxactHasSummaryConflictIn(sxact) (((sxact)->flags & SXACT_FLAG_SUMMARY_CONFLICT_IN) != 0) #define SxactHasSummaryConflictIn(sxact) (((sxact)->flags & SXACT_FLAG_SUMMARY_CONFLICT_IN) != 0)
...@@ -3046,7 +3047,7 @@ SetNewSxactGlobalXmin(void) ...@@ -3046,7 +3047,7 @@ SetNewSxactGlobalXmin(void)
for (sxact = FirstPredXact(); sxact != NULL; sxact = NextPredXact(sxact)) for (sxact = FirstPredXact(); sxact != NULL; sxact = NextPredXact(sxact))
{ {
if (!SxactIsDoomed(sxact) if (!SxactIsRolledBack(sxact)
&& !SxactIsCommitted(sxact) && !SxactIsCommitted(sxact)
&& sxact != OldCommittedSxact) && sxact != OldCommittedSxact)
{ {
...@@ -3113,6 +3114,7 @@ ReleasePredicateLocks(const bool isCommit) ...@@ -3113,6 +3114,7 @@ ReleasePredicateLocks(const bool isCommit)
Assert(!isCommit || SxactIsPrepared(MySerializableXact)); Assert(!isCommit || SxactIsPrepared(MySerializableXact));
Assert(!isCommit || !SxactIsDoomed(MySerializableXact)); Assert(!isCommit || !SxactIsDoomed(MySerializableXact));
Assert(!SxactIsCommitted(MySerializableXact)); Assert(!SxactIsCommitted(MySerializableXact));
Assert(!SxactIsRolledBack(MySerializableXact));
/* may not be serializable during COMMIT/ROLLBACK PREPARED */ /* may not be serializable during COMMIT/ROLLBACK PREPARED */
if (MySerializableXact->pid != 0) if (MySerializableXact->pid != 0)
...@@ -3151,7 +3153,22 @@ ReleasePredicateLocks(const bool isCommit) ...@@ -3151,7 +3153,22 @@ ReleasePredicateLocks(const bool isCommit)
MySerializableXact->flags |= SXACT_FLAG_READ_ONLY; MySerializableXact->flags |= SXACT_FLAG_READ_ONLY;
} }
else else
{
/*
* The DOOMED flag indicates that we intend to roll back this
* transaction and so it should not cause serialization failures for
* other transactions that conflict with it. Note that this flag might
* already be set, if another backend marked this transaction for
* abort.
*
* The ROLLED_BACK flag further indicates that ReleasePredicateLocks
* has been called, and so the SerializableXact is eligible for
* cleanup. This means it should not be considered when calculating
* SxactGlobalXmin.
*/
MySerializableXact->flags |= SXACT_FLAG_DOOMED; MySerializableXact->flags |= SXACT_FLAG_DOOMED;
MySerializableXact->flags |= SXACT_FLAG_ROLLED_BACK;
}
if (!topLevelIsDeclaredReadOnly) if (!topLevelIsDeclaredReadOnly)
{ {
...@@ -3527,7 +3544,7 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial, ...@@ -3527,7 +3544,7 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
nextConflict; nextConflict;
Assert(sxact != NULL); Assert(sxact != NULL);
Assert(SxactIsDoomed(sxact) || SxactIsCommitted(sxact)); Assert(SxactIsRolledBack(sxact) || SxactIsCommitted(sxact));
Assert(LWLockHeldByMe(SerializableFinishedListLock)); Assert(LWLockHeldByMe(SerializableFinishedListLock));
/* /*
......
...@@ -90,21 +90,22 @@ typedef struct SERIALIZABLEXACT ...@@ -90,21 +90,22 @@ typedef struct SERIALIZABLEXACT
int pid; /* pid of associated process */ int pid; /* pid of associated process */
} SERIALIZABLEXACT; } SERIALIZABLEXACT;
#define SXACT_FLAG_COMMITTED 0x00000001 /* already committed */ #define SXACT_FLAG_COMMITTED 0x00000001 /* already committed */
#define SXACT_FLAG_PREPARED 0x00000002 /* about to commit */ #define SXACT_FLAG_PREPARED 0x00000002 /* about to commit */
#define SXACT_FLAG_DOOMED 0x00000004 /* will roll back */ #define SXACT_FLAG_ROLLED_BACK 0x00000004 /* already rolled back */
#define SXACT_FLAG_DOOMED 0x00000008 /* will roll back */
/* /*
* The following flag actually means that the flagged transaction has a * The following flag actually means that the flagged transaction has a
* conflict out *to a transaction which committed ahead of it*. It's hard * conflict out *to a transaction which committed ahead of it*. It's hard
* to get that into a name of a reasonable length. * to get that into a name of a reasonable length.
*/ */
#define SXACT_FLAG_CONFLICT_OUT 0x00000008 #define SXACT_FLAG_CONFLICT_OUT 0x00000010
#define SXACT_FLAG_READ_ONLY 0x00000010 #define SXACT_FLAG_READ_ONLY 0x00000020
#define SXACT_FLAG_DEFERRABLE_WAITING 0x00000020 #define SXACT_FLAG_DEFERRABLE_WAITING 0x00000040
#define SXACT_FLAG_RO_SAFE 0x00000040 #define SXACT_FLAG_RO_SAFE 0x00000080
#define SXACT_FLAG_RO_UNSAFE 0x00000080 #define SXACT_FLAG_RO_UNSAFE 0x00000100
#define SXACT_FLAG_SUMMARY_CONFLICT_IN 0x00000100 #define SXACT_FLAG_SUMMARY_CONFLICT_IN 0x00000200
#define SXACT_FLAG_SUMMARY_CONFLICT_OUT 0x00000200 #define SXACT_FLAG_SUMMARY_CONFLICT_OUT 0x00000400
/* /*
* The following types are used to provide an ad hoc list for holding * The following types are used to provide an ad hoc list for holding
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment