if (!HEAP_XMAX_IS_LOCKED_ONLY(oldtup.t_data->t_infomask))
                update_xact = HeapTupleGetUpdateXid(oldtup.t_data);
 
-           /* there was no UPDATE in the MultiXact; or it aborted. */
+           /*
+            * There was no UPDATE in the MultiXact; or it aborted. No
+            * TransactionIdIsInProgress() call needed here, since we called
+            * MultiXactIdWait() above.
+            */
            if (!TransactionIdIsValid(update_xact) ||
                TransactionIdDidAbort(update_xact))
                can_continue = true;
  * Given a multixact Xmax and corresponding infomask, which does not have the
  * HEAP_XMAX_LOCK_ONLY bit set, obtain and return the Xid of the updating
  * transaction.
+ *
+ * Caller is expected to check the status of the updating transaction, if
+ * necessary.
  */
 static TransactionId
 MultiXactIdGetUpdateXid(TransactionId xmax, uint16 t_infomask)
        for (i = 0; i < nmembers; i++)
        {
            /* Ignore lockers */
-           if (members[i].status == MultiXactStatusForKeyShare ||
-               members[i].status == MultiXactStatusForShare ||
-               members[i].status == MultiXactStatusForNoKeyUpdate ||
-               members[i].status == MultiXactStatusForUpdate)
+           if (!ISUPDATE_from_mxstatus(members[i].status))
                continue;
 
-           /* ignore aborted transactions */
-           if (TransactionIdDidAbort(members[i].xid))
-               continue;
-           /* there should be at most one non-aborted updater */
+           /* there can be at most one updater */
            Assert(update_xact == InvalidTransactionId);
-           Assert(members[i].status == MultiXactStatusNoKeyUpdate ||
-                  members[i].status == MultiXactStatusUpdate);
            update_xact = members[i].xid;
 #ifndef USE_ASSERT_CHECKING
 
 
                TransactionId xmax;
 
                xmax = HeapTupleGetUpdateXid(tuple);
-               if (!TransactionIdIsValid(xmax))
-                   return true;
+
+               /* not LOCKED_ONLY, so it has to have an xmax */
+               Assert(TransactionIdIsValid(xmax));
 
                /* updating subtransaction must have aborted */
                if (!TransactionIdIsCurrentTransactionId(xmax))
            return true;
 
        xmax = HeapTupleGetUpdateXid(tuple);
-       if (!TransactionIdIsValid(xmax))
-           return true;
+
+       /* not LOCKED_ONLY, so it has to have an xmax */
+       Assert(TransactionIdIsValid(xmax));
+
        if (TransactionIdIsCurrentTransactionId(xmax))
            return false;
        if (TransactionIdIsInProgress(xmax))
            return true;
        if (TransactionIdDidCommit(xmax))
            return false;
+       /* it must have aborted or crashed */
        return true;
    }
 
                TransactionId xmax;
 
                xmax = HeapTupleGetUpdateXid(tuple);
-               if (!TransactionIdIsValid(xmax))
-                   return HeapTupleMayBeUpdated;
+
+               /* not LOCKED_ONLY, so it has to have an xmax */
+               Assert(TransactionIdIsValid(xmax));
 
                /* updating subtransaction must have aborted */
                if (!TransactionIdIsCurrentTransactionId(xmax))
        }
 
        xmax = HeapTupleGetUpdateXid(tuple);
-       if (!TransactionIdIsValid(xmax))
-       {
-           if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple)))
-               return HeapTupleBeingUpdated;
 
-           SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
-           return HeapTupleMayBeUpdated;
-       }
+       /* not LOCKED_ONLY, so it has to have an xmax */
+       Assert(TransactionIdIsValid(xmax));
 
        if (TransactionIdIsCurrentTransactionId(xmax))
        {
                return HeapTupleInvisible;      /* updated before scan started */
        }
 
-       if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple)))
+       if (TransactionIdIsInProgress(xmax))
            return HeapTupleBeingUpdated;
 
        if (TransactionIdDidCommit(xmax))
            return HeapTupleUpdated;
+
+       /* no member, even just a locker, alive anymore */
+       if (!MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple)))
+           SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
+                       InvalidTransactionId);
+
        /* it must have aborted or crashed */
-       SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
        return HeapTupleMayBeUpdated;
    }
 
                TransactionId xmax;
 
                xmax = HeapTupleGetUpdateXid(tuple);
-               if (!TransactionIdIsValid(xmax))
-                   return true;
+
+               /* not LOCKED_ONLY, so it has to have an xmax */
+               Assert(TransactionIdIsValid(xmax));
 
                /* updating subtransaction must have aborted */
                if (!TransactionIdIsCurrentTransactionId(xmax))
            return true;
 
        xmax = HeapTupleGetUpdateXid(tuple);
-       if (!TransactionIdIsValid(xmax))
-           return true;
+
+       /* not LOCKED_ONLY, so it has to have an xmax */
+       Assert(TransactionIdIsValid(xmax));
+
        if (TransactionIdIsCurrentTransactionId(xmax))
            return false;
        if (TransactionIdIsInProgress(xmax))
        }
        if (TransactionIdDidCommit(xmax))
            return false;
+       /* it must have aborted or crashed */
        return true;
    }
 
                TransactionId xmax;
 
                xmax = HeapTupleGetUpdateXid(tuple);
-               if (!TransactionIdIsValid(xmax))
-                   return true;
+
+               /* not LOCKED_ONLY, so it has to have an xmax */
+               Assert(TransactionIdIsValid(xmax));
 
                /* updating subtransaction must have aborted */
                if (!TransactionIdIsCurrentTransactionId(xmax))
        Assert(!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask));
 
        xmax = HeapTupleGetUpdateXid(tuple);
-       if (!TransactionIdIsValid(xmax))
-           return true;
+
+       /* not LOCKED_ONLY, so it has to have an xmax */
+       Assert(TransactionIdIsValid(xmax));
+
        if (TransactionIdIsCurrentTransactionId(xmax))
        {
            if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
                return true;    /* treat as still in progress */
            return false;
        }
+       /* it must have aborted or crashed */
        return true;
    }
 
            Assert(!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask));
 
            xmax = HeapTupleGetUpdateXid(tuple);
-           if (!TransactionIdIsValid(xmax))
-               return HEAPTUPLE_LIVE;
+
+           /* not LOCKED_ONLY, so it has to have an xmax */
+           Assert(TransactionIdIsValid(xmax));
+
            if (TransactionIdIsInProgress(xmax))
                return HEAPTUPLE_DELETE_IN_PROGRESS;
            else if (TransactionIdDidCommit(xmax))
        Assert(!(tuple->t_infomask & HEAP_XMAX_COMMITTED));
 
        xmax = HeapTupleGetUpdateXid(tuple);
-       if (!TransactionIdIsValid(xmax))
-           return HEAPTUPLE_LIVE;
+
+       /* not LOCKED_ONLY, so it has to have an xmax */
+       Assert(TransactionIdIsValid(xmax));
+
        /* multi is not running -- updating xact cannot be */
        Assert(!TransactionIdIsInProgress(xmax));
        if (TransactionIdDidCommit(xmax))
            else
                return HEAPTUPLE_DEAD;
        }
-       else
-       {
-           /*
-            * Not in Progress, Not Committed, so either Aborted or crashed.
-            */
-           SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
-           return HEAPTUPLE_LIVE;
-       }
 
        /*
-        * Deleter committed, but perhaps it was recent enough that some open
-        * transactions could still see the tuple.
+        * Not in Progress, Not Committed, so either Aborted or crashed.
+        * Remove the Xmax.
         */
-
-       /* Otherwise, it's dead and removable */
-       return HEAPTUPLE_DEAD;
+       SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId);
+       return HEAPTUPLE_LIVE;
    }
 
    if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
 
    /* ... but if it's a multi, then perhaps the updating Xid aborted. */
    xmax = HeapTupleGetUpdateXid(tuple);
-   if (!TransactionIdIsValid(xmax))    /* shouldn't happen .. */
-       return true;
+
+   /* not LOCKED_ONLY, so it has to have an xmax */
+   Assert(TransactionIdIsValid(xmax));
 
    if (TransactionIdIsCurrentTransactionId(xmax))
        return false;