@@ -143,7 +143,6 @@ typedef struct BrinLeader
143143 */
144144 BrinShared * brinshared ;
145145 Sharedsort * sharedsort ;
146- Snapshot snapshot ;
147146 WalUsage * walusage ;
148147 BufferUsage * bufferusage ;
149148} BrinLeader ;
@@ -231,7 +230,7 @@ static void brin_fill_empty_ranges(BrinBuildState *state,
231230static void _brin_begin_parallel (BrinBuildState * buildstate , Relation heap , Relation index ,
232231 bool isconcurrent , int request );
233232static void _brin_end_parallel (BrinLeader * brinleader , BrinBuildState * state );
234- static Size _brin_parallel_estimate_shared (Relation heap , Snapshot snapshot );
233+ static Size _brin_parallel_estimate_shared (Relation heap );
235234static double _brin_parallel_heapscan (BrinBuildState * state );
236235static double _brin_parallel_merge (BrinBuildState * state );
237236static void _brin_leader_participate_as_worker (BrinBuildState * buildstate ,
@@ -1221,7 +1220,6 @@ brinbuild(Relation heap, Relation index, IndexInfo *indexInfo)
12211220 reltuples = _brin_parallel_merge (state );
12221221
12231222 _brin_end_parallel (state -> bs_leader , state );
1224- Assert (!indexInfo -> ii_Concurrent || !TransactionIdIsValid (MyProc -> xmin ));
12251223 }
12261224 else /* no parallel index build */
12271225 {
@@ -1254,7 +1252,6 @@ brinbuild(Relation heap, Relation index, IndexInfo *indexInfo)
12541252 brin_fill_empty_ranges (state ,
12551253 state -> bs_currRangeStart ,
12561254 state -> bs_maxRangeStart );
1257- Assert (!indexInfo -> ii_Concurrent || !TransactionIdIsValid (MyProc -> xmin ));
12581255 }
12591256
12601257 /* release resources */
@@ -1269,6 +1266,7 @@ brinbuild(Relation heap, Relation index, IndexInfo *indexInfo)
12691266
12701267 result -> heap_tuples = reltuples ;
12711268 result -> index_tuples = idxtuples ;
1269+ Assert (!indexInfo -> ii_Concurrent || !TransactionIdIsValid (MyProc -> xid ));
12721270
12731271 return result ;
12741272}
@@ -2368,7 +2366,6 @@ _brin_begin_parallel(BrinBuildState *buildstate, Relation heap, Relation index,
23682366{
23692367 ParallelContext * pcxt ;
23702368 int scantuplesortstates ;
2371- Snapshot snapshot ;
23722369 Size estbrinshared ;
23732370 Size estsort ;
23742371 BrinShared * brinshared ;
@@ -2399,25 +2396,25 @@ _brin_begin_parallel(BrinBuildState *buildstate, Relation heap, Relation index,
23992396 * Prepare for scan of the base relation. In a normal index build, we use
24002397 * SnapshotAny because we must retrieve all tuples and do our own time
24012398 * qual checks (because we have to index RECENTLY_DEAD tuples). In a
2402- * concurrent build, we take a regular MVCC snapshot and index whatever's
2403- * live according to that.
2399+ * concurrent build, we take a regular MVCC snapshot and push it as active.
2400+ * Later we index whatever's live according to that snapshot while that
2401+ * snapshot is reset periodically.
24042402 */
24052403 if (!isconcurrent )
24062404 {
24072405 Assert (ActiveSnapshotSet ());
2408- snapshot = SnapshotAny ;
24092406 need_pop_active_snapshot = false;
24102407 }
24112408 else
24122409 {
2413- snapshot = RegisterSnapshot ( GetTransactionSnapshot ());
2410+ Assert (! ActiveSnapshotSet ());
24142411 PushActiveSnapshot (GetTransactionSnapshot ());
24152412 }
24162413
24172414 /*
24182415 * Estimate size for our own PARALLEL_KEY_BRIN_SHARED workspace.
24192416 */
2420- estbrinshared = _brin_parallel_estimate_shared (heap , snapshot );
2417+ estbrinshared = _brin_parallel_estimate_shared (heap );
24212418 shm_toc_estimate_chunk (& pcxt -> estimator , estbrinshared );
24222419 estsort = tuplesort_estimate_shared (scantuplesortstates );
24232420 shm_toc_estimate_chunk (& pcxt -> estimator , estsort );
@@ -2457,8 +2454,6 @@ _brin_begin_parallel(BrinBuildState *buildstate, Relation heap, Relation index,
24572454 {
24582455 if (need_pop_active_snapshot )
24592456 PopActiveSnapshot ();
2460- if (IsMVCCSnapshot (snapshot ))
2461- UnregisterSnapshot (snapshot );
24622457 DestroyParallelContext (pcxt );
24632458 ExitParallelMode ();
24642459 return ;
@@ -2483,7 +2478,8 @@ _brin_begin_parallel(BrinBuildState *buildstate, Relation heap, Relation index,
24832478
24842479 table_parallelscan_initialize (heap ,
24852480 ParallelTableScanFromBrinShared (brinshared ),
2486- snapshot );
2481+ isconcurrent ? InvalidSnapshot : SnapshotAny ,
2482+ isconcurrent );
24872483
24882484 /*
24892485 * Store shared tuplesort-private state, for which we reserved space.
@@ -2529,7 +2525,6 @@ _brin_begin_parallel(BrinBuildState *buildstate, Relation heap, Relation index,
25292525 brinleader -> nparticipanttuplesorts ++ ;
25302526 brinleader -> brinshared = brinshared ;
25312527 brinleader -> sharedsort = sharedsort ;
2532- brinleader -> snapshot = snapshot ;
25332528 brinleader -> walusage = walusage ;
25342529 brinleader -> bufferusage = bufferusage ;
25352530
@@ -2545,6 +2540,13 @@ _brin_begin_parallel(BrinBuildState *buildstate, Relation heap, Relation index,
25452540 /* Save leader state now that it's clear build will be parallel */
25462541 buildstate -> bs_leader = brinleader ;
25472542
2543+ /*
2544+ * In case of concurrent build snapshots are going to be reset periodically.
2545+ * We need to wait until all workers imported initial snapshot.
2546+ */
2547+ if (isconcurrent )
2548+ WaitForParallelWorkersToAttach (pcxt , true);
2549+
25482550 /* Join heap scan ourselves */
25492551 if (leaderparticipates )
25502552 _brin_leader_participate_as_worker (buildstate , heap , index );
@@ -2553,7 +2555,8 @@ _brin_begin_parallel(BrinBuildState *buildstate, Relation heap, Relation index,
25532555 * Caller needs to wait for all launched workers when we return. Make
25542556 * sure that the failure-to-start case will not hang forever.
25552557 */
2556- WaitForParallelWorkersToAttach (pcxt );
2558+ if (!isconcurrent )
2559+ WaitForParallelWorkersToAttach (pcxt , false);
25572560 if (need_pop_active_snapshot )
25582561 PopActiveSnapshot ();
25592562}
@@ -2576,9 +2579,6 @@ _brin_end_parallel(BrinLeader *brinleader, BrinBuildState *state)
25762579 for (i = 0 ; i < brinleader -> pcxt -> nworkers_launched ; i ++ )
25772580 InstrAccumParallelQuery (& brinleader -> bufferusage [i ], & brinleader -> walusage [i ]);
25782581
2579- /* Free last reference to MVCC snapshot, if one was used */
2580- if (IsMVCCSnapshot (brinleader -> snapshot ))
2581- UnregisterSnapshot (brinleader -> snapshot );
25822582 DestroyParallelContext (brinleader -> pcxt );
25832583 ExitParallelMode ();
25842584}
@@ -2778,14 +2778,14 @@ _brin_parallel_merge(BrinBuildState *state)
27782778
27792779/*
27802780 * Returns size of shared memory required to store state for a parallel
2781- * brin index build based on the snapshot its parallel scan will use .
2781+ * brin index build.
27822782 */
27832783static Size
2784- _brin_parallel_estimate_shared (Relation heap , Snapshot snapshot )
2784+ _brin_parallel_estimate_shared (Relation heap )
27852785{
27862786 /* c.f. shm_toc_allocate as to why BUFFERALIGN is used */
27872787 return add_size (BUFFERALIGN (sizeof (BrinShared )),
2788- table_parallelscan_estimate (heap , snapshot ));
2788+ table_parallelscan_estimate (heap , InvalidSnapshot ));
27892789}
27902790
27912791/*
@@ -2807,6 +2807,7 @@ _brin_leader_participate_as_worker(BrinBuildState *buildstate, Relation heap, Re
28072807 /* Perform work common to all participants */
28082808 _brin_parallel_scan_and_build (buildstate , brinleader -> brinshared ,
28092809 brinleader -> sharedsort , heap , index , sortmem , true);
2810+ Assert (!brinleader -> brinshared -> isconcurrent || !TransactionIdIsValid (MyProc -> xid ));
28102811}
28112812
28122813/*
@@ -2947,6 +2948,13 @@ _brin_parallel_build_main(dsm_segment *seg, shm_toc *toc)
29472948
29482949 _brin_parallel_scan_and_build (buildstate , brinshared , sharedsort ,
29492950 heapRel , indexRel , sortmem , false);
2951+ if (brinshared -> isconcurrent )
2952+ {
2953+ PopActiveSnapshot ();
2954+ InvalidateCatalogSnapshot ();
2955+ Assert (!TransactionIdIsValid (MyProc -> xid ));
2956+ PushActiveSnapshot (GetTransactionSnapshot ());
2957+ }
29502958
29512959 /* Report WAL/buffer usage during parallel execution */
29522960 bufferusage = shm_toc_lookup (toc , PARALLEL_KEY_BUFFER_USAGE , false);
0 commit comments