On Wed, Feb 15, 2012 at 2:54 AM, Tom Lane <t...@sss.pgh.pa.us> wrote:
> Alexander Korotkov <aekorot...@gmail.com> writes: > > ITSM, I found the problem. This piece of code is triggering an error. It > > assumes each page of corresponding to have initialized buffer. That > should > > be true because we're inserting index tuples from up to down while > > splits propagate from down to up. > > But this assumptions becomes false we turn buffer off in the root page. > So, > > root page can produce pages without initialized buffers when splits. > > Hmm ... can we tighten the error check rather than just remove it? It > feels less than safe to assume that a hash-entry-not-found condition > *must* reflect a corner-case situation like that. At the very least > I'd like to see it verify that we'd turned off buffering before deciding > this is OK. Better, would it be practical to make dummy entries in the > hash table even after turning buffers off, so that the logic here > becomes > > if (!found) error; > else if (entry is dummy) return without doing anything; > else proceed; > > regards, tom lane > Ok, there is another patch fixes this problem. Instead of error triggering remove it adds empty buffers on root page split if needed. ------ With best regards, Alexander Korotkov.
*** a/src/backend/access/gist/gistbuild.c --- b/src/backend/access/gist/gistbuild.c *************** *** 668,677 **** gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, if (is_split && BufferGetBlockNumber(buffer) == GIST_ROOT_BLKNO) { GISTBufferingInsertStack *oldroot = gfbb->rootitem; ! Page page = BufferGetPage(buffer); ! ItemId iid; ! IndexTuple idxtuple; ! BlockNumber leftmostchild; gfbb->rootitem = (GISTBufferingInsertStack *) MemoryContextAlloc( gfbb->context, sizeof(GISTBufferingInsertStack)); --- 668,678 ---- if (is_split && BufferGetBlockNumber(buffer) == GIST_ROOT_BLKNO) { GISTBufferingInsertStack *oldroot = gfbb->rootitem; ! Page page = BufferGetPage(buffer); ! ItemId iid; ! IndexTuple idxtuple; ! BlockNumber leftmostchild; ! OffsetNumber maxoff, i; gfbb->rootitem = (GISTBufferingInsertStack *) MemoryContextAlloc( gfbb->context, sizeof(GISTBufferingInsertStack)); *************** *** 694,699 **** gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, --- 695,719 ---- oldroot->parent = gfbb->rootitem; oldroot->blkno = leftmostchild; oldroot->downlinkoffnum = InvalidOffsetNumber; + + /* + * If root page split produce new pages on leven which have buffers + * then initialize empty buffers there. + */ + if (LEVEL_HAS_BUFFERS(oldroot->level, gfbb)) + { + maxoff = PageGetMaxOffsetNumber(page); + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + { + iid = PageGetItemId(page, i); + idxtuple = (IndexTuple) PageGetItem(page, iid); + gistGetNodeBuffer(gfbb, + buildstate->giststate, + ItemPointerGetBlockNumber(&(idxtuple->t_tid)), + i, + gfbb->rootitem); + } + } } if (splitinfo)
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers