@@ -5627,17 +5627,13 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
5627
5627
5628
5628
/*
5629
5629
* It's an update; should we keep it? If the transaction is known
5630
- * aborted then it's okay to ignore it, otherwise not. However,
5631
- * if the Xid is older than the cutoff_xid, we must remove it.
5632
- * Note that such an old updater cannot possibly be committed,
5633
- * because HeapTupleSatisfiesVacuum would have returned
5630
+ * aborted or crashed then it's okay to ignore it, otherwise not.
5631
+ * Note that an updater older than cutoff_xid cannot possibly be
5632
+ * committed, because HeapTupleSatisfiesVacuum would have returned
5634
5633
* HEAPTUPLE_DEAD and we would not be trying to freeze the tuple.
5635
5634
*
5636
- * Note the TransactionIdDidAbort() test is just an optimization
5637
- * and not strictly necessary for correctness.
5638
- *
5639
5635
* As with all tuple visibility routines, it's critical to test
5640
- * TransactionIdIsInProgress before the transam.c routines ,
5636
+ * TransactionIdIsInProgress before TransactionIdDidCommit ,
5641
5637
* because of race conditions explained in detail in tqual.c.
5642
5638
*/
5643
5639
if (TransactionIdIsCurrentTransactionId (xid ) ||
@@ -5646,46 +5642,40 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
5646
5642
Assert (!TransactionIdIsValid (update_xid ));
5647
5643
update_xid = xid ;
5648
5644
}
5649
- else if (! TransactionIdDidAbort (xid ))
5645
+ else if (TransactionIdDidCommit (xid ))
5650
5646
{
5651
5647
/*
5652
- * Test whether to tell caller to set HEAP_XMAX_COMMITTED
5653
- * while we have the Xid still in cache. Note this can only
5654
- * be done if the transaction is known not running.
5648
+ * The transaction committed, so we can tell caller to set
5649
+ * HEAP_XMAX_COMMITTED. (We can only do this because we know
5650
+ * the transaction is not running.)
5655
5651
*/
5656
- if (TransactionIdDidCommit (xid ))
5657
- update_committed = true;
5658
5652
Assert (!TransactionIdIsValid (update_xid ));
5653
+ update_committed = true;
5659
5654
update_xid = xid ;
5660
5655
}
5661
5656
5657
+ /*
5658
+ * Not in progress, not committed -- must be aborted or crashed;
5659
+ * we can ignore it.
5660
+ */
5661
+
5662
+ /*
5663
+ * Since the tuple wasn't marked HEAPTUPLE_DEAD by vacuum, the
5664
+ * update Xid cannot possibly be older than the xid cutoff.
5665
+ */
5666
+ Assert (!TransactionIdIsValid (update_xid ) ||
5667
+ !TransactionIdPrecedes (update_xid , cutoff_xid ));
5668
+
5662
5669
/*
5663
5670
* If we determined that it's an Xid corresponding to an update
5664
5671
* that must be retained, additionally add it to the list of
5665
- * members of the new Multis , in case we end up using that. (We
5672
+ * members of the new Multi , in case we end up using that. (We
5666
5673
* might still decide to use only an update Xid and not a multi,
5667
5674
* but it's easier to maintain the list as we walk the old members
5668
5675
* list.)
5669
- *
5670
- * It is possible to end up with a very old updater Xid that
5671
- * crashed and thus did not mark itself as aborted in pg_clog.
5672
- * That would manifest as a pre-cutoff Xid. Make sure to ignore
5673
- * it.
5674
5676
*/
5675
5677
if (TransactionIdIsValid (update_xid ))
5676
- {
5677
- if (!TransactionIdPrecedes (update_xid , cutoff_xid ))
5678
- {
5679
- newmembers [nnewmembers ++ ] = members [i ];
5680
- }
5681
- else
5682
- {
5683
- /* cannot have committed: would be HEAPTUPLE_DEAD */
5684
- Assert (!TransactionIdDidCommit (update_xid ));
5685
- update_xid = InvalidTransactionId ;
5686
- update_committed = false;
5687
- }
5688
- }
5678
+ newmembers [nnewmembers ++ ] = members [i ];
5689
5679
}
5690
5680
else
5691
5681
{
0 commit comments