diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c
index 8b3663b3c9da2fa40eef80e7b4eea55bb283218a..eaed9fb5a97f4791ae557ef82af9a4d125acfb46 100644
--- a/src/backend/executor/execProcnode.c
+++ b/src/backend/executor/execProcnode.c
@@ -752,6 +752,19 @@ ExecShutdownNode(PlanState *node)
 
 	planstate_tree_walker(node, ExecShutdownNode, NULL);
 
+	/*
+	 * Treat the node as running while we shut it down, but only if it's run
+	 * at least once already.  We don't expect much CPU consumption during
+	 * node shutdown, but in the case of Gather or Gather Merge, we may shut
+	 * down workers at this stage.  If so, their buffer usage will get
+	 * propagated into pgBufferUsage at this point, and we want to make sure
+	 * that it gets associated with the Gather node.  We skip this if the node
+	 * has never been executed, so as to avoid incorrectly making it appear
+	 * that it has.
+	 */
+	if (node->instrument && node->instrument->running)
+		InstrStartNode(node->instrument);
+
 	switch (nodeTag(node))
 	{
 		case T_GatherState:
@@ -776,6 +789,10 @@ ExecShutdownNode(PlanState *node)
 			break;
 	}
 
+	/* Stop the node if we started it above, reporting 0 tuples. */
+	if (node->instrument && node->instrument->running)
+		InstrStopNode(node->instrument, 0);
+
 	return false;
 }
 
diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c
index cdc9c51bd1558b84615d2ba4ef220610d118cf40..4a700b7b30e8fe7f5b8b086902d2060d99c91d48 100644
--- a/src/backend/executor/nodeGather.c
+++ b/src/backend/executor/nodeGather.c
@@ -324,7 +324,10 @@ gather_readnext(GatherState *gatherstate)
 			Assert(!tup);
 			--gatherstate->nreaders;
 			if (gatherstate->nreaders == 0)
+			{
+				ExecShutdownGatherWorkers(gatherstate);
 				return NULL;
+			}
 			memmove(&gatherstate->reader[gatherstate->nextreader],
 					&gatherstate->reader[gatherstate->nextreader + 1],
 					sizeof(TupleQueueReader *)
diff --git a/src/backend/executor/nodeLimit.c b/src/backend/executor/nodeLimit.c
index 56d98b4490bfdf003333afb8010197c7c1fdb178..66ea6aa3c35215965e558f9c6f1601c9df67cc79 100644
--- a/src/backend/executor/nodeLimit.c
+++ b/src/backend/executor/nodeLimit.c
@@ -134,6 +134,8 @@ ExecLimit(PlanState *pstate)
 					node->position - node->offset >= node->count)
 				{
 					node->lstate = LIMIT_WINDOWEND;
+					/* Allow nodes to release or shut down resources. */
+					(void) ExecShutdownNode(outerPlan);
 					return NULL;
 				}