On 9/3/2015 5:49 PM, Tatsuo Ishii wrote:
>
> However I inserted data *after* creating index, the value is
> different.
> VACUUM;
> VACUUM
> SELECT * FROM brin_revmap_data(get_raw_page('brinidx', 1)) WHERE pages !=
> '(0,0)'::tid;
> pages
> -------
> (2,1)
> (2,2)
> (2,3)
> (2,4)
> (4 rows)
>
> SELECT * FROM brin_page_items(get_raw_page('brinidx', 2), 'brinidx');
> itemoffset | blknum | attnum | allnulls | hasnulls | placeholder |
> value
> ------------+--------+--------+----------+----------+-------------+------------------
> 1 | 0 | 1 | f | f | f | {1 ..
> 28928}
> 2 | 128 | 1 | f | f | f | {28929 ..
> 57856}
> 3 | 256 | 1 | f | f | f | {57857 ..
> 86784}
> 4 | 384 | 1 | f | f | f | {1 ..
> 100000}
> (4 rows)
> ===============================================================
>
> How the index value for block 384 could be {1 .. 100000}?
>
The summarization during VACUUM invokes IndexBuildHeapRangeScan() which is
passed scanStartBlock and scanNumBlocks. If scanStartBlock + scanNumBlocks
> heapTotalBlocks, further down the line, heapgettup() may start returning
tuples from the beginning given the following code in it:
page++;
if (page >= scan->rs_nblocks)
page = 0;
finished = (page == scan->rs_startblock) ||
(scan->rs_numblocks != InvalidBlockNumber ?
--scan->rs_numblocks == 0 :
false);
Where finished indicates whether it thinks the end of heap is reached.
In this case, scan->rs_startblock is 384 set by IndexBuildHeapRangeScan()
using heap_setscanlimits(). One can imagine how the above heap finish
criteria might not work as expected.
That helps explain why 1 becomes the min for that brin tuple.
Attached hack fixes the symptom but perhaps not the correct fix for this.
Thanks,
Amit
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index e59b163..9c7fafd 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -2268,7 +2268,11 @@ IndexBuildHeapRangeScan(Relation heapRelation,
/* set our scan endpoints */
if (!allow_sync)
+ {
+ numblocks = (start_blockno + numblocks <= scan->rs_nblocks)
+ ? numblocks : scan->rs_nblocks - start_blockno;
heap_setscanlimits(scan, start_blockno, numblocks);
+ }
else
{
/* syncscan can only be requested on whole relation */
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers