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

Commitfdd13f1

Browse files
committed
Give the ResourceOwner mechanism full responsibility for releasing buffer
pins at end of transaction, and reduce AtEOXact_Buffers to an Assertcross-check that this was done correctly. When not USE_ASSERT_CHECKING,AtEOXact_Buffers is a complete no-op. This gets rid of an O(NBuffers)bottleneck during transaction commit/abort, which recent testing has shownbecomes significant above a few tens of thousands of shared buffers.
1 parent1c2de47 commitfdd13f1

File tree

6 files changed

+95
-72
lines changed

6 files changed

+95
-72
lines changed

‎src/backend/access/transam/xact.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.191 2004/10/04 21:52:14 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.192 2004/10/16 18:57:22 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -1528,6 +1528,9 @@ CommitTransaction(void)
15281528
RESOURCE_RELEASE_BEFORE_LOCKS,
15291529
true, true);
15301530

1531+
/* Check we've released all buffer pins */
1532+
AtEOXact_Buffers(true);
1533+
15311534
/*
15321535
* Make catalog changes visible to all backends. This has to happen
15331536
* after relcache references are dropped (see comments for
@@ -1684,6 +1687,7 @@ AbortTransaction(void)
16841687
ResourceOwnerRelease(TopTransactionResourceOwner,
16851688
RESOURCE_RELEASE_BEFORE_LOCKS,
16861689
false, true);
1690+
AtEOXact_Buffers(false);
16871691
AtEOXact_Inval(false);
16881692
smgrDoPendingDeletes(false);
16891693
ResourceOwnerRelease(TopTransactionResourceOwner,

‎src/backend/storage/buffer/bufmgr.c

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.179 2004/10/16 18:05:06 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.180 2004/10/16 18:57:23 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -851,35 +851,45 @@ ResetBufferUsage(void)
851851
/*
852852
*AtEOXact_Buffers - clean up at end of transaction.
853853
*
854-
*During abort, we need to release any buffer pins we're holding
855-
*(this cleans up in case ereport interrupted a routine that pins a
856-
*buffer). During commit, we shouldn't need to do that, but check
857-
*anyway to see if anyone leaked a buffer reference count.
854+
*As of PostgreSQL 8.0, buffer pins should get released by the
855+
*ResourceOwner mechanism. This routine is just a debugging
856+
*cross-check that no pins remain.
858857
*/
859858
void
860859
AtEOXact_Buffers(boolisCommit)
861860
{
861+
#ifdefUSE_ASSERT_CHECKING
862862
inti;
863863

864+
for (i=0;i<NBuffers;i++)
865+
{
866+
Assert(PrivateRefCount[i]==0);
867+
}
868+
869+
AtEOXact_LocalBuffers(isCommit);
870+
#endif
871+
}
872+
873+
/*
874+
* Ensure we have released all shared-buffer locks and pins during backend exit
875+
*/
876+
void
877+
AtProcExit_Buffers(void)
878+
{
879+
inti;
880+
881+
AbortBufferIO();
882+
UnlockBuffers();
883+
864884
for (i=0;i<NBuffers;i++)
865885
{
866886
if (PrivateRefCount[i]!=0)
867887
{
868888
BufferDesc*buf=&(BufferDescriptors[i]);
869889

870-
if (isCommit)
871-
elog(WARNING,
872-
"buffer refcount leak: [%03d] "
873-
"(rel=%u/%u/%u, blockNum=%u, flags=0x%x, refcount=%u %d)",
874-
i,
875-
buf->tag.rnode.spcNode,buf->tag.rnode.dbNode,
876-
buf->tag.rnode.relNode,
877-
buf->tag.blockNum,buf->flags,
878-
buf->refcount,PrivateRefCount[i]);
879-
880890
/*
881-
* We don't worry about updatingtheResourceOwner structures;
882-
*resowner.c will clear them for itself.
891+
* We don't worry about updating ResourceOwner; if we even got
892+
*here, it suggests that ResourceOwners are messed up.
883893
*/
884894
PrivateRefCount[i]=1;/* make sure we release shared pin */
885895
LWLockAcquire(BufMgrLock,LW_EXCLUSIVE);
@@ -888,8 +898,37 @@ AtEOXact_Buffers(bool isCommit)
888898
Assert(PrivateRefCount[i]==0);
889899
}
890900
}
901+
}
891902

892-
AtEOXact_LocalBuffers(isCommit);
903+
/*
904+
* Helper routine to issue warnings when a buffer is unexpectedly pinned
905+
*/
906+
void
907+
PrintBufferLeakWarning(Bufferbuffer)
908+
{
909+
BufferDesc*buf;
910+
int32loccount;
911+
912+
Assert(BufferIsValid(buffer));
913+
if (BufferIsLocal(buffer))
914+
{
915+
buf=&LocalBufferDescriptors[-buffer-1];
916+
loccount=LocalRefCount[-buffer-1];
917+
}
918+
else
919+
{
920+
buf=&BufferDescriptors[buffer-1];
921+
loccount=PrivateRefCount[buffer-1];
922+
}
923+
924+
elog(WARNING,
925+
"buffer refcount leak: [%03d] "
926+
"(rel=%u/%u/%u, blockNum=%u, flags=0x%x, refcount=%u %d)",
927+
buffer,
928+
buf->tag.rnode.spcNode,buf->tag.rnode.dbNode,
929+
buf->tag.rnode.relNode,
930+
buf->tag.blockNum,buf->flags,
931+
buf->refcount,loccount);
893932
}
894933

895934
/*

‎src/backend/storage/buffer/localbuf.c

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.59 2004/08/29 05:06:47 momjian Exp $
12+
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.60 2004/10/16 18:57:24 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -232,23 +232,12 @@ InitLocalBuffer(void)
232232
void
233233
AtEOXact_LocalBuffers(boolisCommit)
234234
{
235+
#ifdefUSE_ASSERT_CHECKING
235236
inti;
236237

237238
for (i=0;i<NLocBuffer;i++)
238239
{
239-
if (LocalRefCount[i]!=0)
240-
{
241-
BufferDesc*buf=&(LocalBufferDescriptors[i]);
242-
243-
if (isCommit)
244-
elog(WARNING,
245-
"local buffer leak: [%03d] (rel=%u/%u/%u, blockNum=%u, flags=0x%x, refcount=%u %d)",
246-
i,
247-
buf->tag.rnode.spcNode,buf->tag.rnode.dbNode,
248-
buf->tag.rnode.relNode,buf->tag.blockNum,buf->flags,
249-
buf->refcount,LocalRefCount[i]);
250-
251-
LocalRefCount[i]=0;
252-
}
240+
Assert(LocalRefCount[i]==0);
253241
}
242+
#endif
254243
}

‎src/backend/storage/lmgr/proc.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.154 2004/09/29 15:15:55 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.155 2004/10/16 18:57:24 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -461,9 +461,7 @@ ProcKill(int code, Datum arg)
461461
* shutdown callback registered by the bufmgr ... but we must do this
462462
* *after* LWLockReleaseAll and *before* zapping MyProc.
463463
*/
464-
AbortBufferIO();
465-
UnlockBuffers();
466-
AtEOXact_Buffers(false);
464+
AtProcExit_Buffers();
467465

468466
/* Get off any wait queue I might be on */
469467
LockWaitCancel();
@@ -509,9 +507,7 @@ DummyProcKill(int code, Datum arg)
509507
LWLockReleaseAll();
510508

511509
/* Release buffer locks and pins, too */
512-
AbortBufferIO();
513-
UnlockBuffers();
514-
AtEOXact_Buffers(false);
510+
AtProcExit_Buffers();
515511

516512
/* I can't be on regular lock queues, so needn't check */
517513

‎src/backend/utils/resowner/resowner.c

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.7 2004/08/30 02:54:40 momjian Exp $
17+
* $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.8 2004/10/16 18:57:25 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -191,37 +191,30 @@ ResourceOwnerReleaseInternal(ResourceOwner owner,
191191

192192
if (phase==RESOURCE_RELEASE_BEFORE_LOCKS)
193193
{
194-
/* Release buffer pins */
195-
if (isTopLevel)
196-
{
197-
/*
198-
* For a top-level xact we are going to release all buffers,
199-
* so just do a single bufmgr call at the top of the
200-
* recursion.
201-
*/
202-
if (owner==TopTransactionResourceOwner)
203-
AtEOXact_Buffers(isCommit);
204-
/* Mark object as owning no buffers, just for sanity */
205-
owner->nbuffers=0;
206-
}
207-
else
194+
/*
195+
* Release buffer pins. Note that ReleaseBuffer will
196+
* remove the buffer entry from my list, so I just have to
197+
* iterate till there are none.
198+
*
199+
* During a commit, there shouldn't be any remaining pins ---
200+
* that would indicate failure to clean up the executor correctly ---
201+
* so issue warnings. In the abort case, just clean up quietly.
202+
*
203+
* XXX this is fairly inefficient due to multiple BufMgrLock
204+
* grabs if there are lots of buffers to be released, but we
205+
* don't expect many (indeed none in the success case) so it's
206+
* probably not worth optimizing.
207+
*
208+
* We are however careful to release back-to-front, so as to
209+
* avoid O(N^2) behavior in ResourceOwnerForgetBuffer().
210+
*/
211+
while (owner->nbuffers>0)
208212
{
209-
/*
210-
* Release buffers retail.Note that ReleaseBuffer will
211-
* remove the buffer entry from my list, so I just have to
212-
* iterate till there are none.
213-
*
214-
* XXX this is fairly inefficient due to multiple BufMgrLock
215-
* grabs if there are lots of buffers to be released, but we
216-
* don't expect many (indeed none in the success case) so it's
217-
* probably not worth optimizing.
218-
*
219-
* We are however careful to release back-to-front, so as to
220-
* avoid O(N^2) behavior in ResourceOwnerForgetBuffer().
221-
*/
222-
while (owner->nbuffers>0)
223-
ReleaseBuffer(owner->buffers[owner->nbuffers-1]);
213+
if (isCommit)
214+
PrintBufferLeakWarning(owner->buffers[owner->nbuffers-1]);
215+
ReleaseBuffer(owner->buffers[owner->nbuffers-1]);
224216
}
217+
225218
/* Release relcache references */
226219
if (isTopLevel)
227220
{

‎src/include/storage/bufmgr.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.87 2004/10/15 22:40:25 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.88 2004/10/16 18:57:26 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -122,6 +122,8 @@ extern void InitBufferPoolAccess(void);
122122
externchar*ShowBufferUsage(void);
123123
externvoidResetBufferUsage(void);
124124
externvoidAtEOXact_Buffers(boolisCommit);
125+
externvoidAtProcExit_Buffers(void);
126+
externvoidPrintBufferLeakWarning(Bufferbuffer);
125127
externvoidFlushBufferPool(void);
126128
externBlockNumberBufferGetBlockNumber(Bufferbuffer);
127129
externBlockNumberRelationGetNumberOfBlocks(Relationrelation);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp