Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite8cab5f

Browse files
committed
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 recordsFix bug in index_beginscan_internal: LockRelation may clean rd_aminfo structure, so move GET_REL_PROCEDURE after LockRelation
1 parentc3be085 commite8cab5f

File tree

12 files changed

+987
-591
lines changed

12 files changed

+987
-591
lines changed

‎src/backend/access/gist/gist.c

Lines changed: 384 additions & 99 deletions
Large diffs are not rendered by default.

‎src/backend/access/gist/gistget.c

Lines changed: 204 additions & 122 deletions
Large diffs are not rendered by default.

‎src/backend/access/gist/gistscan.c

Lines changed: 33 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.58 2005/05/17 03:34:18 neilc Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.59 2005/06/27 12:45:22 teodor Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -24,11 +24,10 @@
2424
staticvoidgistregscan(IndexScanDescscan);
2525
staticvoidgistdropscan(IndexScanDescscan);
2626
staticvoidgistadjone(IndexScanDescscan,intop,BlockNumberblkno,
27-
OffsetNumberoffnum);
28-
staticvoidadjuststack(GISTSTACK*stk,BlockNumberblkno);
29-
staticvoidadjustiptr(IndexScanDescscan,ItemPointeriptr,
30-
intop,BlockNumberblkno,OffsetNumberoffnum);
31-
staticvoidgistfreestack(GISTSTACK*s);
27+
OffsetNumberoffnum,XLogRecPtrnewlsn,XLogRecPtroldlsn);
28+
staticvoidadjustiptr(IndexScanDescscan,ItemPointeriptr,GISTSearchStack*stk,
29+
intop,BlockNumberblkno,OffsetNumberoffnum,XLogRecPtrnewlsn,XLogRecPtroldlsn);
30+
staticvoidgistfreestack(GISTSearchStack*s);
3231

3332
/*
3433
* Whenever we start a GiST scan in a backend, we register it in
@@ -139,7 +138,7 @@ gistmarkpos(PG_FUNCTION_ARGS)
139138
{
140139
IndexScanDescscan= (IndexScanDesc)PG_GETARG_POINTER(0);
141140
GISTScanOpaqueso;
142-
GISTSTACK*o,
141+
GISTSearchStack*o,
143142
*n,
144143
*tmp;
145144

@@ -156,12 +155,13 @@ gistmarkpos(PG_FUNCTION_ARGS)
156155
/* copy the parent stack from the current item data */
157156
while (n!=NULL)
158157
{
159-
tmp= (GISTSTACK*)palloc(sizeof(GISTSTACK));
160-
tmp->offset=n->offset;
158+
tmp= (GISTSearchStack*)palloc(sizeof(GISTSearchStack));
159+
tmp->lsn=n->lsn;
160+
tmp->parentlsn=n->parentlsn;
161161
tmp->block=n->block;
162-
tmp->parent=o;
162+
tmp->next=o;
163163
o=tmp;
164-
n=n->parent;
164+
n=n->next;
165165
}
166166

167167
gistfreestack(so->markstk);
@@ -187,7 +187,7 @@ gistrestrpos(PG_FUNCTION_ARGS)
187187
{
188188
IndexScanDescscan= (IndexScanDesc)PG_GETARG_POINTER(0);
189189
GISTScanOpaqueso;
190-
GISTSTACK*o,
190+
GISTSearchStack*o,
191191
*n,
192192
*tmp;
193193

@@ -204,12 +204,13 @@ gistrestrpos(PG_FUNCTION_ARGS)
204204
/* copy the parent stack from the current item data */
205205
while (n!=NULL)
206206
{
207-
tmp= (GISTSTACK*)palloc(sizeof(GISTSTACK));
208-
tmp->offset=n->offset;
207+
tmp= (GISTSearchStack*)palloc(sizeof(GISTSearchStack));
208+
tmp->lsn=n->lsn;
209+
tmp->parentlsn=n->parentlsn;
209210
tmp->block=n->block;
210-
tmp->parent=o;
211+
tmp->next=o;
211212
o=tmp;
212-
n=n->parent;
213+
n=n->next;
213214
}
214215

215216
gistfreestack(so->stack);
@@ -253,6 +254,7 @@ gistendscan(PG_FUNCTION_ARGS)
253254
pfree(scan->opaque);
254255
}
255256

257+
256258
gistdropscan(scan);
257259

258260
PG_RETURN_VOID();
@@ -331,16 +333,19 @@ ReleaseResources_gist(void)
331333
}
332334

333335
void
334-
gistadjscans(Relationrel,intop,BlockNumberblkno,OffsetNumberoffnum)
336+
gistadjscans(Relationrel,intop,BlockNumberblkno,OffsetNumberoffnum,XLogRecPtrnewlsn,XLogRecPtroldlsn)
335337
{
336338
GISTScanListl;
337339
Oidrelid;
338340

341+
if (XLogRecPtrIsInvalid(newlsn)||XLogRecPtrIsInvalid(oldlsn) )
342+
return;
343+
339344
relid=RelationGetRelid(rel);
340345
for (l=GISTScans;l!=NULL;l=l->gsl_next)
341346
{
342347
if (l->gsl_scan->indexRelation->rd_id==relid)
343-
gistadjone(l->gsl_scan,op,blkno,offnum);
348+
gistadjone(l->gsl_scan,op,blkno,offnum,newlsn,oldlsn);
344349
}
345350
}
346351

@@ -358,20 +363,12 @@ static void
358363
gistadjone(IndexScanDescscan,
359364
intop,
360365
BlockNumberblkno,
361-
OffsetNumberoffnum)
366+
OffsetNumberoffnum,XLogRecPtrnewlsn,XLogRecPtroldlsn)
362367
{
363-
GISTScanOpaqueso;
364-
365-
adjustiptr(scan,&(scan->currentItemData),op,blkno,offnum);
366-
adjustiptr(scan,&(scan->currentMarkData),op,blkno,offnum);
367-
368-
so= (GISTScanOpaque)scan->opaque;
368+
GISTScanOpaqueso= (GISTScanOpaque)scan->opaque ;
369369

370-
if (op==GISTOP_SPLIT)
371-
{
372-
adjuststack(so->stack,blkno);
373-
adjuststack(so->markstk,blkno);
374-
}
370+
adjustiptr(scan,&(scan->currentItemData),so->stack,op,blkno,offnum,newlsn,oldlsn);
371+
adjustiptr(scan,&(scan->currentMarkData),so->markstk,op,blkno,offnum,newlsn,oldlsn);
375372
}
376373

377374
/*
@@ -383,10 +380,10 @@ gistadjone(IndexScanDesc scan,
383380
*/
384381
staticvoid
385382
adjustiptr(IndexScanDescscan,
386-
ItemPointeriptr,
383+
ItemPointeriptr,GISTSearchStack*stk,
387384
intop,
388385
BlockNumberblkno,
389-
OffsetNumberoffnum)
386+
OffsetNumberoffnum,XLogRecPtrnewlsn,XLogRecPtroldlsn)
390387
{
391388
OffsetNumbercuroff;
392389
GISTScanOpaqueso;
@@ -402,7 +399,7 @@ adjustiptr(IndexScanDesc scan,
402399
{
403400
caseGISTOP_DEL:
404401
/* back up one if we need to */
405-
if (curoff >=offnum)
402+
if (curoff >=offnum&&XLByteEQ(stk->lsn,oldlsn) )/* the same vesrion of page */
406403
{
407404
if (curoff>FirstOffsetNumber)
408405
{
@@ -421,56 +418,22 @@ adjustiptr(IndexScanDesc scan,
421418
else
422419
so->flags |=GS_MRKBEFORE;
423420
}
421+
stk->lsn=newlsn;
424422
}
425423
break;
426-
427-
caseGISTOP_SPLIT:
428-
/* back to start of page on split */
429-
ItemPointerSet(iptr,blkno,FirstOffsetNumber);
430-
if (iptr==&(scan->currentItemData))
431-
so->flags &= ~GS_CURBEFORE;
432-
else
433-
so->flags &= ~GS_MRKBEFORE;
434-
break;
435-
436424
default:
437425
elog(ERROR,"Bad operation in GiST scan adjust: %d",op);
438426
}
439427
}
440428
}
441429
}
442430

443-
/*
444-
*adjuststack() -- adjust the supplied stack for a split on a page in
445-
* the index we're scanning.
446-
*
447-
*If a page on our parent stack has split, we need to back up to the
448-
*beginning of the page and rescan it. The reason for this is that
449-
*the split algorithm for GiSTs doesn't order tuples in any useful
450-
*way on a single page. This means on that a split, we may wind up
451-
*looking at some heap tuples more than once. This is handled in the
452-
*access method update code for heaps; if we've modified the tuple we
453-
*are looking at already in this transaction, we ignore the update
454-
*request.
455-
*/
456-
staticvoid
457-
adjuststack(GISTSTACK*stk,BlockNumberblkno)
458-
{
459-
while (stk!=NULL)
460-
{
461-
if (stk->block==blkno)
462-
stk->offset=FirstOffsetNumber;
463-
464-
stk=stk->parent;
465-
}
466-
}
467-
468431
staticvoid
469-
gistfreestack(GISTSTACK*s)
432+
gistfreestack(GISTSearchStack*s)
470433
{
471434
while (s!=NULL)
472435
{
473-
GISTSTACK*p=s->parent;
436+
GISTSearchStack*p=s->next;
474437
pfree(s);
475438
s=p;
476439
}

‎src/backend/access/gist/gistutil.c

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.2 2005/06/20 10:29:36 teodor Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.3 2005/06/27 12:45:22 teodor Exp $
1212
*-------------------------------------------------------------------------
1313
*/
1414
#include"postgres.h"
@@ -803,8 +803,12 @@ GISTInitBuffer(Buffer b, uint32 f)
803803
page=BufferGetPage(b);
804804
PageInit(page,pageSize,sizeof(GISTPageOpaqueData));
805805

806-
opaque=(GISTPageOpaque)PageGetSpecialPointer(page);
806+
opaque=GistPageGetOpaque(page);
807807
opaque->flags=f;
808+
opaque->nsplited=0;
809+
opaque->level=0;
810+
opaque->rightlink=InvalidBlockNumber;
811+
memset(&(opaque->nsn),0,sizeof(GistNSN) );
808812
}
809813

810814
void
@@ -856,30 +860,38 @@ gistUserPicksplit(Relation r, GistEntryVector *entryvec, GIST_SPLITVEC *v,
856860
}
857861

858862
Buffer
859-
gistReadBuffer(Relationr,BlockNumberblkno) {
863+
gistNewBuffer(Relationr) {
860864
Bufferbuffer=InvalidBuffer;
865+
boolneedLock;
861866

862-
if (blkno!=P_NEW ) {
863-
buffer=ReadBuffer(r,blkno);
864-
}else {
865-
Pagepage;
866-
867-
while(true) {
868-
blkno=GetFreeIndexPage(&r->rd_node);
869-
if (blkno==InvalidBlockNumber)
870-
break;
867+
while(true) {
868+
BlockNumberblkno=GetFreeIndexPage(&r->rd_node);
869+
if (blkno==InvalidBlockNumber)
870+
break;
871871

872-
buffer=ReadBuffer(r,blkno);
873-
page=BufferGetPage(buffer);
872+
buffer=ReadBuffer(r,blkno);
873+
if (ConditionalLockBuffer(buffer) ) {
874+
Pagepage=BufferGetPage(buffer);
874875
if (GistPageIsDeleted(page ) ) {
875876
GistPageSetNonDeleted(page );
876877
returnbuffer;
877-
}
878-
ReleaseBuffer(buffer);
878+
}else
879+
LockBuffer(buffer,GIST_UNLOCK);
879880
}
880881

881-
buffer=ReadBuffer(r,P_NEW);
882+
ReleaseBuffer(buffer );
882883
}
883-
884+
885+
needLock= !RELATION_IS_LOCAL(r);
886+
887+
if (needLock)
888+
LockRelationForExtension(r,ExclusiveLock);
889+
890+
buffer=ReadBuffer(r,P_NEW);
891+
LockBuffer(buffer,GIST_EXCLUSIVE);
892+
893+
if (needLock)
894+
UnlockRelationForExtension(r,ExclusiveLock);
895+
884896
returnbuffer;
885897
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp