mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Simplify multixact freezing a bit
Testing for abortedness of a multixact member that's being frozen is unnecessary: we only need to know whether the transaction is still in progress or committed to determine whether it must be kept or not. This let us simplify the code a bit and avoid a useless TransactionIdDidAbort test. Suggested by Andres Freund awhile back.
This commit is contained in:
parent
60d931827b
commit
c2581794f3
@ -5627,17 +5627,13 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* It's an update; should we keep it? If the transaction is known
|
* It's an update; should we keep it? If the transaction is known
|
||||||
* aborted then it's okay to ignore it, otherwise not. However,
|
* aborted or crashed then it's okay to ignore it, otherwise not.
|
||||||
* if the Xid is older than the cutoff_xid, we must remove it.
|
* Note that an updater older than cutoff_xid cannot possibly be
|
||||||
* Note that such an old updater cannot possibly be committed,
|
* committed, because HeapTupleSatisfiesVacuum would have returned
|
||||||
* because HeapTupleSatisfiesVacuum would have returned
|
|
||||||
* HEAPTUPLE_DEAD and we would not be trying to freeze the tuple.
|
* HEAPTUPLE_DEAD and we would not be trying to freeze the tuple.
|
||||||
*
|
*
|
||||||
* Note the TransactionIdDidAbort() test is just an optimization
|
|
||||||
* and not strictly necessary for correctness.
|
|
||||||
*
|
|
||||||
* As with all tuple visibility routines, it's critical to test
|
* As with all tuple visibility routines, it's critical to test
|
||||||
* TransactionIdIsInProgress before the transam.c routines,
|
* TransactionIdIsInProgress before TransactionIdDidCommit,
|
||||||
* because of race conditions explained in detail in tqual.c.
|
* because of race conditions explained in detail in tqual.c.
|
||||||
*/
|
*/
|
||||||
if (TransactionIdIsCurrentTransactionId(xid) ||
|
if (TransactionIdIsCurrentTransactionId(xid) ||
|
||||||
@ -5646,48 +5642,42 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
|
|||||||
Assert(!TransactionIdIsValid(update_xid));
|
Assert(!TransactionIdIsValid(update_xid));
|
||||||
update_xid = xid;
|
update_xid = xid;
|
||||||
}
|
}
|
||||||
else if (!TransactionIdDidAbort(xid))
|
else if (TransactionIdDidCommit(xid))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Test whether to tell caller to set HEAP_XMAX_COMMITTED
|
* The transaction committed, so we can tell caller to set
|
||||||
* while we have the Xid still in cache. Note this can only
|
* HEAP_XMAX_COMMITTED. (We can only do this because we know
|
||||||
* be done if the transaction is known not running.
|
* the transaction is not running.)
|
||||||
*/
|
*/
|
||||||
if (TransactionIdDidCommit(xid))
|
|
||||||
update_committed = true;
|
|
||||||
Assert(!TransactionIdIsValid(update_xid));
|
Assert(!TransactionIdIsValid(update_xid));
|
||||||
|
update_committed = true;
|
||||||
update_xid = xid;
|
update_xid = xid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Not in progress, not committed -- must be aborted or crashed;
|
||||||
|
* we can ignore it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since the tuple wasn't marked HEAPTUPLE_DEAD by vacuum, the
|
||||||
|
* update Xid cannot possibly be older than the xid cutoff.
|
||||||
|
*/
|
||||||
|
Assert(!TransactionIdIsValid(update_xid) ||
|
||||||
|
!TransactionIdPrecedes(update_xid, cutoff_xid));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we determined that it's an Xid corresponding to an update
|
* If we determined that it's an Xid corresponding to an update
|
||||||
* that must be retained, additionally add it to the list of
|
* that must be retained, additionally add it to the list of
|
||||||
* members of the new Multis, in case we end up using that. (We
|
* members of the new Multi, in case we end up using that. (We
|
||||||
* might still decide to use only an update Xid and not a multi,
|
* might still decide to use only an update Xid and not a multi,
|
||||||
* but it's easier to maintain the list as we walk the old members
|
* but it's easier to maintain the list as we walk the old members
|
||||||
* list.)
|
* list.)
|
||||||
*
|
|
||||||
* It is possible to end up with a very old updater Xid that
|
|
||||||
* crashed and thus did not mark itself as aborted in pg_clog.
|
|
||||||
* That would manifest as a pre-cutoff Xid. Make sure to ignore
|
|
||||||
* it.
|
|
||||||
*/
|
*/
|
||||||
if (TransactionIdIsValid(update_xid))
|
if (TransactionIdIsValid(update_xid))
|
||||||
{
|
|
||||||
if (!TransactionIdPrecedes(update_xid, cutoff_xid))
|
|
||||||
{
|
|
||||||
newmembers[nnewmembers++] = members[i];
|
newmembers[nnewmembers++] = members[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
/* cannot have committed: would be HEAPTUPLE_DEAD */
|
|
||||||
Assert(!TransactionIdDidCommit(update_xid));
|
|
||||||
update_xid = InvalidTransactionId;
|
|
||||||
update_committed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* We only keep lockers if they are still running */
|
/* We only keep lockers if they are still running */
|
||||||
if (TransactionIdIsCurrentTransactionId(members[i].xid) ||
|
if (TransactionIdIsCurrentTransactionId(members[i].xid) ||
|
||||||
|
Loading…
x
Reference in New Issue
Block a user