*** a/src/backend/access/heap/heapam.c
--- b/src/backend/access/heap/heapam.c
***************
*** 4539,4547 **** failed:
  	/*
  	 * We might already hold the desired lock (or stronger), possibly under a
  	 * different subtransaction of the current top transaction.  If so, there
! 	 * is no need to change state or issue a WAL record.  We already handled
! 	 * the case where this is true for xmax being a MultiXactId, so now check
! 	 * for cases where it is a plain TransactionId.
  	 *
  	 * Note in particular that this covers the case where we already hold
  	 * exclusive lock on the tuple and the caller only wants key share or
--- 4539,4546 ----
  	/*
  	 * We might already hold the desired lock (or stronger), possibly under a
  	 * different subtransaction of the current top transaction.  If so, there
! 	 * is no need to change state or issue a WAL record.  First check
! 	 * for cases where xmax is a plain TransactionId.
  	 *
  	 * Note in particular that this covers the case where we already hold
  	 * exclusive lock on the tuple and the caller only wants key share or
***************
*** 4568,4573 **** failed:
--- 4567,4618 ----
  	}
  
  	/*
+ 	 * Now check the multixact case.  It was already checked above, but it's
+ 	 * possible to get MayBeUpdated from HTSU and so we wouldn't have run
+ 	 * through it.
+ 	 *
+ 	 * XXX this is run with buffer lock held -- probably not a good idea.
+ 	 */
+ 	if (old_infomask & HEAP_XMAX_IS_MULTI)
+ 	{
+ 		int			i;
+ 		int			nmembers;
+ 		MultiXactMember *members;
+ 
+ 		/*
+ 		 * We don't need to allow old multixacts here; if that had been
+ 		 * the case, HeapTupleSatisfiesUpdate would have returned
+ 		 * MayBeUpdated and we wouldn't be here.
+ 		 */
+ 		nmembers =
+ 			GetMultiXactIdMembers(xmax, &members, false,
+ 								  HEAP_XMAX_IS_LOCKED_ONLY(old_infomask));
+ 
+ 		for (i = 0; i < nmembers; i++)
+ 		{
+ 			if (TransactionIdIsCurrentTransactionId(members[i].xid))
+ 			{
+ 				LockTupleMode membermode;
+ 
+ 				membermode = TUPLOCK_from_mxstatus(members[i].status);
+ 
+ 				if (membermode >= mode)
+ 				{
+ 					LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);
+ 					if (have_tuple_lock)
+ 						UnlockTupleTuplock(relation, tid, mode);
+ 
+ 					pfree(members);
+ 					return HeapTupleMayBeUpdated;
+ 				}
+ 			}
+ 		}
+ 
+ 		if (members)
+ 			pfree(members);
+ 	}
+ 
+ 	/*
  	 * If this is the first possibly-multixact-able operation in the current
  	 * transaction, set my per-backend OldestMemberMXactId setting. We can be
  	 * certain that the transaction will never become a member of any older
