@@ -5627,17 +5627,13 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
56275627
56285628 /*
56295629 * 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
56345633 * HEAPTUPLE_DEAD and we would not be trying to freeze the tuple.
56355634 *
5636- * Note the TransactionIdDidAbort() test is just an optimization
5637- * and not strictly necessary for correctness.
5638- *
56395635 * As with all tuple visibility routines, it's critical to test
5640- * TransactionIdIsInProgress before the transam.c routines ,
5636+ * TransactionIdIsInProgress before TransactionIdDidCommit ,
56415637 * because of race conditions explained in detail in tqual.c.
56425638 */
56435639 if (TransactionIdIsCurrentTransactionId (xid ) ||
@@ -5646,46 +5642,40 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
56465642 Assert (!TransactionIdIsValid (update_xid ));
56475643 update_xid = xid ;
56485644 }
5649- else if (! TransactionIdDidAbort (xid ))
5645+ else if (TransactionIdDidCommit (xid ))
56505646 {
56515647 /*
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.)
56555651 */
5656- if (TransactionIdDidCommit (xid ))
5657- update_committed = true;
56585652 Assert (!TransactionIdIsValid (update_xid ));
5653+ update_committed = true;
56595654 update_xid = xid ;
56605655 }
56615656
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+
56625669 /*
56635670 * If we determined that it's an Xid corresponding to an update
56645671 * 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
56665673 * might still decide to use only an update Xid and not a multi,
56675674 * but it's easier to maintain the list as we walk the old members
56685675 * 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.
56745676 */
56755677 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 ];
56895679 }
56905680 else
56915681 {
0 commit comments