1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-14 08:21:07 +03:00

Fix coredump during replay WAL after crash. Change entrySplitPage() to prevent

usage of any information from system catalog, because it could be called during
replay of WAL.

Per bug report from Craig McElroy <craig.mcelroy@contegix.com>. Patch doesn't
change on-disk storage.
This commit is contained in:
Teodor Sigaev
2007-10-29 13:49:21 +00:00
parent 811be893fa
commit 85376c6f7d

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gin/ginentrypage.c,v 1.9 2007/09/20 17:56:30 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/gin/ginentrypage.c,v 1.10 2007/10/29 13:49:21 teodor Exp $
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -403,6 +403,31 @@ entryPlaceToPage(GinBtree btree, Buffer buf, OffsetNumber off, XLogRecData **prd
btree->entry = NULL; btree->entry = NULL;
} }
/*
* Returns new tuple with copied value from source tuple.
* New tuple will not store posting list
*/
static IndexTuple
copyIndexTuple(IndexTuple itup, Page page)
{
IndexTuple nitup;
if (GinPageIsLeaf(page) && !GinIsPostingTree(itup))
{
nitup = (IndexTuple) palloc(MAXALIGN(GinGetOrigSizePosting(itup)));
memcpy(nitup, itup, GinGetOrigSizePosting(itup));
nitup->t_info &= ~INDEX_SIZE_MASK;
nitup->t_info |= GinGetOrigSizePosting(itup);
}
else
{
nitup = (IndexTuple) palloc(MAXALIGN(IndexTupleSize(itup)));
memcpy(nitup, itup, IndexTupleSize(itup));
}
return nitup;
}
/* /*
* Place tuple and split page, original buffer(lbuf) leaves untouched, * Place tuple and split page, original buffer(lbuf) leaves untouched,
* returns shadow page of lbuf filled new data. * returns shadow page of lbuf filled new data.
@ -424,8 +449,6 @@ entrySplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogR
IndexTuple itup, IndexTuple itup,
leftrightmost = NULL; leftrightmost = NULL;
static ginxlogSplit data; static ginxlogSplit data;
Datum value;
bool isnull;
Page page; Page page;
Page lpage = GinPageGetCopyPage(BufferGetPage(lbuf)); Page lpage = GinPageGetCopyPage(BufferGetPage(lbuf));
Page rpage = BufferGetPage(rbuf); Page rpage = BufferGetPage(rbuf);
@ -494,9 +517,9 @@ entrySplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogR
ptr += MAXALIGN(IndexTupleSize(itup)); ptr += MAXALIGN(IndexTupleSize(itup));
} }
value = index_getattr(leftrightmost, FirstOffsetNumber, btree->ginstate->tupdesc, &isnull); btree->entry = copyIndexTuple(leftrightmost, lpage);
btree->entry = GinFormTuple(btree->ginstate, value, NULL, 0);
ItemPointerSet(&(btree->entry)->t_tid, BufferGetBlockNumber(lbuf), InvalidOffsetNumber); ItemPointerSet(&(btree->entry)->t_tid, BufferGetBlockNumber(lbuf), InvalidOffsetNumber);
btree->rightblkno = BufferGetBlockNumber(rbuf); btree->rightblkno = BufferGetBlockNumber(rbuf);
data.node = btree->index->rd_node; data.node = btree->index->rd_node;
@ -533,20 +556,9 @@ ginPageGetLinkItup(Buffer buf)
Page page = BufferGetPage(buf); Page page = BufferGetPage(buf);
itup = getRightMostTuple(page); itup = getRightMostTuple(page);
if (GinPageIsLeaf(page) && !GinIsPostingTree(itup)) nitup = copyIndexTuple(itup, page);
{
nitup = (IndexTuple) palloc(MAXALIGN(GinGetOrigSizePosting(itup)));
memcpy(nitup, itup, GinGetOrigSizePosting(itup));
nitup->t_info &= ~INDEX_SIZE_MASK;
nitup->t_info |= GinGetOrigSizePosting(itup);
}
else
{
nitup = (IndexTuple) palloc(MAXALIGN(IndexTupleSize(itup)));
memcpy(nitup, itup, IndexTupleSize(itup));
}
ItemPointerSet(&nitup->t_tid, BufferGetBlockNumber(buf), InvalidOffsetNumber); ItemPointerSet(&nitup->t_tid, BufferGetBlockNumber(buf), InvalidOffsetNumber);
return nitup; return nitup;
} }