Extend Table AM routine to get total blocks can be analyzed
Started by Pengzhou Tangabout 6 years ago1 messages
Hi Hackers,
Table AM routine already provided two custom functions to fetch sample
blocks and sample tuples,
however, the total blocks the ANALYZE can scan are still restricted to the
number of physical blocks
in a table, this doesn't work well for storages which organize blocks in
different ways than the heap.
Here is proposing to add a new method named scan_analyze_total_blocks() to
provide more flexibility,
it can return physical or logical blocks number which depends on how the
table AM implement
scan_analyze_next_block() and scan_analyze_next_tuple().
Attachments:
v1-0001-extend-tableam-scan-analyze-total-blocks.patchapplication/octet-stream; name=v1-0001-extend-tableam-scan-analyze-total-blocks.patchDownload
From ac9aff839a258e7f24cb3f27d4ae107cc327af33 Mon Sep 17 00:00:00 2001
From: Pengzhou Tang <ptang@pivotal.io>
Date: Mon, 11 Nov 2019 02:35:51 -0500
Subject: [PATCH] Extend Table AM routine to get total blocks can be analyzed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Table AM routine already provided two custom functions to fetch sample
blocks and sample tuples, however, the total blocks the ANALYZE can scan
is still restricted to the number of physical blocks in a table, this is
a big restriction for storages which organize blocks in different ways.
A new method named scan_analyze_total_blocks() is added to provide
more flexibility, it can returns physical or logical blocks number which
depends on how the table AM implement scan_analyze_next_block() and
scan_analyze_next_tuple().
---
src/backend/access/heap/heapam_handler.c | 8 ++++++++
src/backend/commands/analyze.c | 8 ++++----
src/include/access/tableam.h | 18 ++++++++++++++++++
3 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index 7081172..bec3ae6 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -977,6 +977,13 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
pfree(isnull);
}
+static int
+heapam_scan_analyze_total_blocks(TableScanDesc scan)
+{
+ Assert(scan->rs_rd);
+ return RelationGetNumberOfBlocks(scan->rs_rd);
+}
+
static bool
heapam_scan_analyze_next_block(TableScanDesc scan, BlockNumber blockno,
BufferAccessStrategy bstrategy)
@@ -2531,6 +2538,7 @@ static const TableAmRoutine heapam_methods = {
.relation_copy_data = heapam_relation_copy_data,
.relation_copy_for_cluster = heapam_relation_copy_for_cluster,
.relation_vacuum = heap_vacuum_rel,
+ .scan_analyze_total_blocks = heapam_scan_analyze_total_blocks,
.scan_analyze_next_block = heapam_scan_analyze_next_block,
.scan_analyze_next_tuple = heapam_scan_analyze_next_tuple,
.index_build_range_scan = heapam_index_build_range_scan,
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 7accb95..f9467b3 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -1037,7 +1037,10 @@ acquire_sample_rows(Relation onerel, int elevel,
Assert(targrows > 0);
- totalblocks = RelationGetNumberOfBlocks(onerel);
+ scan = table_beginscan_analyze(onerel);
+ slot = table_slot_create(onerel, NULL);
+
+ totalblocks = table_scan_analyze_total_blocks(scan);
/* Need a cutoff xmin for HeapTupleSatisfiesVacuum */
OldestXmin = GetOldestXmin(onerel, PROCARRAY_FLAGS_VACUUM);
@@ -1047,9 +1050,6 @@ acquire_sample_rows(Relation onerel, int elevel,
/* Prepare for sampling rows */
reservoir_init_selection_state(&rstate, targrows);
- scan = table_beginscan_analyze(onerel);
- slot = table_slot_create(onerel, NULL);
-
/* Outer loop over blocks to sample */
while (BlockSampler_HasMore(&bs))
{
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index 6402291..e47c370 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -501,6 +501,13 @@ typedef struct TableAmRoutine
BufferAccessStrategy bstrategy);
/*
+ * The total blocks the analyze can scan, it can be the physical number of
+ * blocks or the logical number, it depends on how the table AM implement
+ * scan_analyze_next_block() and scan_analyze_next_tuple().
+ */
+ BlockNumber (*scan_analyze_total_blocks) (TableScanDesc scan);
+
+ /*
* Prepare to analyze block `blockno` of `scan`. The scan has been started
* with table_beginscan_analyze(). See also
* table_scan_analyze_next_block().
@@ -1433,6 +1440,17 @@ table_relation_vacuum(Relation rel, struct VacuumParams *params,
}
/*
+ * The total blocks the analyze can scan, it can be the physical number of
+ * blocks or the logical number, it depends on how the table AM implement
+ * table_scan_analyze_next_block() and table_scan_analyze_next_tuple().
+ */
+static inline BlockNumber
+table_scan_analyze_total_blocks(TableScanDesc scan)
+{
+ return scan->rs_rd->rd_tableam->scan_analyze_total_blocks(scan);
+}
+
+/*
* 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
--
1.8.3.1