*** a/src/backend/access/heap/heapam.c
--- b/src/backend/access/heap/heapam.c
***************
*** 4585,4591 **** l5:
  	}
  	else if (old_infomask & HEAP_XMAX_IS_MULTI)
  	{
! 		MultiXactStatus new_status;
  
  		/*
  		 * Currently we don't allow XMAX_COMMITTED to be set for multis, so
--- 4585,4591 ----
  	}
  	else if (old_infomask & HEAP_XMAX_IS_MULTI)
  	{
! 		bool	keepmulti = false;
  
  		/*
  		 * Currently we don't allow XMAX_COMMITTED to be set for multis, so
***************
*** 4609,4630 **** l5:
  		}
  
  		/*
! 		 * If the XMAX is already a MultiXactId, then we need to expand it to
! 		 * include add_to_xmax; but if all the members were lockers and are
! 		 * all gone, we can do away with the IS_MULTI bit and just set
! 		 * add_to_xmax as the only locker/updater.	If all lockers are gone
! 		 * and we have an updater that aborted, we can also do without a
! 		 * multi.
! 		 *
! 		 * The cost of doing GetMultiXactIdMembers would be paid by
! 		 * MultiXactIdExpand if we weren't to do this, so this check is not
! 		 * incurring extra work anyhow.
  		 */
! 		if (!MultiXactIdIsRunning(xmax))
  		{
! 			if (HEAP_XMAX_IS_LOCKED_ONLY(old_infomask) ||
! 				TransactionIdDidAbort(MultiXactIdGetUpdateXid(xmax,
! 															  old_infomask)))
  			{
  				/*
  				 * Reset these bits and restart; otherwise fall through to
--- 4609,4673 ----
  		}
  
  		/*
! 		 * Examine the members of the existing MultiXact.  If any of them is
! 		 * the current transaction and holds a lock at least as strong as we
! 		 * are requesting, then the lock request can be satisfied with the
! 		 * existing MultiXactId; there's no need to create a new one.  Note we
! 		 * only try this for locks, not updates, for three reasons: 1. if the
! 		 * savepoint with the update later tried to abort, we'd be screwed;
! 		 * 2. there's no way to "upgrade" a lock to an update within a
! 		 * multixact anyway; 3. there is no point in trying because if the
! 		 * multixact had a valid (non-aborted) update, the tuple would be
! 		 * invisible and we wouldn't be trying to lock it.
  		 */
! 		if (!is_update)
! 		{
! 			MultiXactMember *members;
! 			int		nmembers;
! 
! 			nmembers = GetMultiXactIdMembers(xmax, &members, true);
! 			if (nmembers > 0)
! 			{
! 				int		i;
! 				MultiXactStatus new_status;
! 
! 				new_status = get_mxact_status_for_lock(mode, false);
! 
! 				for (i = 0; i < nmembers; i++)
! 				{
! 					if (TransactionIdIsCurrentTransactionId(members[i].xid) &&
! 						(members[i].status >= new_status))
! 					{
! 						keepmulti = true;
! 						break;
! 					}
! 				}
! 				pfree(members);
! 			}
! 		}
! 
! 		if (keepmulti)
! 			new_xmax = xmax;
! 		else
  		{
! 			MultiXactStatus new_status;
! 
! 			/*
! 			 * If the XMAX is already a MultiXactId, then we need to expand it
! 			 * to include add_to_xmax; but if all the members were lockers and
! 			 * are all gone, we can do away with the IS_MULTI bit and just set
! 			 * add_to_xmax as the only locker/updater.	If all lockers are
! 			 * gone and we have an updater that aborted, we can also do
! 			 * without a multi.
! 			 *
! 			 * The cost of doing GetMultiXactIdMembers would be paid by
! 			 * MultiXactIdExpand if we weren't to do this, so this check is
! 			 * not incurring extra work anyhow.
! 			 */
! 			if (!MultiXactIdIsRunning(xmax) &&
! 				(HEAP_XMAX_IS_LOCKED_ONLY(old_infomask) ||
! 				 !TransactionIdDidCommit(MultiXactIdGetUpdateXid(xmax,
! 																 old_infomask))))
  			{
  				/*
  				 * Reset these bits and restart; otherwise fall through to
***************
*** 4634,4645 **** l5:
  				old_infomask |= HEAP_XMAX_INVALID;
  				goto l5;
  			}
- 		}
  
! 		new_status = get_mxact_status_for_lock(mode, is_update);
  
- 		new_xmax = MultiXactIdExpand((MultiXactId) xmax, add_to_xmax,
- 									 new_status);
  		GetMultiXactIdHintBits(new_xmax, &new_infomask, &new_infomask2);
  	}
  	else if (old_infomask & HEAP_XMAX_COMMITTED)
--- 4677,4689 ----
  				old_infomask |= HEAP_XMAX_INVALID;
  				goto l5;
  			}
  
! 			new_status = get_mxact_status_for_lock(mode, is_update);
! 
! 			new_xmax = MultiXactIdExpand((MultiXactId) xmax, add_to_xmax,
! 										 new_status);
! 		}
  
  		GetMultiXactIdHintBits(new_xmax, &new_infomask, &new_infomask2);
  	}
  	else if (old_infomask & HEAP_XMAX_COMMITTED)
