aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/storage/lmgr/predicate.c21
-rw-r--r--src/include/storage/predicate_internals.h21
2 files changed, 30 insertions, 12 deletions
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index 3678878f03e..8cbca78fb76 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -246,6 +246,7 @@
#define SxactIsCommitted(sxact) (((sxact)->flags & SXACT_FLAG_COMMITTED) != 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 SxactIsReadOnly(sxact) (((sxact)->flags & SXACT_FLAG_READ_ONLY) != 0)
#define SxactHasSummaryConflictIn(sxact) (((sxact)->flags & SXACT_FLAG_SUMMARY_CONFLICT_IN) != 0)
@@ -3046,7 +3047,7 @@ SetNewSxactGlobalXmin(void)
for (sxact = FirstPredXact(); sxact != NULL; sxact = NextPredXact(sxact))
{
- if (!SxactIsDoomed(sxact)
+ if (!SxactIsRolledBack(sxact)
&& !SxactIsCommitted(sxact)
&& sxact != OldCommittedSxact)
{
@@ -3113,6 +3114,7 @@ ReleasePredicateLocks(const bool isCommit)
Assert(!isCommit || SxactIsPrepared(MySerializableXact));
Assert(!isCommit || !SxactIsDoomed(MySerializableXact));
Assert(!SxactIsCommitted(MySerializableXact));
+ Assert(!SxactIsRolledBack(MySerializableXact));
/* may not be serializable during COMMIT/ROLLBACK PREPARED */
if (MySerializableXact->pid != 0)
@@ -3151,7 +3153,22 @@ ReleasePredicateLocks(const bool isCommit)
MySerializableXact->flags |= SXACT_FLAG_READ_ONLY;
}
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_ROLLED_BACK;
+ }
if (!topLevelIsDeclaredReadOnly)
{
@@ -3527,7 +3544,7 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
nextConflict;
Assert(sxact != NULL);
- Assert(SxactIsDoomed(sxact) || SxactIsCommitted(sxact));
+ Assert(SxactIsRolledBack(sxact) || SxactIsCommitted(sxact));
Assert(LWLockHeldByMe(SerializableFinishedListLock));
/*
diff --git a/src/include/storage/predicate_internals.h b/src/include/storage/predicate_internals.h
index 495983f3458..0c90f275d65 100644
--- a/src/include/storage/predicate_internals.h
+++ b/src/include/storage/predicate_internals.h
@@ -90,21 +90,22 @@ typedef struct SERIALIZABLEXACT
int pid; /* pid of associated process */
} SERIALIZABLEXACT;
-#define SXACT_FLAG_COMMITTED 0x00000001 /* already committed */
-#define SXACT_FLAG_PREPARED 0x00000002 /* about to commit */
-#define SXACT_FLAG_DOOMED 0x00000004 /* will roll back */
+#define SXACT_FLAG_COMMITTED 0x00000001 /* already committed */
+#define SXACT_FLAG_PREPARED 0x00000002 /* about to commit */
+#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
* conflict out *to a transaction which committed ahead of it*. It's hard
* to get that into a name of a reasonable length.
*/
-#define SXACT_FLAG_CONFLICT_OUT 0x00000008
-#define SXACT_FLAG_READ_ONLY 0x00000010
-#define SXACT_FLAG_DEFERRABLE_WAITING 0x00000020
-#define SXACT_FLAG_RO_SAFE 0x00000040
-#define SXACT_FLAG_RO_UNSAFE 0x00000080
-#define SXACT_FLAG_SUMMARY_CONFLICT_IN 0x00000100
-#define SXACT_FLAG_SUMMARY_CONFLICT_OUT 0x00000200
+#define SXACT_FLAG_CONFLICT_OUT 0x00000010
+#define SXACT_FLAG_READ_ONLY 0x00000020
+#define SXACT_FLAG_DEFERRABLE_WAITING 0x00000040
+#define SXACT_FLAG_RO_SAFE 0x00000080
+#define SXACT_FLAG_RO_UNSAFE 0x00000100
+#define SXACT_FLAG_SUMMARY_CONFLICT_IN 0x00000200
+#define SXACT_FLAG_SUMMARY_CONFLICT_OUT 0x00000400
/*
* The following types are used to provide an ad hoc list for holding