summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/xid8funcs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/xid8funcs.c')
-rw-r--r--src/backend/utils/adt/xid8funcs.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/src/backend/utils/adt/xid8funcs.c b/src/backend/utils/adt/xid8funcs.c
index cc2b4ac7979..d0e236ee3cc 100644
--- a/src/backend/utils/adt/xid8funcs.c
+++ b/src/backend/utils/adt/xid8funcs.c
@@ -36,6 +36,7 @@
#include "miscadmin.h"
#include "postmaster/postmaster.h"
#include "storage/lwlock.h"
+#include "storage/procarray.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/snapmgr.h"
@@ -677,29 +678,22 @@ pg_xact_status(PG_FUNCTION_ARGS)
{
Assert(TransactionIdIsValid(xid));
- if (TransactionIdIsCurrentTransactionId(xid))
+ /*
+ * Like when doing visiblity checks on a row, check whether the
+ * transaction is still in progress before looking into the CLOG.
+ * Otherwise we would incorrectly return "committed" for a transaction
+ * that is committing and has already updated the CLOG, but hasn't
+ * removed its XID from the proc array yet. (See comment on that race
+ * condition at the top of heapam_visibility.c)
+ */
+ if (TransactionIdIsInProgress(xid))
status = "in progress";
else if (TransactionIdDidCommit(xid))
status = "committed";
- else if (TransactionIdDidAbort(xid))
- status = "aborted";
else
{
- /*
- * The xact is not marked as either committed or aborted in clog.
- *
- * It could be a transaction that ended without updating clog or
- * writing an abort record due to a crash. We can safely assume
- * it's aborted if it isn't committed and is older than our
- * snapshot xmin.
- *
- * Otherwise it must be in-progress (or have been at the time we
- * checked commit/abort status).
- */
- if (TransactionIdPrecedes(xid, GetActiveSnapshot()->xmin))
- status = "aborted";
- else
- status = "in progress";
+ /* it must have aborted or crashed */
+ status = "aborted";
}
}
else