From e8cab5fe49c45e9dc2990e36ecd6a42bf01dc4bc Mon Sep 17 00:00:00 2001 From: Teodor Sigaev Date: Mon, 27 Jun 2005 12:45:23 +0000 Subject: Concurrency for GiST - full concurrency for insert/update/select/vacuum: - select and vacuum never locks more than one page simultaneously - select (gettuple) hasn't any lock across it's calls - insert never locks more than two page simultaneously: - during search of leaf to insert it locks only one page simultaneously - while walk upward to the root it locked only parent (may be non-direct parent) and child. One of them X-lock, another may be S- or X-lock - 'vacuum full' locks index - improve gistgetmulti - simplify XLOG records Fix bug in index_beginscan_internal: LockRelation may clean rd_aminfo structure, so move GET_REL_PROCEDURE after LockRelation --- src/backend/access/gist/gistutil.c | 48 ++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 18 deletions(-) (limited to 'src/backend/access/gist/gistutil.c') diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index 735be85f25..e7c985b459 100644 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.2 2005/06/20 10:29:36 teodor Exp $ + * $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.3 2005/06/27 12:45:22 teodor Exp $ *------------------------------------------------------------------------- */ #include "postgres.h" @@ -803,8 +803,12 @@ GISTInitBuffer(Buffer b, uint32 f) page = BufferGetPage(b); PageInit(page, pageSize, sizeof(GISTPageOpaqueData)); - opaque = (GISTPageOpaque) PageGetSpecialPointer(page); + opaque = GistPageGetOpaque(page); opaque->flags = f; + opaque->nsplited = 0; + opaque->level = 0; + opaque->rightlink = InvalidBlockNumber; + memset( &(opaque->nsn), 0, sizeof(GistNSN) ); } void @@ -856,30 +860,38 @@ gistUserPicksplit(Relation r, GistEntryVector *entryvec, GIST_SPLITVEC *v, } Buffer -gistReadBuffer(Relation r, BlockNumber blkno) { +gistNewBuffer(Relation r) { Buffer buffer = InvalidBuffer; + bool needLock; - if ( blkno != P_NEW ) { - buffer = ReadBuffer(r, blkno); - } else { - Page page; - - while(true) { - blkno = GetFreeIndexPage(&r->rd_node); - if (blkno == InvalidBlockNumber) - break; + while(true) { + BlockNumber blkno = GetFreeIndexPage(&r->rd_node); + if (blkno == InvalidBlockNumber) + break; - buffer = ReadBuffer(r, blkno); - page = BufferGetPage(buffer); + buffer = ReadBuffer(r, blkno); + if ( ConditionalLockBuffer(buffer) ) { + Page page = BufferGetPage(buffer); if ( GistPageIsDeleted( page ) ) { GistPageSetNonDeleted( page ); return buffer; - } - ReleaseBuffer( buffer ); + } else + LockBuffer(buffer, GIST_UNLOCK); } - buffer = ReadBuffer(r, P_NEW); + ReleaseBuffer( buffer ); } - + + needLock = !RELATION_IS_LOCAL(r); + + if (needLock) + LockRelationForExtension(r, ExclusiveLock); + + buffer = ReadBuffer(r, P_NEW); + LockBuffer(buffer, GIST_EXCLUSIVE); + + if (needLock) + UnlockRelationForExtension(r, ExclusiveLock); + return buffer; } -- cgit v1.2.1