Commit 67f99d21 authored by Tom Lane's avatar Tom Lane

Fix oversight in async-commit patch: there were some places in heapam.c

that still thought they could set HEAP_XMAX_COMMITTED immediately after
seeing the other transaction commit.  Make them use the same logic as
tqual.c does to determine if the hint bit can be set yet.
parent 6ccc262d
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.236 2007/06/09 18:49:54 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.237 2007/08/14 17:35:18 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -1509,6 +1509,34 @@ heap_get_latest_tid(Relation relation, ...@@ -1509,6 +1509,34 @@ heap_get_latest_tid(Relation relation,
} /* end of loop */ } /* end of loop */
} }
/*
* UpdateXmaxHintBits - update tuple hint bits after xmax transaction ends
*
* This is called after we have waited for the XMAX transaction to terminate.
* If the transaction aborted, we guarantee the XMAX_INVALID hint bit will
* be set on exit. If the transaction committed, we set the XMAX_COMMITTED
* hint bit if possible --- but beware that that may not yet be possible,
* if the transaction committed asynchronously. Hence callers should look
* only at XMAX_INVALID.
*/
static void
UpdateXmaxHintBits(HeapTupleHeader tuple, Buffer buffer, TransactionId xid)
{
Assert(TransactionIdEquals(HeapTupleHeaderGetXmax(tuple), xid));
if (!(tuple->t_infomask & (HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID)))
{
if (TransactionIdDidCommit(xid))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
xid);
else
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId);
}
}
/* /*
* heap_insert - insert tuple into a heap * heap_insert - insert tuple into a heap
* *
...@@ -1840,16 +1868,8 @@ l1: ...@@ -1840,16 +1868,8 @@ l1:
xwait)) xwait))
goto l1; goto l1;
/* Otherwise we can mark it committed or aborted */ /* Otherwise check if it committed or aborted */
if (!(tp.t_data->t_infomask & (HEAP_XMAX_COMMITTED | UpdateXmaxHintBits(tp.t_data, buffer, xwait);
HEAP_XMAX_INVALID)))
{
if (TransactionIdDidCommit(xwait))
tp.t_data->t_infomask |= HEAP_XMAX_COMMITTED;
else
tp.t_data->t_infomask |= HEAP_XMAX_INVALID;
SetBufferCommitInfoNeedsSave(buffer);
}
} }
/* /*
...@@ -2164,16 +2184,8 @@ l2: ...@@ -2164,16 +2184,8 @@ l2:
xwait)) xwait))
goto l2; goto l2;
/* Otherwise we can mark it committed or aborted */ /* Otherwise check if it committed or aborted */
if (!(oldtup.t_data->t_infomask & (HEAP_XMAX_COMMITTED | UpdateXmaxHintBits(oldtup.t_data, buffer, xwait);
HEAP_XMAX_INVALID)))
{
if (TransactionIdDidCommit(xwait))
oldtup.t_data->t_infomask |= HEAP_XMAX_COMMITTED;
else
oldtup.t_data->t_infomask |= HEAP_XMAX_INVALID;
SetBufferCommitInfoNeedsSave(buffer);
}
} }
/* /*
...@@ -2713,16 +2725,8 @@ l3: ...@@ -2713,16 +2725,8 @@ l3:
xwait)) xwait))
goto l3; goto l3;
/* Otherwise we can mark it committed or aborted */ /* Otherwise check if it committed or aborted */
if (!(tuple->t_data->t_infomask & (HEAP_XMAX_COMMITTED | UpdateXmaxHintBits(tuple->t_data, *buffer, xwait);
HEAP_XMAX_INVALID)))
{
if (TransactionIdDidCommit(xwait))
tuple->t_data->t_infomask |= HEAP_XMAX_COMMITTED;
else
tuple->t_data->t_infomask |= HEAP_XMAX_INVALID;
SetBufferCommitInfoNeedsSave(*buffer);
}
} }
/* /*
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
* *
* NOTE: all the HeapTupleSatisfies routines will update the tuple's * NOTE: all the HeapTupleSatisfies routines will update the tuple's
* "hint" status bits if we see that the inserting or deleting transaction * "hint" status bits if we see that the inserting or deleting transaction
* has now committed or aborted. If the hint bits are changed, * has now committed or aborted (and it is safe to set the hint bits).
* SetBufferCommitInfoNeedsSave is called on the passed-in buffer. * If the hint bits are changed, SetBufferCommitInfoNeedsSave is called on
* The caller must hold at least a shared buffer context lock on the buffer * the passed-in buffer. The caller must hold not only a pin, but at least
* containing the tuple. * shared buffer content lock on the buffer containing the tuple.
* *
* NOTE: must check TransactionIdIsInProgress (which looks in PGPROC array) * NOTE: must check TransactionIdIsInProgress (which looks in PGPROC array)
* before TransactionIdDidCommit/TransactionIdDidAbort (which look in * before TransactionIdDidCommit/TransactionIdDidAbort (which look in
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.103 2007/08/01 22:45:09 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.104 2007/08/14 17:35:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -81,18 +81,23 @@ static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot); ...@@ -81,18 +81,23 @@ static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot);
/* /*
* HeapTupleSetHintBits() * SetHintBits()
* *
* Set commit/abort hint bits on a tuple, if appropriate at this time. * Set commit/abort hint bits on a tuple, if appropriate at this time.
* *
* We cannot change the LSN of the page here because we may hold only a share * It is only safe to set a transaction-committed hint bit if we know the
* lock on the buffer, so it is only safe to set a transaction-committed hint * transaction's commit record has been flushed to disk. We cannot change
* bit if we know the transaction's commit record has been flushed to disk. * the LSN of the page here because we may hold only a share lock on the
* buffer, so we can't use the LSN to interlock this; we have to just refrain
* from setting the hint bit until some future re-examination of the tuple.
* *
* We can always set hint bits when marking a transaction aborted. Also, * We can always set hint bits when marking a transaction aborted. (Some
* if we are cleaning up HEAP_MOVED_IN or HEAP_MOVED_OFF entries, then * code in heapam.c relies on that!)
*
* Also, if we are cleaning up HEAP_MOVED_IN or HEAP_MOVED_OFF entries, then
* we can always set the hint bits, since VACUUM FULL always uses synchronous * we can always set the hint bits, since VACUUM FULL always uses synchronous
* commits. * commits and doesn't move tuples that weren't previously hinted. (This is
* not known by this subroutine, but is applied by its callers.)
* *
* Normal commits may be asynchronous, so for those we need to get the LSN * Normal commits may be asynchronous, so for those we need to get the LSN
* of the transaction and then check whether this is flushed. * of the transaction and then check whether this is flushed.
...@@ -101,8 +106,8 @@ static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot); ...@@ -101,8 +106,8 @@ static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot);
* InvalidTransactionId if no check is needed. * InvalidTransactionId if no check is needed.
*/ */
static inline void static inline void
HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer, SetHintBits(HeapTupleHeader tuple, Buffer buffer,
uint16 infomask, TransactionId xid) uint16 infomask, TransactionId xid)
{ {
if (TransactionIdIsValid(xid)) if (TransactionIdIsValid(xid))
{ {
...@@ -117,6 +122,19 @@ HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer, ...@@ -117,6 +122,19 @@ HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
SetBufferCommitInfoNeedsSave(buffer); SetBufferCommitInfoNeedsSave(buffer);
} }
/*
* HeapTupleSetHintBits --- exported version of SetHintBits()
*
* This must be separate because of C99's brain-dead notions about how to
* implement inline functions.
*/
void
HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
uint16 infomask, TransactionId xid)
{
SetHintBits(tuple, buffer, infomask, xid);
}
/* /*
* HeapTupleSatisfiesSelf * HeapTupleSatisfiesSelf
...@@ -160,12 +178,12 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) ...@@ -160,12 +178,12 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
{ {
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
} }
} }
else if (tuple->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
...@@ -177,12 +195,12 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) ...@@ -177,12 +195,12 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
if (TransactionIdIsInProgress(xvac)) if (TransactionIdIsInProgress(xvac))
return false; return false;
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
else else
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
} }
...@@ -200,8 +218,8 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) ...@@ -200,8 +218,8 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
/* deleting subtransaction aborted? */ /* deleting subtransaction aborted? */
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple))) if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return true; return true;
} }
...@@ -212,13 +230,13 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) ...@@ -212,13 +230,13 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple))) else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
return false; return false;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple))) else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
HeapTupleHeaderGetXmin(tuple)); HeapTupleHeaderGetXmin(tuple));
else else
{ {
/* it must have aborted or crashed */ /* it must have aborted or crashed */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
} }
...@@ -255,8 +273,8 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) ...@@ -255,8 +273,8 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple))) if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
{ {
/* it must have aborted or crashed */ /* it must have aborted or crashed */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return true; return true;
} }
...@@ -264,13 +282,13 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) ...@@ -264,13 +282,13 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
if (tuple->t_infomask & HEAP_IS_LOCKED) if (tuple->t_infomask & HEAP_IS_LOCKED)
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return true; return true;
} }
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
HeapTupleHeaderGetXmax(tuple)); HeapTupleHeaderGetXmax(tuple));
return false; return false;
} }
...@@ -333,12 +351,12 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) ...@@ -333,12 +351,12 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
{ {
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
} }
} }
else if (tuple->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
...@@ -350,12 +368,12 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) ...@@ -350,12 +368,12 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
if (TransactionIdIsInProgress(xvac)) if (TransactionIdIsInProgress(xvac))
return false; return false;
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
else else
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
} }
...@@ -376,8 +394,8 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) ...@@ -376,8 +394,8 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
/* deleting subtransaction aborted? */ /* deleting subtransaction aborted? */
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple))) if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return true; return true;
} }
...@@ -391,13 +409,13 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) ...@@ -391,13 +409,13 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple))) else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
return false; return false;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple))) else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
HeapTupleHeaderGetXmin(tuple)); HeapTupleHeaderGetXmin(tuple));
else else
{ {
/* it must have aborted or crashed */ /* it must have aborted or crashed */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
} }
...@@ -437,8 +455,8 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) ...@@ -437,8 +455,8 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple))) if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
{ {
/* it must have aborted or crashed */ /* it must have aborted or crashed */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return true; return true;
} }
...@@ -446,13 +464,13 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer) ...@@ -446,13 +464,13 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
if (tuple->t_infomask & HEAP_IS_LOCKED) if (tuple->t_infomask & HEAP_IS_LOCKED)
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return true; return true;
} }
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
HeapTupleHeaderGetXmax(tuple)); HeapTupleHeaderGetXmax(tuple));
return false; return false;
} }
...@@ -499,12 +517,12 @@ HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -499,12 +517,12 @@ HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot,
{ {
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
} }
} }
else if (tuple->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
...@@ -516,12 +534,12 @@ HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -516,12 +534,12 @@ HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot,
if (TransactionIdIsInProgress(xvac)) if (TransactionIdIsInProgress(xvac))
return false; return false;
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
else else
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
} }
...@@ -578,12 +596,12 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid, ...@@ -578,12 +596,12 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
{ {
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return HeapTupleInvisible; return HeapTupleInvisible;
} }
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
} }
} }
else if (tuple->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
...@@ -595,12 +613,12 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid, ...@@ -595,12 +613,12 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
if (TransactionIdIsInProgress(xvac)) if (TransactionIdIsInProgress(xvac))
return HeapTupleInvisible; return HeapTupleInvisible;
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
else else
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return HeapTupleInvisible; return HeapTupleInvisible;
} }
} }
...@@ -621,8 +639,8 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid, ...@@ -621,8 +639,8 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
/* deleting subtransaction aborted? */ /* deleting subtransaction aborted? */
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple))) if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
} }
...@@ -636,13 +654,13 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid, ...@@ -636,13 +654,13 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple))) else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
return HeapTupleInvisible; return HeapTupleInvisible;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple))) else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
HeapTupleHeaderGetXmin(tuple)); HeapTupleHeaderGetXmin(tuple));
else else
{ {
/* it must have aborted or crashed */ /* it must have aborted or crashed */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return HeapTupleInvisible; return HeapTupleInvisible;
} }
} }
...@@ -666,8 +684,8 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid, ...@@ -666,8 +684,8 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
if (MultiXactIdIsRunning(HeapTupleHeaderGetXmax(tuple))) if (MultiXactIdIsRunning(HeapTupleHeaderGetXmax(tuple)))
return HeapTupleBeingUpdated; return HeapTupleBeingUpdated;
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
} }
...@@ -687,8 +705,8 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid, ...@@ -687,8 +705,8 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple))) if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
{ {
/* it must have aborted or crashed */ /* it must have aborted or crashed */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
} }
...@@ -696,13 +714,13 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid, ...@@ -696,13 +714,13 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
if (tuple->t_infomask & HEAP_IS_LOCKED) if (tuple->t_infomask & HEAP_IS_LOCKED)
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return HeapTupleMayBeUpdated; return HeapTupleMayBeUpdated;
} }
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
HeapTupleHeaderGetXmax(tuple)); HeapTupleHeaderGetXmax(tuple));
return HeapTupleUpdated; /* updated by other */ return HeapTupleUpdated; /* updated by other */
} }
...@@ -747,12 +765,12 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -747,12 +765,12 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
{ {
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
} }
} }
else if (tuple->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
...@@ -764,12 +782,12 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -764,12 +782,12 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
if (TransactionIdIsInProgress(xvac)) if (TransactionIdIsInProgress(xvac))
return false; return false;
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
else else
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
} }
...@@ -787,8 +805,8 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -787,8 +805,8 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
/* deleting subtransaction aborted? */ /* deleting subtransaction aborted? */
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple))) if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return true; return true;
} }
...@@ -803,13 +821,13 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -803,13 +821,13 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
return true; /* in insertion by other */ return true; /* in insertion by other */
} }
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple))) else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
HeapTupleHeaderGetXmin(tuple)); HeapTupleHeaderGetXmin(tuple));
else else
{ {
/* it must have aborted or crashed */ /* it must have aborted or crashed */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
} }
...@@ -849,8 +867,8 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -849,8 +867,8 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple))) if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
{ {
/* it must have aborted or crashed */ /* it must have aborted or crashed */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return true; return true;
} }
...@@ -858,13 +876,13 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -858,13 +876,13 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
if (tuple->t_infomask & HEAP_IS_LOCKED) if (tuple->t_infomask & HEAP_IS_LOCKED)
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return true; return true;
} }
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
HeapTupleHeaderGetXmax(tuple)); HeapTupleHeaderGetXmax(tuple));
return false; /* updated by other */ return false; /* updated by other */
} }
...@@ -908,12 +926,12 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -908,12 +926,12 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
{ {
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
} }
} }
else if (tuple->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
...@@ -925,12 +943,12 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -925,12 +943,12 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
if (TransactionIdIsInProgress(xvac)) if (TransactionIdIsInProgress(xvac))
return false; return false;
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
else else
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
} }
...@@ -952,8 +970,8 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -952,8 +970,8 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
/* FIXME -- is this correct w.r.t. the cmax of the tuple? */ /* FIXME -- is this correct w.r.t. the cmax of the tuple? */
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple))) if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return true; return true;
} }
...@@ -967,13 +985,13 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -967,13 +985,13 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple))) else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
return false; return false;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple))) else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
HeapTupleHeaderGetXmin(tuple)); HeapTupleHeaderGetXmin(tuple));
else else
{ {
/* it must have aborted or crashed */ /* it must have aborted or crashed */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return false; return false;
} }
} }
...@@ -1014,14 +1032,14 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot, ...@@ -1014,14 +1032,14 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple))) if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
{ {
/* it must have aborted or crashed */ /* it must have aborted or crashed */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return true; return true;
} }
/* xmax transaction committed */ /* xmax transaction committed */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
HeapTupleHeaderGetXmax(tuple)); HeapTupleHeaderGetXmax(tuple));
} }
/* /*
...@@ -1070,12 +1088,12 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin, ...@@ -1070,12 +1088,12 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
return HEAPTUPLE_DELETE_IN_PROGRESS; return HEAPTUPLE_DELETE_IN_PROGRESS;
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return HEAPTUPLE_DEAD; return HEAPTUPLE_DEAD;
} }
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
} }
else if (tuple->t_infomask & HEAP_MOVED_IN) else if (tuple->t_infomask & HEAP_MOVED_IN)
{ {
...@@ -1086,12 +1104,12 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin, ...@@ -1086,12 +1104,12 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
if (TransactionIdIsInProgress(xvac)) if (TransactionIdIsInProgress(xvac))
return HEAPTUPLE_INSERT_IN_PROGRESS; return HEAPTUPLE_INSERT_IN_PROGRESS;
if (TransactionIdDidCommit(xvac)) if (TransactionIdDidCommit(xvac))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
InvalidTransactionId); InvalidTransactionId);
else else
{ {
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return HEAPTUPLE_DEAD; return HEAPTUPLE_DEAD;
} }
} }
...@@ -1105,15 +1123,15 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin, ...@@ -1105,15 +1123,15 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
return HEAPTUPLE_DELETE_IN_PROGRESS; return HEAPTUPLE_DELETE_IN_PROGRESS;
} }
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple))) else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
HeapTupleHeaderGetXmin(tuple)); HeapTupleHeaderGetXmin(tuple));
else else
{ {
/* /*
* Not in Progress, Not Committed, so either Aborted or crashed * Not in Progress, Not Committed, so either Aborted or crashed
*/ */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID, SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
InvalidTransactionId); InvalidTransactionId);
return HEAPTUPLE_DEAD; return HEAPTUPLE_DEAD;
} }
/* /*
...@@ -1158,8 +1176,8 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin, ...@@ -1158,8 +1176,8 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
* We know that xmax did lock the tuple, but it did not and will * We know that xmax did lock the tuple, but it did not and will
* never actually update it. * never actually update it.
*/ */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
} }
return HEAPTUPLE_LIVE; return HEAPTUPLE_LIVE;
} }
...@@ -1176,15 +1194,15 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin, ...@@ -1176,15 +1194,15 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
if (TransactionIdIsInProgress(HeapTupleHeaderGetXmax(tuple))) if (TransactionIdIsInProgress(HeapTupleHeaderGetXmax(tuple)))
return HEAPTUPLE_DELETE_IN_PROGRESS; return HEAPTUPLE_DELETE_IN_PROGRESS;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple))) else if (TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED, SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
HeapTupleHeaderGetXmax(tuple)); HeapTupleHeaderGetXmax(tuple));
else else
{ {
/* /*
* Not in Progress, Not Committed, so either Aborted or crashed * Not in Progress, Not Committed, so either Aborted or crashed
*/ */
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID, SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId); InvalidTransactionId);
return HEAPTUPLE_LIVE; return HEAPTUPLE_LIVE;
} }
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/tqual.h,v 1.67 2007/07/25 12:22:54 mha Exp $ * $PostgreSQL: pgsql/src/include/utils/tqual.h,v 1.68 2007/08/14 17:35:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -145,6 +145,9 @@ extern HTSU_Result HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, ...@@ -145,6 +145,9 @@ extern HTSU_Result HeapTupleSatisfiesUpdate(HeapTupleHeader tuple,
extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple,
TransactionId OldestXmin, Buffer buffer); TransactionId OldestXmin, Buffer buffer);
extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
uint16 infomask, TransactionId xid);
extern Snapshot GetTransactionSnapshot(void); extern Snapshot GetTransactionSnapshot(void);
extern Snapshot GetLatestSnapshot(void); extern Snapshot GetLatestSnapshot(void);
extern Snapshot CopySnapshot(Snapshot snapshot); extern Snapshot CopySnapshot(Snapshot snapshot);
......
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