Fix brin index summarizing while vacuuming.
authorTatsuo Ishii <ishii@postgresql.org>
Sat, 5 Sep 2015 00:19:25 +0000 (09:19 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Sat, 5 Sep 2015 00:19:25 +0000 (09:19 +0900)
If the number of heap blocks is not multiples of pages per range, the
summarizing produces wrong summary information for the last brin index
tuple while vacuuming.

Problem reported by Tatsuo Ishii and fixed by Amit Langote.

Discussion at "[HACKERS] BRIN INDEX value (message id :20150903.174935.1946402199422994347.t-ishii@sraoss.co.jp)
Backpatched to 9.5 in which brin index was added.

src/backend/access/brin/brin.c

index 25d2a094ddad877df855e1fb6bde73ee6c115d96..99337b0f0c047ab33277f4e0fca342095a5e2a39 100644 (file)
@@ -934,12 +934,13 @@ terminate_brin_buildstate(BrinBuildState *state)
  */
 static void
 summarize_range(IndexInfo *indexInfo, BrinBuildState *state, Relation heapRel,
-               BlockNumber heapBlk)
+               BlockNumber heapBlk, BlockNumber heapNumBlks)
 {
    Buffer      phbuf;
    BrinTuple  *phtup;
    Size        phsz;
    OffsetNumber offset;
+   BlockNumber scanNumBlks;
 
    /*
     * Insert the placeholder tuple
@@ -960,8 +961,10 @@ summarize_range(IndexInfo *indexInfo, BrinBuildState *state, Relation heapRel,
     * by transactions that are still in progress, among other corner cases.
     */
    state->bs_currRangeStart = heapBlk;
+   scanNumBlks = heapBlk + state->bs_pagesPerRange <= heapNumBlks ?
+                       state->bs_pagesPerRange : heapNumBlks - heapBlk;
    IndexBuildHeapRangeScan(heapRel, state->bs_irel, indexInfo, false, true,
-                           heapBlk, state->bs_pagesPerRange,
+                           heapBlk, scanNumBlks,
                            brinbuildCallback, (void *) state);
 
    /*
@@ -1066,7 +1069,7 @@ brinsummarize(Relation index, Relation heapRel, double *numSummarized,
                                                   pagesPerRange);
                indexInfo = BuildIndexInfo(index);
            }
-           summarize_range(indexInfo, state, heapRel, heapBlk);
+           summarize_range(indexInfo, state, heapRel, heapBlk, heapNumBlocks);
 
            /* and re-initialize state for the next range */
            brin_memtuple_initialize(state->bs_dtuple, state->bs_bdesc);