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

Commite8d029a

Browse files
committed
Do unlocked prechecks in bufmgr.c loops that scan the whole buffer pool.
DropRelFileNodeBuffers, DropDatabaseBuffers, FlushRelationBuffers, andFlushDatabaseBuffers have to scan the whole shared_buffers pool becausewe have no index structure that would find the target buffers any moreefficiently than that. This gets expensive with large NBuffers. We canshave some cycles from these loops by prechecking to see if the currentbuffer is interesting before we acquire the buffer header lock.Ordinarily such a test would be unsafe, but in these cases it should besafe because we are already assuming that the caller holds a lock thatprevents any new target pages from being loaded into the buffer poolconcurrently. Therefore, no buffer tag should be changing to a value ofinterest, only away from a value of interest. So a false negative matchis impossible, while a false positive is safe because we'll recheck afteracquiring the buffer lock. Initial testing says that this speeds theseloops by a factor of 2X to 3X on common Intel hardware.Patch for DropRelFileNodeBuffers by Jeff Janes (based on an idea ofHeikki's); extended to the remaining sequential scans by Tom Lane
1 parent2c8a4e9 commite8d029a

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

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

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2048,6 +2048,7 @@ DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum,
20482048
{
20492049
inti;
20502050

2051+
/* If it's a local relation, it's localbuf.c's problem. */
20512052
if (rnode.backend!=InvalidBackendId)
20522053
{
20532054
if (rnode.backend==MyBackendId)
@@ -2059,6 +2060,25 @@ DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum,
20592060
{
20602061
volatileBufferDesc*bufHdr=&BufferDescriptors[i];
20612062

2063+
/*
2064+
* We can make this a tad faster by prechecking the buffer tag before
2065+
* we attempt to lock the buffer; this saves a lot of lock
2066+
* acquisitions in typical cases. It should be safe because the
2067+
* caller must have AccessExclusiveLock on the relation, or some other
2068+
* reason to be certain that no one is loading new pages of the rel
2069+
* into the buffer pool. (Otherwise we might well miss such pages
2070+
* entirely.) Therefore, while the tag might be changing while we
2071+
* look at it, it can't be changing *to* a value we care about, only
2072+
* *away* from such a value. So false negatives are impossible, and
2073+
* false positives are safe because we'll recheck after getting the
2074+
* buffer lock.
2075+
*
2076+
* We could check forkNum and blockNum as well as the rnode, but the
2077+
* incremental win from doing so seems small.
2078+
*/
2079+
if (!RelFileNodeEquals(bufHdr->tag.rnode,rnode.node))
2080+
continue;
2081+
20622082
LockBufHdr(bufHdr);
20632083
if (RelFileNodeEquals(bufHdr->tag.rnode,rnode.node)&&
20642084
bufHdr->tag.forkNum==forkNum&&
@@ -2084,7 +2104,6 @@ void
20842104
DropDatabaseBuffers(Oiddbid)
20852105
{
20862106
inti;
2087-
volatileBufferDesc*bufHdr;
20882107

20892108
/*
20902109
* We needn't consider local buffers, since by assumption the target
@@ -2093,7 +2112,15 @@ DropDatabaseBuffers(Oid dbid)
20932112

20942113
for (i=0;i<NBuffers;i++)
20952114
{
2096-
bufHdr=&BufferDescriptors[i];
2115+
volatileBufferDesc*bufHdr=&BufferDescriptors[i];
2116+
2117+
/*
2118+
* As in DropRelFileNodeBuffers, an unlocked precheck should be safe
2119+
* and saves some cycles.
2120+
*/
2121+
if (bufHdr->tag.rnode.dbNode!=dbid)
2122+
continue;
2123+
20972124
LockBufHdr(bufHdr);
20982125
if (bufHdr->tag.rnode.dbNode==dbid)
20992126
InvalidateBuffer(bufHdr);/* releases spinlock */
@@ -2220,6 +2247,14 @@ FlushRelationBuffers(Relation rel)
22202247
for (i=0;i<NBuffers;i++)
22212248
{
22222249
bufHdr=&BufferDescriptors[i];
2250+
2251+
/*
2252+
* As in DropRelFileNodeBuffers, an unlocked precheck should be safe
2253+
* and saves some cycles.
2254+
*/
2255+
if (!RelFileNodeEquals(bufHdr->tag.rnode,rel->rd_node))
2256+
continue;
2257+
22232258
LockBufHdr(bufHdr);
22242259
if (RelFileNodeEquals(bufHdr->tag.rnode,rel->rd_node)&&
22252260
(bufHdr->flags&BM_VALID)&& (bufHdr->flags&BM_DIRTY))
@@ -2262,6 +2297,14 @@ FlushDatabaseBuffers(Oid dbid)
22622297
for (i=0;i<NBuffers;i++)
22632298
{
22642299
bufHdr=&BufferDescriptors[i];
2300+
2301+
/*
2302+
* As in DropRelFileNodeBuffers, an unlocked precheck should be safe
2303+
* and saves some cycles.
2304+
*/
2305+
if (bufHdr->tag.rnode.dbNode!=dbid)
2306+
continue;
2307+
22652308
LockBufHdr(bufHdr);
22662309
if (bufHdr->tag.rnode.dbNode==dbid&&
22672310
(bufHdr->flags&BM_VALID)&& (bufHdr->flags&BM_DIRTY))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp