mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
Report progress of CREATE INDEX operations
This uses the progress reporting infrastructure added by c16dc1aca5,
adding support for CREATE INDEX and CREATE INDEX CONCURRENTLY.
There are two pieces to this: one is index-AM-agnostic, and the other is
AM-specific. The latter is fairly elaborate for btrees, including
reportage for parallel index builds and the separate phases that btree
index creation uses; other index AMs, which are much simpler in their
building procedures, have simplistic reporting only, but that seems
sufficient, at least for non-concurrent builds.
The index-AM-agnostic part is fairly complete, providing insight into
the CONCURRENTLY wait phases as well as block-based progress during the
index validation table scan. (The index validation index scan requires
patching each AM, which has not been included here.)
Reviewers: Rahila Syed, Pavan Deolasee, Tatsuro Yamada
Discussion: https://postgr.es/m/20181220220022.mg63bhk26zdpvmcj@alvherre.pgsql
This commit is contained in:
@@ -112,6 +112,7 @@ brinhandler(PG_FUNCTION_ARGS)
|
||||
amroutine->amcostestimate = brincostestimate;
|
||||
amroutine->amoptions = brinoptions;
|
||||
amroutine->amproperty = NULL;
|
||||
amroutine->ambuildphasename = NULL;
|
||||
amroutine->amvalidate = brinvalidate;
|
||||
amroutine->ambeginscan = brinbeginscan;
|
||||
amroutine->amrescan = brinrescan;
|
||||
@@ -719,7 +720,7 @@ brinbuild(Relation heap, Relation index, IndexInfo *indexInfo)
|
||||
* Now scan the relation. No syncscan allowed here because we want the
|
||||
* heap blocks in physical order.
|
||||
*/
|
||||
reltuples = table_index_build_scan(heap, index, indexInfo, false,
|
||||
reltuples = table_index_build_scan(heap, index, indexInfo, false, true,
|
||||
brinbuildCallback, (void *) state, NULL);
|
||||
|
||||
/* process the final batch */
|
||||
@@ -1236,7 +1237,7 @@ summarize_range(IndexInfo *indexInfo, BrinBuildState *state, Relation heapRel,
|
||||
* cases.
|
||||
*/
|
||||
state->bs_currRangeStart = heapBlk;
|
||||
table_index_build_range_scan(heapRel, state->bs_irel, indexInfo, false, true,
|
||||
table_index_build_range_scan(heapRel, state->bs_irel, indexInfo, false, true, false,
|
||||
heapBlk, scanNumBlks,
|
||||
brinbuildCallback, (void *) state, NULL);
|
||||
|
||||
|
||||
@@ -395,7 +395,7 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)
|
||||
* Do the heap scan. We disallow sync scan here because dataPlaceToPage
|
||||
* prefers to receive tuples in TID order.
|
||||
*/
|
||||
reltuples = table_index_build_scan(heap, index, indexInfo, false,
|
||||
reltuples = table_index_build_scan(heap, index, indexInfo, false, true,
|
||||
ginBuildCallback, (void *) &buildstate,
|
||||
NULL);
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ ginhandler(PG_FUNCTION_ARGS)
|
||||
amroutine->amcostestimate = gincostestimate;
|
||||
amroutine->amoptions = ginoptions;
|
||||
amroutine->amproperty = NULL;
|
||||
amroutine->ambuildphasename = NULL;
|
||||
amroutine->amvalidate = ginvalidate;
|
||||
amroutine->ambeginscan = ginbeginscan;
|
||||
amroutine->amrescan = ginrescan;
|
||||
|
||||
@@ -86,6 +86,7 @@ gisthandler(PG_FUNCTION_ARGS)
|
||||
amroutine->amcostestimate = gistcostestimate;
|
||||
amroutine->amoptions = gistoptions;
|
||||
amroutine->amproperty = gistproperty;
|
||||
amroutine->ambuildphasename = NULL;
|
||||
amroutine->amvalidate = gistvalidate;
|
||||
amroutine->ambeginscan = gistbeginscan;
|
||||
amroutine->amrescan = gistrescan;
|
||||
|
||||
@@ -205,7 +205,7 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
|
||||
/*
|
||||
* Do the heap scan.
|
||||
*/
|
||||
reltuples = table_index_build_scan(heap, index, indexInfo, true,
|
||||
reltuples = table_index_build_scan(heap, index, indexInfo, true, true,
|
||||
gistBuildCallback,
|
||||
(void *) &buildstate, NULL);
|
||||
|
||||
|
||||
@@ -23,9 +23,11 @@
|
||||
#include "access/relscan.h"
|
||||
#include "access/tableam.h"
|
||||
#include "catalog/index.h"
|
||||
#include "commands/progress.h"
|
||||
#include "commands/vacuum.h"
|
||||
#include "miscadmin.h"
|
||||
#include "optimizer/plancat.h"
|
||||
#include "pgstat.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/index_selfuncs.h"
|
||||
#include "utils/rel.h"
|
||||
@@ -83,6 +85,7 @@ hashhandler(PG_FUNCTION_ARGS)
|
||||
amroutine->amcostestimate = hashcostestimate;
|
||||
amroutine->amoptions = hashoptions;
|
||||
amroutine->amproperty = NULL;
|
||||
amroutine->ambuildphasename = NULL;
|
||||
amroutine->amvalidate = hashvalidate;
|
||||
amroutine->ambeginscan = hashbeginscan;
|
||||
amroutine->amrescan = hashrescan;
|
||||
@@ -160,9 +163,11 @@ hashbuild(Relation heap, Relation index, IndexInfo *indexInfo)
|
||||
buildstate.heapRel = heap;
|
||||
|
||||
/* do the heap scan */
|
||||
reltuples = table_index_build_scan(heap, index, indexInfo, true,
|
||||
reltuples = table_index_build_scan(heap, index, indexInfo, true, true,
|
||||
hashbuildCallback,
|
||||
(void *) &buildstate, NULL);
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_TOTAL,
|
||||
buildstate.indtuples);
|
||||
|
||||
if (buildstate.spool)
|
||||
{
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/hash.h"
|
||||
#include "commands/progress.h"
|
||||
#include "miscadmin.h"
|
||||
#include "pgstat.h"
|
||||
#include "utils/tuplesort.h"
|
||||
|
||||
|
||||
@@ -116,6 +118,7 @@ void
|
||||
_h_indexbuild(HSpool *hspool, Relation heapRel)
|
||||
{
|
||||
IndexTuple itup;
|
||||
long tups_done = 0;
|
||||
#ifdef USE_ASSERT_CHECKING
|
||||
uint32 hashkey = 0;
|
||||
#endif
|
||||
@@ -141,5 +144,8 @@ _h_indexbuild(HSpool *hspool, Relation heapRel)
|
||||
#endif
|
||||
|
||||
_hash_doinsert(hspool->index, itup, heapRel);
|
||||
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_DONE,
|
||||
++tups_done);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,8 @@ static bool SampleHeapTupleVisible(TableScanDesc scan, Buffer buffer,
|
||||
HeapTuple tuple,
|
||||
OffsetNumber tupoffset);
|
||||
|
||||
static BlockNumber heapam_scan_get_blocks_done(HeapScanDesc hscan);
|
||||
|
||||
static const TableAmRoutine heapam_methods;
|
||||
|
||||
|
||||
@@ -1120,6 +1122,7 @@ heapam_index_build_range_scan(Relation heapRelation,
|
||||
IndexInfo *indexInfo,
|
||||
bool allow_sync,
|
||||
bool anyvisible,
|
||||
bool progress,
|
||||
BlockNumber start_blockno,
|
||||
BlockNumber numblocks,
|
||||
IndexBuildCallback callback,
|
||||
@@ -1140,6 +1143,7 @@ heapam_index_build_range_scan(Relation heapRelation,
|
||||
Snapshot snapshot;
|
||||
bool need_unregister_snapshot = false;
|
||||
TransactionId OldestXmin;
|
||||
BlockNumber previous_blkno = InvalidBlockNumber;
|
||||
BlockNumber root_blkno = InvalidBlockNumber;
|
||||
OffsetNumber root_offsets[MaxHeapTuplesPerPage];
|
||||
|
||||
@@ -1227,6 +1231,25 @@ heapam_index_build_range_scan(Relation heapRelation,
|
||||
|
||||
hscan = (HeapScanDesc) scan;
|
||||
|
||||
/* Publish number of blocks to scan */
|
||||
if (progress)
|
||||
{
|
||||
BlockNumber nblocks;
|
||||
|
||||
if (hscan->rs_base.rs_parallel != NULL)
|
||||
{
|
||||
ParallelBlockTableScanDesc pbscan;
|
||||
|
||||
pbscan = (ParallelBlockTableScanDesc) hscan->rs_base.rs_parallel;
|
||||
nblocks = pbscan->phs_nblocks;
|
||||
}
|
||||
else
|
||||
nblocks = hscan->rs_nblocks;
|
||||
|
||||
pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_TOTAL,
|
||||
nblocks);
|
||||
}
|
||||
|
||||
/*
|
||||
* Must call GetOldestXmin() with SnapshotAny. Should never call
|
||||
* GetOldestXmin() with MVCC snapshot. (It's especially worth checking
|
||||
@@ -1259,6 +1282,19 @@ heapam_index_build_range_scan(Relation heapRelation,
|
||||
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
|
||||
/* Report scan progress, if asked to. */
|
||||
if (progress)
|
||||
{
|
||||
BlockNumber blocks_done = heapam_scan_get_blocks_done(hscan);
|
||||
|
||||
if (blocks_done != previous_blkno)
|
||||
{
|
||||
pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_DONE,
|
||||
blocks_done);
|
||||
previous_blkno = blocks_done;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* When dealing with a HOT-chain of updated tuples, we want to index
|
||||
* the values of the live tuple (if any), but index it under the TID
|
||||
@@ -1600,6 +1636,25 @@ heapam_index_build_range_scan(Relation heapRelation,
|
||||
}
|
||||
}
|
||||
|
||||
/* Report scan progress one last time. */
|
||||
if (progress)
|
||||
{
|
||||
BlockNumber blks_done;
|
||||
|
||||
if (hscan->rs_base.rs_parallel != NULL)
|
||||
{
|
||||
ParallelBlockTableScanDesc pbscan;
|
||||
|
||||
pbscan = (ParallelBlockTableScanDesc) hscan->rs_base.rs_parallel;
|
||||
blks_done = pbscan->phs_nblocks;
|
||||
}
|
||||
else
|
||||
blks_done = hscan->rs_nblocks;
|
||||
|
||||
pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_DONE,
|
||||
blks_done);
|
||||
}
|
||||
|
||||
table_endscan(scan);
|
||||
|
||||
/* we can now forget our snapshot, if set and registered by us */
|
||||
@@ -1636,6 +1691,7 @@ heapam_index_validate_scan(Relation heapRelation,
|
||||
BlockNumber root_blkno = InvalidBlockNumber;
|
||||
OffsetNumber root_offsets[MaxHeapTuplesPerPage];
|
||||
bool in_index[MaxHeapTuplesPerPage];
|
||||
BlockNumber previous_blkno = InvalidBlockNumber;
|
||||
|
||||
/* state variables for the merge */
|
||||
ItemPointer indexcursor = NULL;
|
||||
@@ -1676,6 +1732,9 @@ heapam_index_validate_scan(Relation heapRelation,
|
||||
false); /* syncscan not OK */
|
||||
hscan = (HeapScanDesc) scan;
|
||||
|
||||
pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_TOTAL,
|
||||
hscan->rs_nblocks);
|
||||
|
||||
/*
|
||||
* Scan all tuples matching the snapshot.
|
||||
*/
|
||||
@@ -1689,6 +1748,14 @@ heapam_index_validate_scan(Relation heapRelation,
|
||||
|
||||
state->htups += 1;
|
||||
|
||||
if ((previous_blkno == InvalidBlockNumber) ||
|
||||
(hscan->rs_cblock != previous_blkno))
|
||||
{
|
||||
pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_DONE,
|
||||
hscan->rs_cblock);
|
||||
previous_blkno = hscan->rs_cblock;
|
||||
}
|
||||
|
||||
/*
|
||||
* As commented in table_index_build_scan, we should index heap-only
|
||||
* tuples under the TIDs of their root tuples; so when we advance onto
|
||||
@@ -1849,6 +1916,46 @@ heapam_index_validate_scan(Relation heapRelation,
|
||||
indexInfo->ii_PredicateState = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of blocks that have been read by this scan since
|
||||
* starting. This is meant for progress reporting rather than be fully
|
||||
* accurate: in a parallel scan, workers can be concurrently reading blocks
|
||||
* further ahead than what we report.
|
||||
*/
|
||||
static BlockNumber
|
||||
heapam_scan_get_blocks_done(HeapScanDesc hscan)
|
||||
{
|
||||
ParallelBlockTableScanDesc bpscan = NULL;
|
||||
BlockNumber startblock;
|
||||
BlockNumber blocks_done;
|
||||
|
||||
if (hscan->rs_base.rs_parallel != NULL)
|
||||
{
|
||||
bpscan = (ParallelBlockTableScanDesc) hscan->rs_base.rs_parallel;
|
||||
startblock = bpscan->phs_startblock;
|
||||
}
|
||||
else
|
||||
startblock = hscan->rs_startblock;
|
||||
|
||||
/*
|
||||
* Might have wrapped around the end of the relation, if startblock was
|
||||
* not zero.
|
||||
*/
|
||||
if (hscan->rs_cblock > startblock)
|
||||
blocks_done = hscan->rs_cblock - startblock;
|
||||
else
|
||||
{
|
||||
BlockNumber nblocks;
|
||||
|
||||
nblocks = bpscan != NULL ? bpscan->phs_nblocks : hscan->rs_nblocks;
|
||||
blocks_done = nblocks - startblock +
|
||||
hscan->rs_cblock;
|
||||
}
|
||||
|
||||
return blocks_done;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* Planner related callbacks for the heap AM
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "access/nbtxlog.h"
|
||||
#include "access/relscan.h"
|
||||
#include "access/xlog.h"
|
||||
#include "commands/progress.h"
|
||||
#include "commands/vacuum.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/execnodes.h"
|
||||
@@ -133,6 +134,7 @@ bthandler(PG_FUNCTION_ARGS)
|
||||
amroutine->amcostestimate = btcostestimate;
|
||||
amroutine->amoptions = btoptions;
|
||||
amroutine->amproperty = btproperty;
|
||||
amroutine->ambuildphasename = btbuildphasename;
|
||||
amroutine->amvalidate = btvalidate;
|
||||
amroutine->ambeginscan = btbeginscan;
|
||||
amroutine->amrescan = btrescan;
|
||||
@@ -1021,6 +1023,10 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
|
||||
if (needLock)
|
||||
UnlockRelationForExtension(rel, ExclusiveLock);
|
||||
|
||||
if (info->report_progress)
|
||||
pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_TOTAL,
|
||||
num_pages);
|
||||
|
||||
/* Quit if we've scanned the whole relation */
|
||||
if (blkno >= num_pages)
|
||||
break;
|
||||
@@ -1028,6 +1034,9 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
|
||||
for (; blkno < num_pages; blkno++)
|
||||
{
|
||||
btvacuumpage(&vstate, blkno, blkno);
|
||||
if (info->report_progress)
|
||||
pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_DONE,
|
||||
blkno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include "access/xlog.h"
|
||||
#include "access/xloginsert.h"
|
||||
#include "catalog/index.h"
|
||||
#include "commands/progress.h"
|
||||
#include "miscadmin.h"
|
||||
#include "pgstat.h"
|
||||
#include "storage/smgr.h"
|
||||
@@ -298,7 +299,8 @@ static double _bt_parallel_heapscan(BTBuildState *buildstate,
|
||||
static void _bt_leader_participate_as_worker(BTBuildState *buildstate);
|
||||
static void _bt_parallel_scan_and_sort(BTSpool *btspool, BTSpool *btspool2,
|
||||
BTShared *btshared, Sharedsort *sharedsort,
|
||||
Sharedsort *sharedsort2, int sortmem);
|
||||
Sharedsort *sharedsort2, int sortmem,
|
||||
bool progress);
|
||||
|
||||
|
||||
/*
|
||||
@@ -394,6 +396,10 @@ _bt_spools_heapscan(Relation heap, Relation index, BTBuildState *buildstate,
|
||||
/* Save as primary spool */
|
||||
buildstate->spool = btspool;
|
||||
|
||||
/* Report table scan phase started */
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE,
|
||||
PROGRESS_BTREE_PHASE_INDEXBUILD_TABLESCAN);
|
||||
|
||||
/* Attempt to launch parallel worker scan when required */
|
||||
if (indexInfo->ii_ParallelWorkers > 0)
|
||||
_bt_begin_parallel(buildstate, indexInfo->ii_Concurrent,
|
||||
@@ -480,13 +486,31 @@ _bt_spools_heapscan(Relation heap, Relation index, BTBuildState *buildstate,
|
||||
|
||||
/* Fill spool using either serial or parallel heap scan */
|
||||
if (!buildstate->btleader)
|
||||
reltuples = table_index_build_scan(heap, index, indexInfo, true,
|
||||
reltuples = table_index_build_scan(heap, index, indexInfo, true, true,
|
||||
_bt_build_callback, (void *) buildstate,
|
||||
NULL);
|
||||
else
|
||||
reltuples = _bt_parallel_heapscan(buildstate,
|
||||
&indexInfo->ii_BrokenHotChain);
|
||||
|
||||
/*
|
||||
* Set the progress target for the next phase. Reset the block number
|
||||
* values set by table_index_build_scan
|
||||
*/
|
||||
{
|
||||
const int index[] = {
|
||||
PROGRESS_CREATEIDX_TUPLES_TOTAL,
|
||||
PROGRESS_SCAN_BLOCKS_TOTAL,
|
||||
PROGRESS_SCAN_BLOCKS_DONE
|
||||
};
|
||||
const int64 val[] = {
|
||||
buildstate->indtuples,
|
||||
0, 0
|
||||
};
|
||||
|
||||
pgstat_progress_update_multi_param(3, index, val);
|
||||
}
|
||||
|
||||
/* okay, all heap tuples are spooled */
|
||||
if (buildstate->spool2 && !buildstate->havedead)
|
||||
{
|
||||
@@ -535,9 +559,15 @@ _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2)
|
||||
}
|
||||
#endif /* BTREE_BUILD_STATS */
|
||||
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE,
|
||||
PROGRESS_BTREE_PHASE_PERFORMSORT_1);
|
||||
tuplesort_performsort(btspool->sortstate);
|
||||
if (btspool2)
|
||||
{
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE,
|
||||
PROGRESS_BTREE_PHASE_PERFORMSORT_2);
|
||||
tuplesort_performsort(btspool2->sortstate);
|
||||
}
|
||||
|
||||
wstate.heap = btspool->heap;
|
||||
wstate.index = btspool->index;
|
||||
@@ -554,6 +584,8 @@ _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2)
|
||||
wstate.btws_pages_written = 0;
|
||||
wstate.btws_zeropage = NULL; /* until needed */
|
||||
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE,
|
||||
PROGRESS_BTREE_PHASE_LEAF_LOAD);
|
||||
_bt_load(&wstate, btspool, btspool2);
|
||||
}
|
||||
|
||||
@@ -1098,6 +1130,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
|
||||
int i,
|
||||
keysz = IndexRelationGetNumberOfKeyAttributes(wstate->index);
|
||||
SortSupport sortKeys;
|
||||
long tuples_done = 0;
|
||||
|
||||
if (merge)
|
||||
{
|
||||
@@ -1202,6 +1235,10 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
|
||||
_bt_buildadd(wstate, state, itup2);
|
||||
itup2 = tuplesort_getindextuple(btspool2->sortstate, true);
|
||||
}
|
||||
|
||||
/* Report progress */
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_DONE,
|
||||
++tuples_done);
|
||||
}
|
||||
pfree(sortKeys);
|
||||
}
|
||||
@@ -1216,6 +1253,10 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
|
||||
state = _bt_pagestate(wstate, 0);
|
||||
|
||||
_bt_buildadd(wstate, state, itup);
|
||||
|
||||
/* Report progress */
|
||||
pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_DONE,
|
||||
++tuples_done);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1528,7 +1569,7 @@ _bt_leader_participate_as_worker(BTBuildState *buildstate)
|
||||
/* Perform work common to all participants */
|
||||
_bt_parallel_scan_and_sort(leaderworker, leaderworker2, btleader->btshared,
|
||||
btleader->sharedsort, btleader->sharedsort2,
|
||||
sortmem);
|
||||
sortmem, true);
|
||||
|
||||
#ifdef BTREE_BUILD_STATS
|
||||
if (log_btree_build_stats)
|
||||
@@ -1619,7 +1660,7 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc)
|
||||
/* Perform sorting of spool, and possibly a spool2 */
|
||||
sortmem = maintenance_work_mem / btshared->scantuplesortstates;
|
||||
_bt_parallel_scan_and_sort(btspool, btspool2, btshared, sharedsort,
|
||||
sharedsort2, sortmem);
|
||||
sharedsort2, sortmem, false);
|
||||
|
||||
#ifdef BTREE_BUILD_STATS
|
||||
if (log_btree_build_stats)
|
||||
@@ -1648,7 +1689,7 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc)
|
||||
static void
|
||||
_bt_parallel_scan_and_sort(BTSpool *btspool, BTSpool *btspool2,
|
||||
BTShared *btshared, Sharedsort *sharedsort,
|
||||
Sharedsort *sharedsort2, int sortmem)
|
||||
Sharedsort *sharedsort2, int sortmem, bool progress)
|
||||
{
|
||||
SortCoordinate coordinate;
|
||||
BTBuildState buildstate;
|
||||
@@ -1705,9 +1746,10 @@ _bt_parallel_scan_and_sort(BTSpool *btspool, BTSpool *btspool2,
|
||||
/* Join parallel scan */
|
||||
indexInfo = BuildIndexInfo(btspool->index);
|
||||
indexInfo->ii_Concurrent = btshared->isconcurrent;
|
||||
scan = table_beginscan_parallel(btspool->heap, ParallelTableScanFromBTShared(btshared));
|
||||
scan = table_beginscan_parallel(btspool->heap,
|
||||
ParallelTableScanFromBTShared(btshared));
|
||||
reltuples = table_index_build_scan(btspool->heap, btspool->index, indexInfo,
|
||||
true, _bt_build_callback,
|
||||
true, progress, _bt_build_callback,
|
||||
(void *) &buildstate, scan);
|
||||
|
||||
/*
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "access/nbtree.h"
|
||||
#include "access/reloptions.h"
|
||||
#include "access/relscan.h"
|
||||
#include "commands/progress.h"
|
||||
#include "miscadmin.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/datum.h"
|
||||
@@ -2051,6 +2052,29 @@ btproperty(Oid index_oid, int attno,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* btbuildphasename() -- Return name of index build phase.
|
||||
*/
|
||||
char *
|
||||
btbuildphasename(int64 phasenum)
|
||||
{
|
||||
switch (phasenum)
|
||||
{
|
||||
case PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE:
|
||||
return "initializing";
|
||||
case PROGRESS_BTREE_PHASE_INDEXBUILD_TABLESCAN:
|
||||
return "scanning table";
|
||||
case PROGRESS_BTREE_PHASE_PERFORMSORT_1:
|
||||
return "sorting live tuples";
|
||||
case PROGRESS_BTREE_PHASE_PERFORMSORT_2:
|
||||
return "sorting dead tuples";
|
||||
case PROGRESS_BTREE_PHASE_LEAF_LOAD:
|
||||
return "loading tuples in tree";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* _bt_truncate() -- create tuple without unneeded suffix attributes.
|
||||
*
|
||||
|
||||
@@ -143,7 +143,7 @@ spgbuild(Relation heap, Relation index, IndexInfo *indexInfo)
|
||||
"SP-GiST build temporary context",
|
||||
ALLOCSET_DEFAULT_SIZES);
|
||||
|
||||
reltuples = table_index_build_scan(heap, index, indexInfo, true,
|
||||
reltuples = table_index_build_scan(heap, index, indexInfo, true, true,
|
||||
spgistBuildCallback, (void *) &buildstate,
|
||||
NULL);
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ spghandler(PG_FUNCTION_ARGS)
|
||||
amroutine->amcostestimate = spgcostestimate;
|
||||
amroutine->amoptions = spgoptions;
|
||||
amroutine->amproperty = spgproperty;
|
||||
amroutine->ambuildphasename = NULL;
|
||||
amroutine->amvalidate = spgvalidate;
|
||||
amroutine->ambeginscan = spgbeginscan;
|
||||
amroutine->amrescan = spgrescan;
|
||||
|
||||
Reference in New Issue
Block a user