Skip to content

Commit

Permalink
ao: Scan progress reporting for CREATE INDEX
Browse files Browse the repository at this point in the history
This enables reporting for the table scan phase of index builds on AO
tables. This directly affects:
(1) pg_stat_progress_create_index.blocks_total
(2) pg_stat_progress_create_index.blocks_done

Sample:

Connect in utility mode to a segment, while CREATE INDEX is running on
an AO table:

postgres=# select pid, command, phase, blocks_total, blocks_done from pg_stat_progress_create_index;
  pid   |   command    |             phase              | blocks_total | blocks_done
--------+--------------+--------------------------------+--------------+-------------
 633034 | CREATE INDEX | building index: scanning table |        54993 |        4412
(1 row)

This commit introduces:

(1) Accounting in AppendOnlyScanDescData to track the total number of
bytes read across all segment files. It is updated whenever a new block
is read. If the block is compressed, its compressed length is added
(uncompressed length otherwise).

(2) Reporting code in appendonly_index_build_range_scan() to report in
increments of BLCKSZ, the number of blocks scanned so far. The total
number of blocks to be scanned is also published up front and is
determined by summing the compressed eof values of all segfiles.

(3) Marks RelationGuessNumberOfBlocksFromSize() as inline, since it is
now being called in a much hotter code path.

Note: We currently only support reporting for non-concurrent index
builds and serial builds.
  • Loading branch information
soumyadeep2007 authored and reshke committed Jan 28, 2025
1 parent 45a3e81 commit 500c213
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 18 deletions.
7 changes: 7 additions & 0 deletions src/backend/access/appendonly/appendonlyam.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ static void appendonly_insert_finish_guts(AppendOnlyInsertDesc aoInsertDesc);

/* Hook for plugins to get control in appendonly_delete() */
appendonly_delete_hook_type appendonly_delete_hook = NULL;
static void AppendOnlyScanDesc_UpdateTotalBytesRead(
AppendOnlyScanDesc scan);

/* ----------------
* initscan - scan code common to appendonly_beginscan and appendonly_rescan
Expand Down Expand Up @@ -1251,6 +1253,8 @@ getNextBlock(AppendOnlyScanDesc scan)
AppendOnlyExecutorReadBlock_GetContents(
&scan->executorReadBlock);

AppendOnlyScanDesc_UpdateTotalBytesRead(scan);

return true;
}

Expand Down Expand Up @@ -1583,6 +1587,9 @@ appendonly_beginrangescan_internal(Relation relation,
AccessShareLock,
appendOnlyMetaDataSnapshot);
}

scan->totalBytesRead = 0;

return scan;
}

Expand Down
20 changes: 16 additions & 4 deletions src/backend/access/appendonly/appendonlyam_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "catalog/storage_xlog.h"
#include "cdb/cdbappendonlyam.h"
#include "cdb/cdbvars.h"
#include "commands/progress.h"
#include "commands/vacuum.h"
#include "commands/progress.h"
#include "executor/executor.h"
Expand Down Expand Up @@ -1572,7 +1573,7 @@ appendonly_index_build_range_scan(Relation heapRelation,
FileSegInfo **seginfo = NULL;
int segfile_count;
int64 total_blockcount = 0;
AppendOnlyScanDesc hscan;
int64 previous_blkno = -1;

/*
* sanity checks
Expand Down Expand Up @@ -1720,10 +1721,22 @@ appendonly_index_build_range_scan(Relation heapRelation,
(numblocks != InvalidBlockNumber && ItemPointerGetBlockNumber(&slot->tts_tid) >= numblocks))
continue;

/* Report scan progress, if asked to. */
if (progress)
{
hscan = (AppendOnlyScanDesc) &aoscan->rs_base;
pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_DONE, hscan->rs_nblocks);
int64 current_blkno =
RelationGuessNumberOfBlocksFromSize(aoscan->totalBytesRead);

/* XXX: How can we report for builds with parallel scans? */
Assert(!aoscan->rs_base.rs_parallel);

/* As soon as a new block starts, report it as scanned */
if (current_blkno != previous_blkno)
{
pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_DONE,
current_blkno);
previous_blkno = current_blkno;
}
}

aoTupleId = (AOTupleId *) &slot->tts_tid;
Expand Down Expand Up @@ -1820,7 +1833,6 @@ appendonly_index_validate_scan(Relation heapRelation,
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("index validate scan - feature not supported on appendoptimized relations")));

}

/* ------------------------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions src/backend/cdb/cdbappendonlystorageread.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "cdb/cdbappendonlystorageformat.h"
#include "cdb/cdbappendonlystorageread.h"
#include "storage/gp_compress.h"
#include "utils/faultinjector.h"
#include "utils/guc.h"


Expand Down Expand Up @@ -1011,6 +1012,8 @@ AppendOnlyStorageRead_ReadNextBlock(AppendOnlyStorageRead *storageRead)
/* UNDONE: Finish the read for the information only header. */
}

SIMPLE_FAULT_INJECTOR("AppendOnlyStorageRead_ReadNextBlock_success");

return true;
}

Expand Down
13 changes: 0 additions & 13 deletions src/backend/storage/buffer/bufmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -3168,19 +3168,6 @@ RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
return 0; /* keep compiler quiet */
}

/*
* GPDB: it is possible to need to calculate the number of blocks from the table
* size. An example use case is when we are the dispatcher and we need to
* acquire the number of blocks from all segments.
*
* Use the same calculation that RelationGetNumberOfBlocksInFork is using.
*/
BlockNumber
RelationGuessNumberOfBlocksFromSize(uint64 szbytes)
{
return (szbytes + (BLCKSZ - 1)) / BLCKSZ;
}

/*
* BufferIsPermanent
* Determines whether a buffer will potentially still be around after
Expand Down
20 changes: 20 additions & 0 deletions src/include/cdb/cdbappendonlyam.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ typedef struct AppendOnlyScanDescData
/* used in predicate pushdown */
ExprContext *aos_pushdown_econtext;
ExprState *aos_pushdown_qual;
/*
* The total number of bytes read, compressed, across all segment files, so
* far. This is used for scan progress reporting.
*/
int64 totalBytesRead;

} AppendOnlyScanDescData;

Expand Down Expand Up @@ -494,5 +499,20 @@ extern bool AppendOnlyExecutorReadBlock_ScanNextTuple(AppendOnlyExecutorReadBloc
TupleTableSlot *slot);

extern void AppendOnlyExecutorReadBlock_GetContents(AppendOnlyExecutorReadBlock *executorReadBlock);
/*
* Update total bytes read for the entire scan. If the block was compressed,
* update it with the compressed length. If the block was not compressed, update
* it with the uncompressed length.
*/
static inline void
AppendOnlyScanDesc_UpdateTotalBytesRead(AppendOnlyScanDesc scan)
{
Assert(scan->storageRead.isActive);

if (scan->storageRead.current.isCompressed)
scan->totalBytesRead += scan->storageRead.current.compressedLen;
else
scan->totalBytesRead += scan->storageRead.current.uncompressedLen;
}

#endif /* CDBAPPENDONLYAM_H */
13 changes: 12 additions & 1 deletion src/include/storage/bufmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,18 @@ extern void DropRelFileNodeBuffers(struct SMgrRelationData *smgr_reln, ForkNumbe
extern void DropRelFileNodesAllBuffers(struct SMgrRelationData **smgr_reln, int nnodes);
extern void DropDatabaseBuffers(Oid dbid);

extern BlockNumber RelationGuessNumberOfBlocksFromSize(uint64 szbytes);
/*
* GPDB: it is possible to need to calculate the number of blocks from the table
* size. An example use case is when we are the dispatcher and we need to
* acquire the number of blocks from all segments.
*
* Use the same calculation that RelationGetNumberOfBlocksInFork is using.
*/
static inline BlockNumber
RelationGuessNumberOfBlocksFromSize(uint64 szbytes)
{
return (szbytes + (BLCKSZ - 1)) / BLCKSZ;
}

#define RelationGetNumberOfBlocks(reln) \
RelationGetNumberOfBlocksInFork(reln, MAIN_FORKNUM)
Expand Down
2 changes: 2 additions & 0 deletions src/test/isolation2/isolation2_schedule
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ test: idle_gang_cleaner
# test idle_in_transaction_session_timeout
test: write_gang_idle_in_transaction_session_timeout

test: ao_index_build_progress

# Tests for FTS
test: fts_errors
test: segwalrep/replication_keeps_crash
Expand Down

0 comments on commit 500c213

Please sign in to comment.