Skip to content

Commit 84c18ac

Browse files
committed
Remove redundant snapshot copying from parallel leader to workers
The parallel query infrastructure copies the leader backend's active snapshot to the worker processes. But BitmapHeapScan node also had bespoken code to pass the snapshot from leader to the worker. That was redundant, so remove it. The removed code was analogous to the snapshot serialization in table_parallelscan_initialize(), but that was the wrong role model. A parallel bitmap heap scan is more like an independent non-parallel bitmap heap scan in each parallel worker as far as the table AM is concerned, because the coordination is done in nodeBitmapHeapscan.c, and the table AM doesn't need to know anything about it. This relies on the assumption that es_snapshot == GetActiveSnapshot(). That's not a new assumption, things would get weird if you used the QueryDesc's snapshot for visibility checks in the scans, but the active snapshot for evaluating quals, for example. This could use some refactoring and cleanup, but for now, just add some assertions. Reviewed-by: Dilip Kumar, Robert Haas Discussion: https://www.postgresql.org/message-id/5f3b9d59-0f43-419d-80ca-6d04c07cf61a@iki.fi
1 parent 2346df6 commit 84c18ac

File tree

6 files changed

+15
-34
lines changed

6 files changed

+15
-34
lines changed

src/backend/access/table/tableam.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,6 @@ table_beginscan_catalog(Relation relation, int nkeys, struct ScanKeyData *key)
120120
NULL, flags);
121121
}
122122

123-
void
124-
table_scan_update_snapshot(TableScanDesc scan, Snapshot snapshot)
125-
{
126-
Assert(IsMVCCSnapshot(snapshot));
127-
128-
RegisterSnapshot(snapshot);
129-
scan->rs_snapshot = snapshot;
130-
scan->rs_flags |= SO_TEMP_SNAPSHOT;
131-
}
132-
133123

134124
/* ----------------------------------------------------------------------------
135125
* Parallel table scan related functions.

src/backend/executor/execMain.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
147147
Assert(queryDesc != NULL);
148148
Assert(queryDesc->estate == NULL);
149149

150+
/* caller must ensure the query's snapshot is active */
151+
Assert(GetActiveSnapshot() == queryDesc->snapshot);
152+
150153
/*
151154
* If the transaction is read-only, we need to check if any writes are
152155
* planned to non-temporary tables. EXPLAIN is considered read-only.
@@ -319,6 +322,9 @@ standard_ExecutorRun(QueryDesc *queryDesc,
319322
Assert(estate != NULL);
320323
Assert(!(estate->es_top_eflags & EXEC_FLAG_EXPLAIN_ONLY));
321324

325+
/* caller must ensure the query's snapshot is active */
326+
Assert(GetActiveSnapshot() == estate->es_snapshot);
327+
322328
/*
323329
* Switch into per-query memory context
324330
*/

src/backend/executor/execParallel.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,13 @@ ExecInitParallelPlan(PlanState *planstate, EState *estate,
720720
shm_toc_estimate_chunk(&pcxt->estimator, dsa_minsize);
721721
shm_toc_estimate_keys(&pcxt->estimator, 1);
722722

723+
/*
724+
* InitializeParallelDSM() passes the active snapshot to the parallel
725+
* worker, which uses it to set es_snapshot. Make sure we don't set
726+
* es_snapshot differently in the child.
727+
*/
728+
Assert(GetActiveSnapshot() == estate->es_snapshot);
729+
723730
/* Everyone's had a chance to ask for space, so now create the DSM. */
724731
InitializeParallelDSM(pcxt);
725732

src/backend/executor/nodeBitmapHeapscan.c

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,6 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
721721
scanstate->prefetch_iterator = NULL;
722722
scanstate->prefetch_pages = 0;
723723
scanstate->prefetch_target = 0;
724-
scanstate->pscan_len = 0;
725724
scanstate->initialized = false;
726725
scanstate->shared_tbmiterator = NULL;
727726
scanstate->shared_prefetch_iterator = NULL;
@@ -841,13 +840,7 @@ void
841840
ExecBitmapHeapEstimate(BitmapHeapScanState *node,
842841
ParallelContext *pcxt)
843842
{
844-
EState *estate = node->ss.ps.state;
845-
846-
node->pscan_len = add_size(offsetof(ParallelBitmapHeapState,
847-
phs_snapshot_data),
848-
EstimateSnapshotSpace(estate->es_snapshot));
849-
850-
shm_toc_estimate_chunk(&pcxt->estimator, node->pscan_len);
843+
shm_toc_estimate_chunk(&pcxt->estimator, sizeof(ParallelBitmapHeapState));
851844
shm_toc_estimate_keys(&pcxt->estimator, 1);
852845
}
853846

@@ -862,14 +855,13 @@ ExecBitmapHeapInitializeDSM(BitmapHeapScanState *node,
862855
ParallelContext *pcxt)
863856
{
864857
ParallelBitmapHeapState *pstate;
865-
EState *estate = node->ss.ps.state;
866858
dsa_area *dsa = node->ss.ps.state->es_query_dsa;
867859

868860
/* If there's no DSA, there are no workers; initialize nothing. */
869861
if (dsa == NULL)
870862
return;
871863

872-
pstate = shm_toc_allocate(pcxt->toc, node->pscan_len);
864+
pstate = shm_toc_allocate(pcxt->toc, sizeof(ParallelBitmapHeapState));
873865

874866
pstate->tbmiterator = 0;
875867
pstate->prefetch_iterator = 0;
@@ -881,7 +873,6 @@ ExecBitmapHeapInitializeDSM(BitmapHeapScanState *node,
881873
pstate->state = BM_INITIAL;
882874

883875
ConditionVariableInit(&pstate->cv);
884-
SerializeSnapshot(estate->es_snapshot, pstate->phs_snapshot_data);
885876

886877
shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, pstate);
887878
node->pstate = pstate;
@@ -927,13 +918,9 @@ ExecBitmapHeapInitializeWorker(BitmapHeapScanState *node,
927918
ParallelWorkerContext *pwcxt)
928919
{
929920
ParallelBitmapHeapState *pstate;
930-
Snapshot snapshot;
931921

932922
Assert(node->ss.ps.state->es_query_dsa != NULL);
933923

934924
pstate = shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, false);
935925
node->pstate = pstate;
936-
937-
snapshot = RestoreSnapshot(pstate->phs_snapshot_data);
938-
table_scan_update_snapshot(node->ss.ss_currentScanDesc, snapshot);
939926
}

src/include/access/tableam.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,11 +1038,6 @@ table_rescan_set_params(TableScanDesc scan, struct ScanKeyData *key,
10381038
allow_pagemode);
10391039
}
10401040

1041-
/*
1042-
* Update snapshot used by the scan.
1043-
*/
1044-
extern void table_scan_update_snapshot(TableScanDesc scan, Snapshot snapshot);
1045-
10461041
/*
10471042
* Return next tuple from `scan`, store in slot.
10481043
*/

src/include/nodes/execnodes.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,7 +1689,6 @@ typedef enum
16891689
* prefetch_target current target prefetch distance
16901690
* state current state of the TIDBitmap
16911691
* cv conditional wait variable
1692-
* phs_snapshot_data snapshot data shared to workers
16931692
* ----------------
16941693
*/
16951694
typedef struct ParallelBitmapHeapState
@@ -1701,7 +1700,6 @@ typedef struct ParallelBitmapHeapState
17011700
int prefetch_target;
17021701
SharedBitmapState state;
17031702
ConditionVariable cv;
1704-
char phs_snapshot_data[FLEXIBLE_ARRAY_MEMBER];
17051703
} ParallelBitmapHeapState;
17061704

17071705
/* ----------------
@@ -1721,7 +1719,6 @@ typedef struct ParallelBitmapHeapState
17211719
* prefetch_pages # pages prefetch iterator is ahead of current
17221720
* prefetch_target current target prefetch distance
17231721
* prefetch_maximum maximum value for prefetch_target
1724-
* pscan_len size of the shared memory for parallel bitmap
17251722
* initialized is node is ready to iterate
17261723
* shared_tbmiterator shared iterator
17271724
* shared_prefetch_iterator shared iterator for prefetching
@@ -1745,7 +1742,6 @@ typedef struct BitmapHeapScanState
17451742
int prefetch_pages;
17461743
int prefetch_target;
17471744
int prefetch_maximum;
1748-
Size pscan_len;
17491745
bool initialized;
17501746
TBMSharedIterator *shared_tbmiterator;
17511747
TBMSharedIterator *shared_prefetch_iterator;

0 commit comments

Comments
 (0)