diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2005-06-27 12:45:23 +0000 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2005-06-27 12:45:23 +0000 |
commit | e8cab5fe49c45e9dc2990e36ecd6a42bf01dc4bc (patch) | |
tree | b4950c8a1550ce26aa276a157b8680732ae3ac9b /src/backend/access/gist/gistutil.c | |
parent | c3be085ab7a21e01f530357d962fa22f74a637ef (diff) | |
download | postgresql-e8cab5fe49c45e9dc2990e36ecd6a42bf01dc4bc.tar.gz |
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
Diffstat (limited to 'src/backend/access/gist/gistutil.c')
-rw-r--r-- | src/backend/access/gist/gistutil.c | 48 |
1 files changed, 30 insertions, 18 deletions
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; } |