Skip to content

Commit b805b63

Browse files
author
Amit Kapila
committed
Fix buffer usage stats for parallel nodes.
The buffer usage stats is accounted only for the execution phase of the node. For Gather and Gather Merge nodes, such stats are accumulated at the time of shutdown of workers which is done after execution of node due to which we missed to account them for such nodes. Fix it by treating nodes as running while we shut down them. We can also miss accounting for a Limit node when Gather or Gather Merge is beneath it, because it can finish the execution before shutting down such nodes. So we allow a Limit node to shut down the resources before it completes the execution. In the passing fix the gather node code to allow workers to shut down as soon as we find that all the tuples from the workers have been retrieved. The original code use to do that, but is accidently removed by commit 01edb5c. Reported-by: Adrien Nayrat Author: Amit Kapila and Robert Haas Reviewed-by: Robert Haas and Andres Freund Backpatch-through: 9.6 where this code was introduced Discussion: https://postgr.es/m/86137f17-1dfb-42f9-7421-82fd786b04a1@anayrat.info
1 parent 3f02b51 commit b805b63

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

src/backend/executor/execProcnode.c

+17
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,19 @@ ExecShutdownNode(PlanState *node)
737737

738738
planstate_tree_walker(node, ExecShutdownNode, NULL);
739739

740+
/*
741+
* Treat the node as running while we shut it down, but only if it's run
742+
* at least once already. We don't expect much CPU consumption during
743+
* node shutdown, but in the case of Gather or Gather Merge, we may shut
744+
* down workers at this stage. If so, their buffer usage will get
745+
* propagated into pgBufferUsage at this point, and we want to make sure
746+
* that it gets associated with the Gather node. We skip this if the node
747+
* has never been executed, so as to avoid incorrectly making it appear
748+
* that it has.
749+
*/
750+
if (node->instrument && node->instrument->running)
751+
InstrStartNode(node->instrument);
752+
740753
switch (nodeTag(node))
741754
{
742755
case T_GatherState:
@@ -755,5 +768,9 @@ ExecShutdownNode(PlanState *node)
755768
break;
756769
}
757770

771+
/* Stop the node if we started it above, reporting 0 tuples. */
772+
if (node->instrument && node->instrument->running)
773+
InstrStopNode(node->instrument, 0);
774+
758775
return false;
759776
}

src/backend/executor/nodeGather.c

+3
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,10 @@ gather_readnext(GatherState *gatherstate)
327327
Assert(!tup);
328328
--gatherstate->nreaders;
329329
if (gatherstate->nreaders == 0)
330+
{
331+
ExecShutdownGatherWorkers(gatherstate);
330332
return NULL;
333+
}
331334
memmove(&gatherstate->reader[gatherstate->nextreader],
332335
&gatherstate->reader[gatherstate->nextreader + 1],
333336
sizeof(TupleQueueReader *)

src/backend/executor/nodeLimit.c

+2
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ ExecLimit(PlanState *pstate)
134134
node->position - node->offset >= node->count)
135135
{
136136
node->lstate = LIMIT_WINDOWEND;
137+
/* Allow nodes to release or shut down resources. */
138+
(void) ExecShutdownNode(outerPlan);
137139
return NULL;
138140
}
139141

0 commit comments

Comments
 (0)