1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-30 21:42:05 +03:00

Add simple sanity checks on newly-read pages to GiST, too.

This commit is contained in:
Tom Lane
2005-11-06 22:39:21 +00:00
parent 766dc45d9f
commit 6236991143
5 changed files with 119 additions and 46 deletions

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.127 2005/10/18 01:06:22 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.128 2005/11/06 22:39:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -529,12 +529,12 @@ gistfindleaf(GISTInsertState *state, GISTSTATE *giststate)
* ready to recheck path in a bad case... We remember, that page->lsn
* should never be invalid.
*/
while (true)
for (;;)
{
if (XLogRecPtrIsInvalid(state->stack->lsn))
state->stack->buffer = ReadBuffer(state->r, state->stack->blkno);
LockBuffer(state->stack->buffer, GIST_SHARE);
gistcheckpage(state->r, state->stack->buffer);
state->stack->page = (Page) BufferGetPage(state->stack->buffer);
opaque = GistPageGetOpaque(state->stack->page);
@ -555,7 +555,6 @@ gistfindleaf(GISTInsertState *state, GISTSTATE *giststate)
continue;
}
if (!GistPageIsLeaf(state->stack->page))
{
/*
@ -649,14 +648,18 @@ gistReadAndLockBuffer(Relation r, BlockNumber blkno)
}
/*
* Traverse the tree to find path from root page,
* to prevent deadlocks, it should lock only one page simultaneously.
* Function uses in recovery and usial mode, so should work with different
* read functions (gistReadAndLockBuffer and XLogReadBuffer)
* Traverse the tree to find path from root page.
*
* returns from the begining of closest parent;
*
* Function is used in both regular and recovery mode, so must work with
* different read functions (gistReadAndLockBuffer and XLogReadBuffer)
*
* To prevent deadlocks, this should lock only one page simultaneously.
*/
GISTInsertStack *
gistFindPath(Relation r, BlockNumber child, Buffer (*myReadBuffer) (Relation, BlockNumber))
gistFindPath(Relation r, BlockNumber child,
Buffer (*myReadBuffer) (Relation, BlockNumber))
{
Page page;
Buffer buffer;
@ -674,7 +677,8 @@ gistFindPath(Relation r, BlockNumber child, Buffer (*myReadBuffer) (Relation, Bl
while (top && top->blkno != child)
{
buffer = myReadBuffer(r, top->blkno); /* buffer locked */
buffer = myReadBuffer(r, top->blkno); /* locks buffer */
gistcheckpage(r, buffer);
page = (Page) BufferGetPage(buffer);
if (GistPageIsLeaf(page))
@ -771,9 +775,9 @@ gistFindCorrectParent(Relation r, GISTInsertStack *child)
GISTInsertStack *parent = child->parent;
LockBuffer(parent->buffer, GIST_EXCLUSIVE);
gistcheckpage(r, parent->buffer);
parent->page = (Page) BufferGetPage(parent->buffer);
/* here we don't need to distinguish between split and page update */
if (parent->childoffnum == InvalidOffsetNumber || !XLByteEQ(parent->lsn, PageGetLSN(parent->page)))
{
@ -811,6 +815,7 @@ gistFindCorrectParent(Relation r, GISTInsertStack *child)
break;
parent->buffer = ReadBuffer(r, parent->blkno);
LockBuffer(parent->buffer, GIST_EXCLUSIVE);
gistcheckpage(r, parent->buffer);
parent->page = (Page) BufferGetPage(parent->buffer);
}
@ -831,7 +836,8 @@ gistFindCorrectParent(Relation r, GISTInsertStack *child)
ptr = parent = gistFindPath(r, child->blkno, gistReadAndLockBuffer);
Assert(ptr != NULL);
/* read all buffers as supposed in caller */
/* read all buffers as expected by caller */
/* note we don't lock them or gistcheckpage them here! */
while (ptr)
{
ptr->buffer = ReadBuffer(r, ptr->blkno);