diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index edde5642ee7816a8174764b0933458e6cf4ea350..1286edee72997637817a1956aaba6c137ff02d53 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -814,7 +814,7 @@ PortalRun(Portal portal, long count, bool isTopLevel,
 							   dest, altdest, completionTag);
 
 				/* Prevent portal's commands from being re-executed */
-				portal->status = PORTAL_DONE;
+				MarkPortalDone(portal);
 
 				/* Always complete at end of RunMulti */
 				result = true;
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 0ca5e110393da8b7c36e6e8ca85e75388ada4e94..7fa66b422122bc8790a41e5bf46fdb732c0a30c2 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -401,6 +401,32 @@ UnpinPortal(Portal portal)
 	portal->portalPinned = false;
 }
 
+/*
+ * MarkPortalDone
+ *		Transition a portal from ACTIVE to DONE state.
+ */
+void
+MarkPortalDone(Portal portal)
+{
+	/* Perform the state transition */
+	Assert(portal->status == PORTAL_ACTIVE);
+	portal->status = PORTAL_DONE;
+
+	/*
+	 * Allow portalcmds.c to clean up the state it knows about.  We might
+	 * as well do that now, since the portal can't be executed any more.
+	 *
+	 * In some cases involving execution of a ROLLBACK command in an already
+	 * aborted transaction, this prevents an assertion failure from reaching
+	 * AtCleanup_Portals with the cleanup hook still unexecuted.
+	 */
+	if (PointerIsValid(portal->cleanup))
+	{
+		(*portal->cleanup) (portal);
+		portal->cleanup = NULL;
+	}
+}
+
 /*
  * PortalDrop
  *		Destroy the portal.
diff --git a/src/include/utils/portal.h b/src/include/utils/portal.h
index dd88451f9510a2b134cababfaef6cbbfcadfe28d..3068003caa35587b34c5a654708689a2e91ceb99 100644
--- a/src/include/utils/portal.h
+++ b/src/include/utils/portal.h
@@ -206,6 +206,7 @@ extern Portal CreatePortal(const char *name, bool allowDup, bool dupSilent);
 extern Portal CreateNewPortal(void);
 extern void PinPortal(Portal portal);
 extern void UnpinPortal(Portal portal);
+extern void MarkPortalDone(Portal portal);
 extern void PortalDrop(Portal portal, bool isTopCommit);
 extern Portal GetPortalByName(const char *name);
 extern void PortalDefineQuery(Portal portal,