mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
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.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@ -1509,6 +1509,34 @@ heap_get_latest_tid(Relation relation,
|
||||
} /* 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
|
||||
*
|
||||
@ -1840,16 +1868,8 @@ l1:
|
||||
xwait))
|
||||
goto l1;
|
||||
|
||||
/* Otherwise we can mark it committed or aborted */
|
||||
if (!(tp.t_data->t_infomask & (HEAP_XMAX_COMMITTED |
|
||||
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);
|
||||
}
|
||||
/* Otherwise check if it committed or aborted */
|
||||
UpdateXmaxHintBits(tp.t_data, buffer, xwait);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2164,16 +2184,8 @@ l2:
|
||||
xwait))
|
||||
goto l2;
|
||||
|
||||
/* Otherwise we can mark it committed or aborted */
|
||||
if (!(oldtup.t_data->t_infomask & (HEAP_XMAX_COMMITTED |
|
||||
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);
|
||||
}
|
||||
/* Otherwise check if it committed or aborted */
|
||||
UpdateXmaxHintBits(oldtup.t_data, buffer, xwait);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2713,16 +2725,8 @@ l3:
|
||||
xwait))
|
||||
goto l3;
|
||||
|
||||
/* Otherwise we can mark it committed or aborted */
|
||||
if (!(tuple->t_data->t_infomask & (HEAP_XMAX_COMMITTED |
|
||||
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);
|
||||
}
|
||||
/* Otherwise check if it committed or aborted */
|
||||
UpdateXmaxHintBits(tuple->t_data, *buffer, xwait);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -5,10 +5,10 @@
|
||||
*
|
||||
* NOTE: all the HeapTupleSatisfies routines will update the tuple's
|
||||
* "hint" status bits if we see that the inserting or deleting transaction
|
||||
* has now committed or aborted. If the hint bits are changed,
|
||||
* SetBufferCommitInfoNeedsSave is called on the passed-in buffer.
|
||||
* The caller must hold at least a shared buffer context lock on the buffer
|
||||
* containing the tuple.
|
||||
* has now committed or aborted (and it is safe to set the hint bits).
|
||||
* If the hint bits are changed, SetBufferCommitInfoNeedsSave is called on
|
||||
* the passed-in buffer. The caller must hold not only a pin, but at least
|
||||
* shared buffer content lock on the buffer containing the tuple.
|
||||
*
|
||||
* NOTE: must check TransactionIdIsInProgress (which looks in PGPROC array)
|
||||
* before TransactionIdDidCommit/TransactionIdDidAbort (which look in
|
||||
@ -31,7 +31,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* 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);
|
||||
|
||||
|
||||
/*
|
||||
* HeapTupleSetHintBits()
|
||||
* SetHintBits()
|
||||
*
|
||||
* 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
|
||||
* lock on the buffer, so it is only safe to set a transaction-committed hint
|
||||
* bit if we know the transaction's commit record has been flushed to disk.
|
||||
* It is only safe to set a transaction-committed hint bit if we know the
|
||||
* transaction's commit record has been flushed to disk. We cannot change
|
||||
* 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,
|
||||
* if we are cleaning up HEAP_MOVED_IN or HEAP_MOVED_OFF entries, then
|
||||
* We can always set hint bits when marking a transaction aborted. (Some
|
||||
* 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
|
||||
* 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
|
||||
* of the transaction and then check whether this is flushed.
|
||||
@ -101,8 +106,8 @@ static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot);
|
||||
* InvalidTransactionId if no check is needed.
|
||||
*/
|
||||
static inline void
|
||||
HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
|
||||
uint16 infomask, TransactionId xid)
|
||||
SetHintBits(HeapTupleHeader tuple, Buffer buffer,
|
||||
uint16 infomask, TransactionId xid)
|
||||
{
|
||||
if (TransactionIdIsValid(xid))
|
||||
{
|
||||
@ -117,6 +122,19 @@ HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer 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
|
||||
@ -160,12 +178,12 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
{
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
@ -177,12 +195,12 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return false;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -200,8 +218,8 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
/* deleting subtransaction aborted? */
|
||||
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -212,13 +230,13 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
|
||||
return false;
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
else
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -255,8 +273,8 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -264,13 +282,13 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
|
||||
if (tuple->t_infomask & HEAP_IS_LOCKED)
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -333,12 +351,12 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
{
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
@ -350,12 +368,12 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return false;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -376,8 +394,8 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
/* deleting subtransaction aborted? */
|
||||
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -391,13 +409,13 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
|
||||
return false;
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
else
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -437,8 +455,8 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -446,13 +464,13 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
|
||||
if (tuple->t_infomask & HEAP_IS_LOCKED)
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -499,12 +517,12 @@ HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
{
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
@ -516,12 +534,12 @@ HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return false;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -578,12 +596,12 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
{
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleInvisible;
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
@ -595,12 +613,12 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return HeapTupleInvisible;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleInvisible;
|
||||
}
|
||||
}
|
||||
@ -621,8 +639,8 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
/* deleting subtransaction aborted? */
|
||||
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleMayBeUpdated;
|
||||
}
|
||||
|
||||
@ -636,13 +654,13 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
|
||||
return HeapTupleInvisible;
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
else
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleInvisible;
|
||||
}
|
||||
}
|
||||
@ -666,8 +684,8 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
|
||||
if (MultiXactIdIsRunning(HeapTupleHeaderGetXmax(tuple)))
|
||||
return HeapTupleBeingUpdated;
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleMayBeUpdated;
|
||||
}
|
||||
|
||||
@ -687,8 +705,8 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleMayBeUpdated;
|
||||
}
|
||||
|
||||
@ -696,13 +714,13 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
|
||||
if (tuple->t_infomask & HEAP_IS_LOCKED)
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleMayBeUpdated;
|
||||
}
|
||||
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
return HeapTupleUpdated; /* updated by other */
|
||||
}
|
||||
|
||||
@ -747,12 +765,12 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
{
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
@ -764,12 +782,12 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return false;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -787,8 +805,8 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
/* deleting subtransaction aborted? */
|
||||
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -803,13 +821,13 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
return true; /* in insertion by other */
|
||||
}
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
else
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -849,8 +867,8 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -858,13 +876,13 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
|
||||
if (tuple->t_infomask & HEAP_IS_LOCKED)
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
return false; /* updated by other */
|
||||
}
|
||||
|
||||
@ -908,12 +926,12 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
{
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
@ -925,12 +943,12 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return false;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -952,8 +970,8 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
/* FIXME -- is this correct w.r.t. the cmax of the tuple? */
|
||||
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -967,13 +985,13 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
|
||||
return false;
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
else
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1014,14 +1032,14 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* xmax transaction committed */
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1070,12 +1088,12 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
|
||||
return HEAPTUPLE_DELETE_IN_PROGRESS;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HEAPTUPLE_DEAD;
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
{
|
||||
@ -1086,12 +1104,12 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return HEAPTUPLE_INSERT_IN_PROGRESS;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HEAPTUPLE_DEAD;
|
||||
}
|
||||
}
|
||||
@ -1105,15 +1123,15 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
|
||||
return HEAPTUPLE_DELETE_IN_PROGRESS;
|
||||
}
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Not in Progress, Not Committed, so either Aborted or crashed
|
||||
*/
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HEAPTUPLE_DEAD;
|
||||
}
|
||||
/*
|
||||
@ -1158,8 +1176,8 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
|
||||
* We know that xmax did lock the tuple, but it did not and will
|
||||
* never actually update it.
|
||||
*/
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
return HEAPTUPLE_LIVE;
|
||||
}
|
||||
@ -1176,15 +1194,15 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
|
||||
if (TransactionIdIsInProgress(HeapTupleHeaderGetXmax(tuple)))
|
||||
return HEAPTUPLE_DELETE_IN_PROGRESS;
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Not in Progress, Not Committed, so either Aborted or crashed
|
||||
*/
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HEAPTUPLE_LIVE;
|
||||
}
|
||||
/*
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
* 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,
|
||||
extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple,
|
||||
TransactionId OldestXmin, Buffer buffer);
|
||||
|
||||
extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
|
||||
uint16 infomask, TransactionId xid);
|
||||
|
||||
extern Snapshot GetTransactionSnapshot(void);
|
||||
extern Snapshot GetLatestSnapshot(void);
|
||||
extern Snapshot CopySnapshot(Snapshot snapshot);
|
||||
|
Reference in New Issue
Block a user