summaryrefslogtreecommitdiff
path: root/src/backend/access/gist/gistutil.c
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2005-06-27 12:45:23 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2005-06-27 12:45:23 +0000
commite8cab5fe49c45e9dc2990e36ecd6a42bf01dc4bc (patch)
treeb4950c8a1550ce26aa276a157b8680732ae3ac9b /src/backend/access/gist/gistutil.c
parentc3be085ab7a21e01f530357d962fa22f74a637ef (diff)
downloadpostgresql-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.c48
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;
}