50
50
#define PARALLEL_KEY_WAL_USAGE UINT64CONST(0xB000000000000004)
51
51
#define PARALLEL_KEY_BUFFER_USAGE UINT64CONST(0xB000000000000005)
52
52
53
- /*
54
- * Status record for spooling/sorting phase.
55
- */
56
- typedef struct BrinSpool
57
- {
58
- Tuplesortstate * sortstate ; /* state data for tuplesort.c */
59
- Relation heap ;
60
- Relation index ;
61
- } BrinSpool ;
62
-
63
53
/*
64
54
* Status for index builds performed in parallel. This is allocated in a
65
55
* dynamic shared memory segment.
@@ -183,7 +173,13 @@ typedef struct BrinBuildState
183
173
*/
184
174
BrinLeader * bs_leader ;
185
175
int bs_worker_id ;
186
- BrinSpool * bs_spool ;
176
+
177
+ /*
178
+ * The sortstate is used by workers (including the leader). It has to be
179
+ * part of the build state, because that's the only thing passed to the
180
+ * build callback etc.
181
+ */
182
+ Tuplesortstate * bs_sortstate ;
187
183
} BrinBuildState ;
188
184
189
185
/*
@@ -231,12 +227,11 @@ static void brin_fill_empty_ranges(BrinBuildState *state,
231
227
/* parallel index builds */
232
228
static void _brin_begin_parallel (BrinBuildState * buildstate , Relation heap , Relation index ,
233
229
bool isconcurrent , int request );
234
- static void _brin_end_parallel (BrinLeader * btleader , BrinBuildState * state );
230
+ static void _brin_end_parallel (BrinLeader * brinleader , BrinBuildState * state );
235
231
static Size _brin_parallel_estimate_shared (Relation heap , Snapshot snapshot );
236
232
static void _brin_leader_participate_as_worker (BrinBuildState * buildstate ,
237
233
Relation heap , Relation index );
238
234
static void _brin_parallel_scan_and_build (BrinBuildState * buildstate ,
239
- BrinSpool * brinspool ,
240
235
BrinShared * brinshared ,
241
236
Sharedsort * sharedsort ,
242
237
Relation heap , Relation index ,
@@ -1143,10 +1138,6 @@ brinbuild(Relation heap, Relation index, IndexInfo *indexInfo)
1143
1138
state = initialize_brin_buildstate (index , revmap , pagesPerRange ,
1144
1139
RelationGetNumberOfBlocks (heap ));
1145
1140
1146
- state -> bs_spool = (BrinSpool * ) palloc0 (sizeof (BrinSpool ));
1147
- state -> bs_spool -> heap = heap ;
1148
- state -> bs_spool -> index = index ;
1149
-
1150
1141
/*
1151
1142
* Attempt to launch parallel worker scan when required
1152
1143
*
@@ -1160,11 +1151,13 @@ brinbuild(Relation heap, Relation index, IndexInfo *indexInfo)
1160
1151
indexInfo -> ii_ParallelWorkers );
1161
1152
1162
1153
/*
1163
- * Now scan the relation. No syncscan allowed here because we want the
1164
- * heap blocks in physical order.
1165
- *
1166
1154
* If parallel build requested and at least one worker process was
1167
- * successfully launched, set up coordination state
1155
+ * successfully launched, set up coordination state, wait for workers to
1156
+ * complete. Then read all tuples from the shared tuplesort and insert
1157
+ * them into the index.
1158
+ *
1159
+ * In serial mode, simply scan the table and build the index one index
1160
+ * tuple at a time.
1168
1161
*/
1169
1162
if (state -> bs_leader )
1170
1163
{
@@ -1176,9 +1169,8 @@ brinbuild(Relation heap, Relation index, IndexInfo *indexInfo)
1176
1169
state -> bs_leader -> nparticipanttuplesorts ;
1177
1170
coordinate -> sharedsort = state -> bs_leader -> sharedsort ;
1178
1171
1179
-
1180
1172
/*
1181
- * Begin serial/ leader tuplesort.
1173
+ * Begin leader tuplesort.
1182
1174
*
1183
1175
* In cases where parallelism is involved, the leader receives the
1184
1176
* same share of maintenance_work_mem as a serial sort (it is
@@ -1199,19 +1191,18 @@ brinbuild(Relation heap, Relation index, IndexInfo *indexInfo)
1199
1191
* INDEX operation, regardless of the use of parallelism or any other
1200
1192
* factor.
1201
1193
*/
1202
- state -> bs_spool -> sortstate =
1203
- tuplesort_begin_index_brin (heap , index ,
1204
- maintenance_work_mem , coordinate ,
1194
+ state -> bs_sortstate =
1195
+ tuplesort_begin_index_brin (maintenance_work_mem , coordinate ,
1205
1196
TUPLESORT_NONE );
1206
1197
1207
- /*
1208
- * In parallel mode, wait for workers to complete, and then read all
1209
- * tuples from the shared tuplesort and insert them into the index.
1210
- */
1211
1198
_brin_end_parallel (state -> bs_leader , state );
1212
1199
}
1213
1200
else /* no parallel index build */
1214
1201
{
1202
+ /*
1203
+ * Now scan the relation. No syncscan allowed here because we want
1204
+ * the heap blocks in physical order.
1205
+ */
1215
1206
reltuples = table_index_build_scan (heap , index , indexInfo , false, true,
1216
1207
brinbuildCallback , (void * ) state , NULL );
1217
1208
@@ -1671,7 +1662,7 @@ initialize_brin_buildstate(Relation idxRel, BrinRevmap *revmap,
1671
1662
state -> bs_dtuple = brin_new_memtuple (state -> bs_bdesc );
1672
1663
state -> bs_leader = NULL ;
1673
1664
state -> bs_worker_id = 0 ;
1674
- state -> bs_spool = NULL ;
1665
+ state -> bs_sortstate = NULL ;
1675
1666
state -> bs_context = CurrentMemoryContext ;
1676
1667
state -> bs_emptyTuple = NULL ;
1677
1668
state -> bs_emptyTupleLen = 0 ;
@@ -2002,7 +1993,7 @@ form_and_spill_tuple(BrinBuildState *state)
2002
1993
state -> bs_dtuple , & size );
2003
1994
2004
1995
/* write the BRIN tuple to the tuplesort */
2005
- tuplesort_putbrintuple (state -> bs_spool -> sortstate , tup , size );
1996
+ tuplesort_putbrintuple (state -> bs_sortstate , tup , size );
2006
1997
2007
1998
state -> bs_numtuples ++ ;
2008
1999
@@ -2522,7 +2513,6 @@ _brin_end_parallel(BrinLeader *brinleader, BrinBuildState *state)
2522
2513
Size tuplen ;
2523
2514
BrinShared * brinshared = brinleader -> brinshared ;
2524
2515
BlockNumber prevblkno = InvalidBlockNumber ;
2525
- BrinSpool * spool ;
2526
2516
MemoryContext rangeCxt ,
2527
2517
oldCxt ;
2528
2518
@@ -2541,8 +2531,7 @@ _brin_end_parallel(BrinLeader *brinleader, BrinBuildState *state)
2541
2531
state -> bs_numtuples = brinshared -> indtuples ;
2542
2532
2543
2533
/* do the actual sort in the leader */
2544
- spool = state -> bs_spool ;
2545
- tuplesort_performsort (spool -> sortstate );
2534
+ tuplesort_performsort (state -> bs_sortstate );
2546
2535
2547
2536
/*
2548
2537
* Initialize BrinMemTuple we'll use to union summaries from workers (in
@@ -2568,7 +2557,7 @@ _brin_end_parallel(BrinLeader *brinleader, BrinBuildState *state)
2568
2557
* That probably gives us an index that is cheaper to scan, thanks to
2569
2558
* mostly getting data from the same index page as before.
2570
2559
*/
2571
- while ((btup = tuplesort_getbrintuple (spool -> sortstate , & tuplen , true)) != NULL )
2560
+ while ((btup = tuplesort_getbrintuple (state -> bs_sortstate , & tuplen , true)) != NULL )
2572
2561
{
2573
2562
/* Ranges should be multiples of pages_per_range for the index. */
2574
2563
Assert (btup -> bt_blkno % brinshared -> pagesPerRange == 0 );
@@ -2640,7 +2629,7 @@ _brin_end_parallel(BrinLeader *brinleader, BrinBuildState *state)
2640
2629
prevblkno = btup -> bt_blkno ;
2641
2630
}
2642
2631
2643
- tuplesort_end (spool -> sortstate );
2632
+ tuplesort_end (state -> bs_sortstate );
2644
2633
2645
2634
/* Fill the BRIN tuple for the last page range with data. */
2646
2635
if (prevblkno != InvalidBlockNumber )
@@ -2704,11 +2693,6 @@ _brin_leader_participate_as_worker(BrinBuildState *buildstate, Relation heap, Re
2704
2693
BrinLeader * brinleader = buildstate -> bs_leader ;
2705
2694
int sortmem ;
2706
2695
2707
- /* Allocate memory and initialize private spool */
2708
- buildstate -> bs_spool = (BrinSpool * ) palloc0 (sizeof (BrinSpool ));
2709
- buildstate -> bs_spool -> heap = buildstate -> bs_spool -> heap ;
2710
- buildstate -> bs_spool -> index = buildstate -> bs_spool -> index ;
2711
-
2712
2696
/*
2713
2697
* Might as well use reliable figure when doling out maintenance_work_mem
2714
2698
* (when requested number of workers were not launched, this will be
@@ -2717,27 +2701,25 @@ _brin_leader_participate_as_worker(BrinBuildState *buildstate, Relation heap, Re
2717
2701
sortmem = maintenance_work_mem / brinleader -> nparticipanttuplesorts ;
2718
2702
2719
2703
/* Perform work common to all participants */
2720
- _brin_parallel_scan_and_build (buildstate , buildstate -> bs_spool , brinleader -> brinshared ,
2704
+ _brin_parallel_scan_and_build (buildstate , brinleader -> brinshared ,
2721
2705
brinleader -> sharedsort , heap , index , sortmem , true);
2722
2706
}
2723
2707
2724
2708
/*
2725
2709
* Perform a worker's portion of a parallel sort.
2726
2710
*
2727
- * This generates a tuplesort for passed btspool, and a second tuplesort
2728
- * state if a second btspool is need (i.e. for unique index builds). All
2729
- * other spool fields should already be set when this is called.
2711
+ * This generates a tuplesort for the worker portion of the table.
2730
2712
*
2731
2713
* sortmem is the amount of working memory to use within each worker,
2732
2714
* expressed in KBs.
2733
2715
*
2734
2716
* When this returns, workers are done, and need only release resources.
2735
2717
*/
2736
2718
static void
2737
- _brin_parallel_scan_and_build (BrinBuildState * state , BrinSpool * brinspool ,
2719
+ _brin_parallel_scan_and_build (BrinBuildState * state ,
2738
2720
BrinShared * brinshared , Sharedsort * sharedsort ,
2739
- Relation heap , Relation index , int sortmem ,
2740
- bool progress )
2721
+ Relation heap , Relation index ,
2722
+ int sortmem , bool progress )
2741
2723
{
2742
2724
SortCoordinate coordinate ;
2743
2725
TableScanDesc scan ;
@@ -2751,10 +2733,8 @@ _brin_parallel_scan_and_build(BrinBuildState *state, BrinSpool *brinspool,
2751
2733
coordinate -> sharedsort = sharedsort ;
2752
2734
2753
2735
/* Begin "partial" tuplesort */
2754
- brinspool -> sortstate = tuplesort_begin_index_brin (brinspool -> heap ,
2755
- brinspool -> index ,
2756
- sortmem , coordinate ,
2757
- TUPLESORT_NONE );
2736
+ state -> bs_sortstate = tuplesort_begin_index_brin (sortmem , coordinate ,
2737
+ TUPLESORT_NONE );
2758
2738
2759
2739
/* Join parallel scan */
2760
2740
indexInfo = BuildIndexInfo (index );
@@ -2770,7 +2750,7 @@ _brin_parallel_scan_and_build(BrinBuildState *state, BrinSpool *brinspool,
2770
2750
form_and_spill_tuple (state );
2771
2751
2772
2752
/* sort the BRIN ranges built by this worker */
2773
- tuplesort_performsort (brinspool -> sortstate );
2753
+ tuplesort_performsort (state -> bs_sortstate );
2774
2754
2775
2755
state -> bs_reltuples += reltuples ;
2776
2756
@@ -2786,7 +2766,7 @@ _brin_parallel_scan_and_build(BrinBuildState *state, BrinSpool *brinspool,
2786
2766
/* Notify leader */
2787
2767
ConditionVariableSignal (& brinshared -> workersdonecv );
2788
2768
2789
- tuplesort_end (brinspool -> sortstate );
2769
+ tuplesort_end (state -> bs_sortstate );
2790
2770
}
2791
2771
2792
2772
/*
@@ -2844,11 +2824,6 @@ _brin_parallel_build_main(dsm_segment *seg, shm_toc *toc)
2844
2824
brinshared -> pagesPerRange ,
2845
2825
InvalidBlockNumber );
2846
2826
2847
- /* Initialize worker's own spool */
2848
- buildstate -> bs_spool = (BrinSpool * ) palloc0 (sizeof (BrinSpool ));
2849
- buildstate -> bs_spool -> heap = heapRel ;
2850
- buildstate -> bs_spool -> index = indexRel ;
2851
-
2852
2827
/* Look up shared state private to tuplesort.c */
2853
2828
sharedsort = shm_toc_lookup (toc , PARALLEL_KEY_TUPLESORT , false);
2854
2829
tuplesort_attach_shared (sharedsort , seg );
@@ -2863,8 +2838,7 @@ _brin_parallel_build_main(dsm_segment *seg, shm_toc *toc)
2863
2838
*/
2864
2839
sortmem = maintenance_work_mem / brinshared -> scantuplesortstates ;
2865
2840
2866
- _brin_parallel_scan_and_build (buildstate , buildstate -> bs_spool ,
2867
- brinshared , sharedsort ,
2841
+ _brin_parallel_scan_and_build (buildstate , brinshared , sharedsort ,
2868
2842
heapRel , indexRel , sortmem , false);
2869
2843
2870
2844
/* Report WAL/buffer usage during parallel execution */
0 commit comments