diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index 59dc394..34c569e 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -36,6 +36,8 @@ #include "utils/resowner.h" #include "utils/snapmgr.h" +#include "optimizer/cost.h" + /* * We don't want to waste a lot of memory on an error queue which, most of @@ -946,7 +948,11 @@ ParallelWorkerMain(Datum main_arg) char *asnapspace; char *tstatespace; StringInfoData msgbuf; - + int i =0; + while (i) + { + sleep(10); + } /* Set flag to indicate that we're initializing a parallel worker. */ InitializingParallelWorker = true; diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c index c55b7c4..08329b0 100644 --- a/src/backend/executor/execParallel.c +++ b/src/backend/executor/execParallel.c @@ -198,6 +198,11 @@ ExecParallelEstimate(PlanState *planstate, ExecParallelEstimateContext *e) ExecIndexScanEstimate((IndexScanState *) planstate, e->pcxt); break; + case T_IndexOnlyScanState: + ExecIndexOnlyScanEstimate((IndexOnlyScanState *) planstate, + e->pcxt); + break; + case T_ForeignScanState: ExecForeignScanEstimate((ForeignScanState *) planstate, e->pcxt); @@ -254,6 +259,11 @@ ExecParallelInitializeDSM(PlanState *planstate, ExecIndexScanInitializeDSM((IndexScanState *) planstate, d->pcxt); break; + case T_IndexOnlyScanState: + ExecIndexOnlyScanInitializeDSM((IndexOnlyScanState *) planstate, + d->pcxt); + break; + case T_ForeignScanState: ExecForeignScanInitializeDSM((ForeignScanState *) planstate, d->pcxt); @@ -701,6 +711,10 @@ ExecParallelInitializeWorker(PlanState *planstate, shm_toc *toc) case T_IndexScanState: ExecIndexScanInitializeWorker((IndexScanState *) planstate, toc); break; + case T_IndexOnlyScanState: + ExecIndexOnlyScanInitializeWorker((IndexOnlyScanState *) planstate, toc); + break; + case T_ForeignScanState: ExecForeignScanInitializeWorker((ForeignScanState *) planstate, toc); diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c index 45566bd..8257f43 100644 --- a/src/backend/executor/nodeIndexonlyscan.c +++ b/src/backend/executor/nodeIndexonlyscan.c @@ -276,7 +276,17 @@ ExecIndexOnlyScan(IndexOnlyScanState *node) */ void ExecReScanIndexOnlyScan(IndexOnlyScanState *node) -{ +{ + bool reset_parallel_scan = true; + + /* + * if we are here to just update the scan keys, then don't reset parallel + * scan + */ + if (node->ioss_NumRuntimeKeys != 0 && !node->ioss_RuntimeKeysReady) + reset_parallel_scan = false; + + /* * If we are doing runtime key calculations (ie, any of the index key * values weren't simple Consts), compute the new key values. But first, @@ -296,10 +306,16 @@ ExecReScanIndexOnlyScan(IndexOnlyScanState *node) node->ioss_RuntimeKeysReady = true; /* reset index scan */ - index_rescan(node->ioss_ScanDesc, - node->ioss_ScanKeys, node->ioss_NumScanKeys, - node->ioss_OrderByKeys, node->ioss_NumOrderByKeys); + if (node->ioss_ScanDesc) + { + + index_rescan(node->ioss_ScanDesc, + node->ioss_ScanKeys, node->ioss_NumScanKeys, + node->ioss_OrderByKeys, node->ioss_NumOrderByKeys); + if (reset_parallel_scan) + index_parallelrescan(node->ioss_ScanDesc); + } ExecScanReScan(&node->ss); } @@ -534,33 +550,99 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags) { indexstate->ioss_RuntimeContext = NULL; } - - /* - * Initialize scan descriptor. - */ - indexstate->ioss_ScanDesc = index_beginscan(currentRelation, + if (!node->scan.plan.parallel_aware) + { + /* + * Initialize scan descriptor. + */ + indexstate->ioss_ScanDesc = index_beginscan(currentRelation, indexstate->ioss_RelationDesc, estate->es_snapshot, NULL, indexstate->ioss_NumScanKeys, indexstate->ioss_NumOrderByKeys, false); - /* Set it up for index-only scan */ - indexstate->ioss_ScanDesc->xs_want_itup = true; - indexstate->ioss_VMBuffer = InvalidBuffer; + /* Set it up for index-only scan */ + indexstate->ioss_ScanDesc->xs_want_itup = true; + indexstate->ioss_VMBuffer = InvalidBuffer; - /* - * If no run-time keys to calculate, go ahead and pass the scankeys to the - * index AM. - */ - if (indexstate->ioss_NumRuntimeKeys == 0) - index_rescan(indexstate->ioss_ScanDesc, + /* + * If no run-time keys to calculate, go ahead and pass the scankeys to the + * index AM. + */ + if (indexstate->ioss_NumRuntimeKeys == 0) + index_rescan(indexstate->ioss_ScanDesc, indexstate->ioss_ScanKeys, indexstate->ioss_NumScanKeys, indexstate->ioss_OrderByKeys, indexstate->ioss_NumOrderByKeys); - + } /* * all done. */ return indexstate; } +void +ExecIndexOnlyScanEstimate(IndexOnlyScanState *node, + ParallelContext *pcxt) +{ + EState *estate = node->ss.ps.state; + + node->ioss_PscanLen = index_parallelscan_estimate(node->ioss_RelationDesc, + estate->es_snapshot); + shm_toc_estimate_chunk(&pcxt->estimator, node->ioss_PscanLen); + shm_toc_estimate_keys(&pcxt->estimator, 1); +} + +void +ExecIndexOnlyScanInitializeDSM(IndexOnlyScanState *node, + ParallelContext *pcxt) +{ + EState *estate = node->ss.ps.state; + ParallelIndexScanDesc piscan; + + piscan = shm_toc_allocate(pcxt->toc, node->ioss_PscanLen); + index_parallelscan_initialize(node->ss.ss_currentRelation, + node->ioss_RelationDesc, + estate->es_snapshot, + piscan); + shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, piscan); + node->ioss_ScanDesc = + index_beginscan_parallel(node->ss.ss_currentRelation, + node->ioss_RelationDesc, + node->ioss_NumScanKeys, + node->ioss_NumOrderByKeys, + piscan); + node->ioss_ScanDesc->xs_want_itup = true; + + /* + * If no run-time keys to calculate, go ahead and pass the scankeys to the + * index AM. + */ + if (node->ioss_NumRuntimeKeys == 0) + index_rescan(node->ioss_ScanDesc, + node->ioss_ScanKeys, node->ioss_NumScanKeys, + node->ioss_OrderByKeys, node->ioss_NumOrderByKeys); +} +void +ExecIndexOnlyScanInitializeWorker(IndexOnlyScanState *node, shm_toc *toc) +{ + ParallelIndexScanDesc piscan; + + piscan = shm_toc_lookup(toc, node->ss.ps.plan->plan_node_id); + node->ioss_ScanDesc = + index_beginscan_parallel(node->ss.ss_currentRelation, + node->ioss_RelationDesc, + node->ioss_NumScanKeys, + node->ioss_NumOrderByKeys, + piscan); + node->ioss_ScanDesc->xs_want_itup = true; + + /* + * If no run-time keys to calculate, go ahead and pass the scankeys to the + * index AM. + */ + if (node->ioss_NumRuntimeKeys == 0) + index_rescan(node->ioss_ScanDesc, + node->ioss_ScanKeys, node->ioss_NumScanKeys, + node->ioss_OrderByKeys, node->ioss_NumOrderByKeys); +} diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 54a8a2f..5d963f5 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -1098,8 +1098,8 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel, * If appropriate, consider parallel index scan. We don't allow * parallel index scan for bitmap scans. */ - if (index->amcanparallel && - !index_only_scan && + if ((index->amcanparallel || + index_only_scan) && rel->consider_parallel && outer_relids == NULL && scantype != ST_BITMAPSCAN) diff --git a/src/include/executor/nodeIndexonlyscan.h b/src/include/executor/nodeIndexonlyscan.h index d63d194..143d8cd 100644 --- a/src/include/executor/nodeIndexonlyscan.h +++ b/src/include/executor/nodeIndexonlyscan.h @@ -14,6 +14,7 @@ #ifndef NODEINDEXONLYSCAN_H #define NODEINDEXONLYSCAN_H +#include "access/parallel.h" #include "nodes/execnodes.h" extern IndexOnlyScanState *ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags); @@ -23,4 +24,8 @@ extern void ExecIndexOnlyMarkPos(IndexOnlyScanState *node); extern void ExecIndexOnlyRestrPos(IndexOnlyScanState *node); extern void ExecReScanIndexOnlyScan(IndexOnlyScanState *node); +extern void ExecIndexOnlyScanEstimate(IndexOnlyScanState *node, ParallelContext *pcxt); +extern void ExecIndexOnlyScanInitializeDSM(IndexOnlyScanState *node, ParallelContext *pcxt); +extern void ExecIndexOnlyScanInitializeWorker(IndexOnlyScanState *node, shm_toc *toc); + #endif /* NODEINDEXONLYSCAN_H */ diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 17d712a..b8f22da 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -1397,6 +1397,8 @@ typedef struct IndexOnlyScanState IndexScanDesc ioss_ScanDesc; Buffer ioss_VMBuffer; long ioss_HeapFetches; + /* This is needed for parallel index scan */ + Size ioss_PscanLen; } IndexOnlyScanState; /* ----------------