summaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2001-07-16 22:43:34 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2001-07-16 22:43:34 +0000
commited5c4e4a14e9f9f4b818521b943bace0d5cd1e01 (patch)
tree5604b1a45b9f52df7e6d278a6b88f38b1dbfb633 /src/backend/utils
parentffbd97c8ac4bb9ebfdc63e4b2156c2b263dd0786 (diff)
downloadpostgresql-ed5c4e4a14e9f9f4b818521b943bace0d5cd1e01.tar.gz
Improve documentation about reasoning behind the order of operations
in GetSnapshotData, GetNewTransactionId, CommitTransaction, AbortTransaction, etc. Correct race condition in transaction status testing in HeapTupleSatisfiesVacuum --- this wasn't important for old VACUUM with exclusive lock on its table, but it sure is important now. All per pghackers discussion 7/11/01 and 7/12/01.
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/time/tqual.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c
index 2dd56b6f08..35113a3622 100644
--- a/src/backend/utils/time/tqual.c
+++ b/src/backend/utils/time/tqual.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.38 2001/07/12 04:11:13 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.39 2001/07/16 22:43:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -610,6 +610,13 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId XmaxRecent)
*
* If the inserting transaction aborted, then the tuple was never visible
* to any other transaction, so we can delete it immediately.
+ *
+ * NOTE: must check TransactionIdIsInProgress (which looks in shared mem)
+ * before TransactionIdDidCommit/TransactionIdDidAbort (which look in
+ * pg_log). Otherwise we have a race condition where we might decide
+ * that a just-committed transaction crashed, because none of the tests
+ * succeed. xact.c is careful to record commit/abort in pg_log before
+ * it unsets MyProc->xid in shared memory.
*/
if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
{
@@ -636,19 +643,19 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId XmaxRecent)
}
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
+ else if (TransactionIdIsInProgress(tuple->t_xmin))
+ return HEAPTUPLE_INSERT_IN_PROGRESS;
+ else if (TransactionIdDidCommit(tuple->t_xmin))
+ tuple->t_infomask |= HEAP_XMIN_COMMITTED;
else if (TransactionIdDidAbort(tuple->t_xmin))
{
tuple->t_infomask |= HEAP_XMIN_INVALID;
return HEAPTUPLE_DEAD;
}
- else if (TransactionIdDidCommit(tuple->t_xmin))
- tuple->t_infomask |= HEAP_XMIN_COMMITTED;
- else if (TransactionIdIsInProgress(tuple->t_xmin))
- return HEAPTUPLE_INSERT_IN_PROGRESS;
else
{
/*
- * Not Aborted, Not Committed, Not in Progress -
+ * Not in Progress, Not Committed, Not Aborted -
* so it's from crashed process. - vadim 11/26/96
*/
tuple->t_infomask |= HEAP_XMIN_INVALID;
@@ -667,19 +674,19 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId XmaxRecent)
if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
{
- if (TransactionIdDidAbort(tuple->t_xmax))
+ if (TransactionIdIsInProgress(tuple->t_xmax))
+ return HEAPTUPLE_DELETE_IN_PROGRESS;
+ else if (TransactionIdDidCommit(tuple->t_xmax))
+ tuple->t_infomask |= HEAP_XMAX_COMMITTED;
+ else if (TransactionIdDidAbort(tuple->t_xmax))
{
tuple->t_infomask |= HEAP_XMAX_INVALID;
return HEAPTUPLE_LIVE;
}
- else if (TransactionIdDidCommit(tuple->t_xmax))
- tuple->t_infomask |= HEAP_XMAX_COMMITTED;
- else if (TransactionIdIsInProgress(tuple->t_xmax))
- return HEAPTUPLE_DELETE_IN_PROGRESS;
else
{
/*
- * Not Aborted, Not Committed, Not in Progress -
+ * Not in Progress, Not Committed, Not Aborted -
* so it's from crashed process. - vadim 06/02/97
*/
tuple->t_infomask |= HEAP_XMAX_INVALID;