Commit 15a8f8ca authored by Alvaro Herrera's avatar Alvaro Herrera

Fix IndexOnlyScan counter for heap fetches in parallel mode

The HeapFetches counter was using a simple value in IndexOnlyScanState,
which fails to propagate values from parallel workers; so the counts are
wrong when IndexOnlyScan runs in parallel.  Move it to Instrumentation,
like all the other counters.

While at it, change INSERT ON CONFLICT conflicting tuple counter to use
the new ntuples2 instead of nfiltered2, which is a blatant misuse.

Discussion: https://postgr.es/m/20180409215851.idwc75ct2bzi6tea@alvherre.pgsql
parent 1a40485a
...@@ -1459,12 +1459,8 @@ ExplainNode(PlanState *planstate, List *ancestors, ...@@ -1459,12 +1459,8 @@ ExplainNode(PlanState *planstate, List *ancestors,
show_instrumentation_count("Rows Removed by Filter", 1, show_instrumentation_count("Rows Removed by Filter", 1,
planstate, es); planstate, es);
if (es->analyze) if (es->analyze)
{ ExplainPropertyFloat("Heap Fetches", NULL,
long heapFetches = planstate->instrument->ntuples2, 0, es);
((IndexOnlyScanState *) planstate)->ioss_HeapFetches;
ExplainPropertyInteger("Heap Fetches", NULL, heapFetches, es);
}
break; break;
case T_BitmapIndexScan: case T_BitmapIndexScan:
show_scan_qual(((BitmapIndexScan *) plan)->indexqualorig, show_scan_qual(((BitmapIndexScan *) plan)->indexqualorig,
...@@ -3132,7 +3128,7 @@ show_modifytable_info(ModifyTableState *mtstate, List *ancestors, ...@@ -3132,7 +3128,7 @@ show_modifytable_info(ModifyTableState *mtstate, List *ancestors,
/* count the number of source rows */ /* count the number of source rows */
total = mtstate->mt_plans[0]->instrument->ntuples; total = mtstate->mt_plans[0]->instrument->ntuples;
other_path = mtstate->ps.instrument->nfiltered2; other_path = mtstate->ps.instrument->ntuples2;
insert_path = total - other_path; insert_path = total - other_path;
ExplainPropertyFloat("Tuples Inserted", NULL, ExplainPropertyFloat("Tuples Inserted", NULL,
......
...@@ -156,6 +156,7 @@ InstrAggNode(Instrumentation *dst, Instrumentation *add) ...@@ -156,6 +156,7 @@ InstrAggNode(Instrumentation *dst, Instrumentation *add)
dst->startup += add->startup; dst->startup += add->startup;
dst->total += add->total; dst->total += add->total;
dst->ntuples += add->ntuples; dst->ntuples += add->ntuples;
dst->ntuples2 += add->ntuples2;
dst->nloops += add->nloops; dst->nloops += add->nloops;
dst->nfiltered1 += add->nfiltered1; dst->nfiltered1 += add->nfiltered1;
dst->nfiltered2 += add->nfiltered2; dst->nfiltered2 += add->nfiltered2;
......
...@@ -162,7 +162,7 @@ IndexOnlyNext(IndexOnlyScanState *node) ...@@ -162,7 +162,7 @@ IndexOnlyNext(IndexOnlyScanState *node)
/* /*
* Rats, we have to visit the heap to check visibility. * Rats, we have to visit the heap to check visibility.
*/ */
node->ioss_HeapFetches++; InstrCountTuples2(node, 1);
tuple = index_fetch_heap(scandesc); tuple = index_fetch_heap(scandesc);
if (tuple == NULL) if (tuple == NULL)
continue; /* no visible tuple, try next index entry */ continue; /* no visible tuple, try next index entry */
...@@ -509,7 +509,6 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags) ...@@ -509,7 +509,6 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.plan = (Plan *) node;
indexstate->ss.ps.state = estate; indexstate->ss.ps.state = estate;
indexstate->ss.ps.ExecProcNode = ExecIndexOnlyScan; indexstate->ss.ps.ExecProcNode = ExecIndexOnlyScan;
indexstate->ioss_HeapFetches = 0;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -461,7 +461,7 @@ ExecInsert(ModifyTableState *mtstate, ...@@ -461,7 +461,7 @@ ExecInsert(ModifyTableState *mtstate,
&conflictTid, planSlot, slot, &conflictTid, planSlot, slot,
estate, canSetTag, &returning)) estate, canSetTag, &returning))
{ {
InstrCountFiltered2(&mtstate->ps, 1); InstrCountTuples2(&mtstate->ps, 1);
return returning; return returning;
} }
else else
...@@ -476,7 +476,7 @@ ExecInsert(ModifyTableState *mtstate, ...@@ -476,7 +476,7 @@ ExecInsert(ModifyTableState *mtstate,
*/ */
Assert(onconflict == ONCONFLICT_NOTHING); Assert(onconflict == ONCONFLICT_NOTHING);
ExecCheckTIDVisible(estate, resultRelInfo, &conflictTid); ExecCheckTIDVisible(estate, resultRelInfo, &conflictTid);
InstrCountFiltered2(&mtstate->ps, 1); InstrCountTuples2(&mtstate->ps, 1);
return NULL; return NULL;
} }
} }
......
...@@ -57,6 +57,7 @@ typedef struct Instrumentation ...@@ -57,6 +57,7 @@ typedef struct Instrumentation
double startup; /* Total startup time (in seconds) */ double startup; /* Total startup time (in seconds) */
double total; /* Total total time (in seconds) */ double total; /* Total total time (in seconds) */
double ntuples; /* Total tuples produced */ double ntuples; /* Total tuples produced */
double ntuples2; /* Secondary node-specific tuple counter */
double nloops; /* # of run cycles for this node */ double nloops; /* # of run cycles for this node */
double nfiltered1; /* # tuples removed by scanqual or joinqual OR double nfiltered1; /* # tuples removed by scanqual or joinqual OR
* # tuples inserted by MERGE */ * # tuples inserted by MERGE */
......
...@@ -1004,6 +1004,11 @@ typedef struct PlanState ...@@ -1004,6 +1004,11 @@ typedef struct PlanState
#define outerPlanState(node) (((PlanState *)(node))->lefttree) #define outerPlanState(node) (((PlanState *)(node))->lefttree)
/* Macros for inline access to certain instrumentation counters */ /* Macros for inline access to certain instrumentation counters */
#define InstrCountTuples2(node, delta) \
do { \
if (((PlanState *)(node))->instrument) \
((PlanState *)(node))->instrument->ntuples2 += (delta); \
} while (0)
#define InstrCountFiltered1(node, delta) \ #define InstrCountFiltered1(node, delta) \
do { \ do { \
if (((PlanState *)(node))->instrument) \ if (((PlanState *)(node))->instrument) \
...@@ -1368,7 +1373,6 @@ typedef struct IndexScanState ...@@ -1368,7 +1373,6 @@ typedef struct IndexScanState
* RelationDesc index relation descriptor * RelationDesc index relation descriptor
* ScanDesc index scan descriptor * ScanDesc index scan descriptor
* VMBuffer buffer in use for visibility map testing, if any * VMBuffer buffer in use for visibility map testing, if any
* HeapFetches number of tuples we were forced to fetch from heap
* ioss_PscanLen Size of parallel index-only scan descriptor * ioss_PscanLen Size of parallel index-only scan descriptor
* ---------------- * ----------------
*/ */
...@@ -1387,7 +1391,6 @@ typedef struct IndexOnlyScanState ...@@ -1387,7 +1391,6 @@ typedef struct IndexOnlyScanState
Relation ioss_RelationDesc; Relation ioss_RelationDesc;
IndexScanDesc ioss_ScanDesc; IndexScanDesc ioss_ScanDesc;
Buffer ioss_VMBuffer; Buffer ioss_VMBuffer;
long ioss_HeapFetches;
Size ioss_PscanLen; Size ioss_PscanLen;
} IndexOnlyScanState; } IndexOnlyScanState;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment