diff options
| author | Alexander Korotkov | 2024-03-30 20:34:04 +0000 |
|---|---|---|
| committer | Alexander Korotkov | 2024-03-30 20:34:04 +0000 |
| commit | 27bc1772fc814946918a5ac8ccb9b5c5ad0380aa (patch) | |
| tree | beb4fac8dfb2756c86f3ac13ec21d72f69daa55c /src/include/access | |
| parent | b154d8a6d0e52e5f6b09739639fdf55fa88bc6b8 (diff) | |
Generalize relation analyze in table AM interface
Currently, there is just one algorithm for sampling tuples from a table written
in acquire_sample_rows(). Custom table AM can just redefine the way to get the
next block/tuple by implementing scan_analyze_next_block() and
scan_analyze_next_tuple() API functions.
This approach doesn't seem general enough. For instance, it's unclear how to
sample this way index-organized tables. This commit allows table AM to
encapsulate the whole sampling algorithm (currently implemented in
acquire_sample_rows()) into the relation_analyze() API function.
Discussion: https://postgr.es/m/CAPpHfdurb9ycV8udYqM%3Do0sPS66PJ4RCBM1g-bBpvzUfogY0EA%40mail.gmail.com
Reviewed-by: Pavel Borisov, Matthias van de Meent
Diffstat (limited to 'src/include/access')
| -rw-r--r-- | src/include/access/heapam.h | 9 | ||||
| -rw-r--r-- | src/include/access/tableam.h | 106 |
2 files changed, 31 insertions, 84 deletions
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index f1122453738..91fbc950343 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -369,6 +369,15 @@ extern bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple); extern bool HeapTupleIsSurelyDead(HeapTuple htup, struct GlobalVisState *vistest); +/* in heap/heapam_handler.c*/ +extern void heapam_scan_analyze_next_block(TableScanDesc scan, + BlockNumber blockno, + BufferAccessStrategy bstrategy); +extern bool heapam_scan_analyze_next_tuple(TableScanDesc scan, + TransactionId OldestXmin, + double *liverows, double *deadrows, + TupleTableSlot *slot); + /* * To avoid leaking too much knowledge about reorderbuffer implementation * details this is implemented in reorderbuffer.c not heapam_visibility.c diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index fc0e7027157..8ed4e7295ad 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -20,6 +20,7 @@ #include "access/relscan.h" #include "access/sdir.h" #include "access/xact.h" +#include "commands/vacuum.h" #include "executor/tuptable.h" #include "utils/rel.h" #include "utils/snapshot.h" @@ -658,41 +659,6 @@ typedef struct TableAmRoutine struct VacuumParams *params, BufferAccessStrategy bstrategy); - /* - * Prepare to analyze block `blockno` of `scan`. The scan has been started - * with table_beginscan_analyze(). See also - * table_scan_analyze_next_block(). - * - * The callback may acquire resources like locks that are held until - * table_scan_analyze_next_tuple() returns false. It e.g. can make sense - * to hold a lock until all tuples on a block have been analyzed by - * scan_analyze_next_tuple. - * - * The callback can return false if the block is not suitable for - * sampling, e.g. because it's a metapage that could never contain tuples. - * - * XXX: This obviously is primarily suited for block-based AMs. It's not - * clear what a good interface for non block based AMs would be, so there - * isn't one yet. - */ - bool (*scan_analyze_next_block) (TableScanDesc scan, - BlockNumber blockno, - BufferAccessStrategy bstrategy); - - /* - * See table_scan_analyze_next_tuple(). - * - * Not every AM might have a meaningful concept of dead rows, in which - * case it's OK to not increment *deadrows - but note that that may - * influence autovacuum scheduling (see comment for relation_vacuum - * callback). - */ - bool (*scan_analyze_next_tuple) (TableScanDesc scan, - TransactionId OldestXmin, - double *liverows, - double *deadrows, - TupleTableSlot *slot); - /* see table_index_build_range_scan for reference about parameters */ double (*index_build_range_scan) (Relation table_rel, Relation index_rel, @@ -713,6 +679,12 @@ typedef struct TableAmRoutine Snapshot snapshot, struct ValidateIndexState *state); + /* See table_relation_analyze() */ + void (*relation_analyze) (Relation relation, + AcquireSampleRowsFunc *func, + BlockNumber *totalpages, + BufferAccessStrategy bstrategy); + /* ------------------------------------------------------------------------ * Miscellaneous functions. @@ -1009,19 +981,6 @@ table_beginscan_tid(Relation rel, Snapshot snapshot) } /* - * table_beginscan_analyze is an alternative entry point for setting up a - * TableScanDesc for an ANALYZE scan. As with bitmap scans, it's worth using - * the same data structure although the behavior is rather different. - */ -static inline TableScanDesc -table_beginscan_analyze(Relation rel) -{ - uint32 flags = SO_TYPE_ANALYZE; - - return rel->rd_tableam->scan_begin(rel, NULL, 0, NULL, NULL, flags); -} - -/* * End relation scan. */ static inline void @@ -1747,42 +1706,6 @@ table_relation_vacuum(Relation rel, struct VacuumParams *params, } /* - * Prepare to analyze block `blockno` of `scan`. The scan needs to have been - * started with table_beginscan_analyze(). Note that this routine might - * acquire resources like locks that are held until - * table_scan_analyze_next_tuple() returns false. - * - * Returns false if block is unsuitable for sampling, true otherwise. - */ -static inline bool -table_scan_analyze_next_block(TableScanDesc scan, BlockNumber blockno, - BufferAccessStrategy bstrategy) -{ - return scan->rs_rd->rd_tableam->scan_analyze_next_block(scan, blockno, - bstrategy); -} - -/* - * Iterate over tuples in the block selected with - * table_scan_analyze_next_block() (which needs to have returned true, and - * this routine may not have returned false for the same block before). If a - * tuple that's suitable for sampling is found, true is returned and a tuple - * is stored in `slot`. - * - * *liverows and *deadrows are incremented according to the encountered - * tuples. - */ -static inline bool -table_scan_analyze_next_tuple(TableScanDesc scan, TransactionId OldestXmin, - double *liverows, double *deadrows, - TupleTableSlot *slot) -{ - return scan->rs_rd->rd_tableam->scan_analyze_next_tuple(scan, OldestXmin, - liverows, deadrows, - slot); -} - -/* * table_index_build_scan - scan the table to find tuples to be indexed * * This is called back from an access-method-specific index build procedure @@ -1887,6 +1810,21 @@ table_index_validate_scan(Relation table_rel, state); } +/* + * table_relation_analyze - fill the infromation for a sampling statistics + * acquisition + * + * The pointer to a function that will collect sample rows from the table + * should be stored to `*func`, plus the estimated size of the table in pages + * should br stored to `*totalpages`. + */ +static inline void +table_relation_analyze(Relation relation, AcquireSampleRowsFunc *func, + BlockNumber *totalpages, BufferAccessStrategy bstrategy) +{ + relation->rd_tableam->relation_analyze(relation, func, + totalpages, bstrategy); +} /* ---------------------------------------------------------------------------- * Miscellaneous functionality |
