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

Commitece01aa

Browse files
committed
Scan the buffer pool just once, not once per fork, during relation drop.
This provides a speedup of about 4X when NBuffers is large enough.There is also a useful reduction in sinval traffic, since weonly do CacheInvalidateSmgr() once not once per fork.Simon Riggs, reviewed and somewhat revised by Tom Lane
1 parent5baf6da commitece01aa

File tree

9 files changed

+150
-23
lines changed

9 files changed

+150
-23
lines changed

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,12 +1356,8 @@ FinishPreparedTransaction(const char *gid, bool isCommit)
13561356
for (i=0;i<ndelrels;i++)
13571357
{
13581358
SMgrRelationsrel=smgropen(delrels[i],InvalidBackendId);
1359-
ForkNumberfork;
13601359

1361-
for (fork=0;fork <=MAX_FORKNUM;fork++)
1362-
{
1363-
smgrdounlink(srel,fork, false);
1364-
}
1360+
smgrdounlink(srel, false);
13651361
smgrclose(srel);
13661362
}
13671363

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4638,10 +4638,8 @@ xact_redo_commit_internal(TransactionId xid, XLogRecPtr lsn,
46384638
ForkNumberfork;
46394639

46404640
for (fork=0;fork <=MAX_FORKNUM;fork++)
4641-
{
46424641
XLogDropRelation(xnodes[i],fork);
4643-
smgrdounlink(srel,fork, true);
4644-
}
4642+
smgrdounlink(srel, true);
46454643
smgrclose(srel);
46464644
}
46474645

@@ -4778,10 +4776,8 @@ xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
47784776
ForkNumberfork;
47794777

47804778
for (fork=0;fork <=MAX_FORKNUM;fork++)
4781-
{
47824779
XLogDropRelation(xlrec->xnodes[i],fork);
4783-
smgrdounlink(srel,fork, true);
4784-
}
4780+
smgrdounlink(srel, true);
47854781
smgrclose(srel);
47864782
}
47874783
}

‎src/backend/catalog/storage.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -356,13 +356,9 @@ smgrDoPendingDeletes(bool isCommit)
356356
if (pending->atCommit==isCommit)
357357
{
358358
SMgrRelationsrel;
359-
inti;
360359

361360
srel=smgropen(pending->relnode,pending->backend);
362-
for (i=0;i <=MAX_FORKNUM;i++)
363-
{
364-
smgrdounlink(srel,i, false);
365-
}
361+
smgrdounlink(srel, false);
366362
smgrclose(srel);
367363
}
368364
/* must explicitly free the list entry */

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

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2020,7 +2020,7 @@ BufferIsPermanent(Buffer buffer)
20202020
*DropRelFileNodeBuffers
20212021
*
20222022
*This function removes from the buffer pool all the pages of the
2023-
*specified relation that have block numbers >= firstDelBlock.
2023+
*specified relationforkthat have block numbers >= firstDelBlock.
20242024
*(In particular, with firstDelBlock = 0, all pages are removed.)
20252025
*Dirty pages are simply dropped, without bothering to write them
20262026
*out first.Therefore, this is NOT rollback-able, and so should be
@@ -2089,6 +2089,46 @@ DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum,
20892089
}
20902090
}
20912091

2092+
/* ---------------------------------------------------------------------
2093+
*DropRelFileNodeAllBuffers
2094+
*
2095+
*This function removes from the buffer pool all the pages of all
2096+
*forks of the specified relation. It's equivalent to calling
2097+
*DropRelFileNodeBuffers once per fork with firstDelBlock = 0.
2098+
* --------------------------------------------------------------------
2099+
*/
2100+
void
2101+
DropRelFileNodeAllBuffers(RelFileNodeBackendrnode)
2102+
{
2103+
inti;
2104+
2105+
/* If it's a local relation, it's localbuf.c's problem. */
2106+
if (rnode.backend!=InvalidBackendId)
2107+
{
2108+
if (rnode.backend==MyBackendId)
2109+
DropRelFileNodeAllLocalBuffers(rnode.node);
2110+
return;
2111+
}
2112+
2113+
for (i=0;i<NBuffers;i++)
2114+
{
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 (!RelFileNodeEquals(bufHdr->tag.rnode,rnode.node))
2122+
continue;
2123+
2124+
LockBufHdr(bufHdr);
2125+
if (RelFileNodeEquals(bufHdr->tag.rnode,rnode.node))
2126+
InvalidateBuffer(bufHdr);/* releases spinlock */
2127+
else
2128+
UnlockBufHdr(bufHdr);
2129+
}
2130+
}
2131+
20922132
/* ---------------------------------------------------------------------
20932133
*DropDatabaseBuffers
20942134
*

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,46 @@ DropRelFileNodeLocalBuffers(RelFileNode rnode, ForkNumber forkNum,
330330
}
331331
}
332332

333+
/*
334+
* DropRelFileNodeAllLocalBuffers
335+
*This function removes from the buffer pool all pages of all forks
336+
*of the specified relation.
337+
*
338+
*See DropRelFileNodeAllBuffers in bufmgr.c for more notes.
339+
*/
340+
void
341+
DropRelFileNodeAllLocalBuffers(RelFileNodernode)
342+
{
343+
inti;
344+
345+
for (i=0;i<NLocBuffer;i++)
346+
{
347+
BufferDesc*bufHdr=&LocalBufferDescriptors[i];
348+
LocalBufferLookupEnt*hresult;
349+
350+
if ((bufHdr->flags&BM_TAG_VALID)&&
351+
RelFileNodeEquals(bufHdr->tag.rnode,rnode))
352+
{
353+
if (LocalRefCount[i]!=0)
354+
elog(ERROR,"block %u of %s is still referenced (local %u)",
355+
bufHdr->tag.blockNum,
356+
relpathbackend(bufHdr->tag.rnode,MyBackendId,
357+
bufHdr->tag.forkNum),
358+
LocalRefCount[i]);
359+
/* Remove entry from hashtable */
360+
hresult= (LocalBufferLookupEnt*)
361+
hash_search(LocalBufHash, (void*)&bufHdr->tag,
362+
HASH_REMOVE,NULL);
363+
if (!hresult)/* shouldn't happen */
364+
elog(ERROR,"local buffer hash table corrupted");
365+
/* Mark buffer invalid */
366+
CLEAR_BUFFERTAG(bufHdr->tag);
367+
bufHdr->flags=0;
368+
bufHdr->usage_count=0;
369+
}
370+
}
371+
}
372+
333373
/*
334374
* InitLocalBuffers -
335375
* init the local buffer cache. Since most queries (esp. multi-user ones)

‎src/backend/storage/smgr/smgr.c

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,64 @@ smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
329329
}
330330

331331
/*
332-
*smgrdounlink() -- Immediately unlink a relation.
332+
*smgrdounlink() -- Immediately unlink all forks of a relation.
333+
*
334+
*All forks of the relation are removed from the store. This should
335+
*not be used during transactional operations, since it can't be undone.
336+
*
337+
*If isRedo is true, it is okay for the underlying file(s) to be gone
338+
*already.
339+
*
340+
*This is equivalent to calling smgrdounlinkfork for each fork, but
341+
*it's significantly quicker so should be preferred when possible.
342+
*/
343+
void
344+
smgrdounlink(SMgrRelationreln,boolisRedo)
345+
{
346+
RelFileNodeBackendrnode=reln->smgr_rnode;
347+
intwhich=reln->smgr_which;
348+
ForkNumberforknum;
349+
350+
/* Close the forks at smgr level */
351+
for (forknum=0;forknum <=MAX_FORKNUM;forknum++)
352+
(*(smgrsw[which].smgr_close)) (reln,forknum);
353+
354+
/*
355+
* Get rid of any remaining buffers for the relation. bufmgr will just
356+
* drop them without bothering to write the contents.
357+
*/
358+
DropRelFileNodeAllBuffers(rnode);
359+
360+
/*
361+
* It'd be nice to tell the stats collector to forget it immediately, too.
362+
* But we can't because we don't know the OID (and in cases involving
363+
* relfilenode swaps, it's not always clear which table OID to forget,
364+
* anyway).
365+
*/
366+
367+
/*
368+
* Send a shared-inval message to force other backends to close any
369+
* dangling smgr references they may have for this rel. We should do this
370+
* before starting the actual unlinking, in case we fail partway through
371+
* that step. Note that the sinval message will eventually come back to
372+
* this backend, too, and thereby provide a backstop that we closed our
373+
* own smgr rel.
374+
*/
375+
CacheInvalidateSmgr(rnode);
376+
377+
/*
378+
* Delete the physical file(s).
379+
*
380+
* Note: smgr_unlink must treat deletion failure as a WARNING, not an
381+
* ERROR, because we've already decided to commit or abort the current
382+
* xact.
383+
*/
384+
for (forknum=0;forknum <=MAX_FORKNUM;forknum++)
385+
(*(smgrsw[which].smgr_unlink)) (rnode,forknum,isRedo);
386+
}
387+
388+
/*
389+
*smgrdounlinkfork() -- Immediately unlink one fork of a relation.
333390
*
334391
*The specified fork of the relation is removed from the store. This
335392
*should not be used during transactional operations, since it can't be
@@ -339,16 +396,16 @@ smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
339396
*already.
340397
*/
341398
void
342-
smgrdounlink(SMgrRelationreln,ForkNumberforknum,boolisRedo)
399+
smgrdounlinkfork(SMgrRelationreln,ForkNumberforknum,boolisRedo)
343400
{
344401
RelFileNodeBackendrnode=reln->smgr_rnode;
345402
intwhich=reln->smgr_which;
346403

347-
/* Close the fork */
404+
/* Close the forkat smgr level*/
348405
(*(smgrsw[which].smgr_close)) (reln,forknum);
349406

350407
/*
351-
* Get rid of any remaining buffers for therelation. bufmgr will just
408+
* Get rid of any remaining buffers for thefork. bufmgr will just
352409
* drop them without bothering to write the contents.
353410
*/
354411
DropRelFileNodeBuffers(rnode,forknum,0);

‎src/include/storage/buf_internals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ extern BufferDesc *LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum,
210210
externvoidMarkLocalBufferDirty(Bufferbuffer);
211211
externvoidDropRelFileNodeLocalBuffers(RelFileNodernode,ForkNumberforkNum,
212212
BlockNumberfirstDelBlock);
213+
externvoidDropRelFileNodeAllLocalBuffers(RelFileNodernode);
213214
externvoidAtEOXact_LocalBuffers(boolisCommit);
214215

215216
#endif/* BUFMGR_INTERNALS_H */

‎src/include/storage/bufmgr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ extern void FlushRelationBuffers(Relation rel);
188188
externvoidFlushDatabaseBuffers(Oiddbid);
189189
externvoidDropRelFileNodeBuffers(RelFileNodeBackendrnode,
190190
ForkNumberforkNum,BlockNumberfirstDelBlock);
191+
externvoidDropRelFileNodeAllBuffers(RelFileNodeBackendrnode);
191192
externvoidDropDatabaseBuffers(Oiddbid);
192193

193194
#defineRelationGetNumberOfBlocks(reln) \

‎src/include/storage/smgr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ extern void smgrclose(SMgrRelation reln);
8080
externvoidsmgrcloseall(void);
8181
externvoidsmgrclosenode(RelFileNodeBackendrnode);
8282
externvoidsmgrcreate(SMgrRelationreln,ForkNumberforknum,boolisRedo);
83-
externvoidsmgrdounlink(SMgrRelationreln,ForkNumberforknum,
84-
boolisRedo);
83+
externvoidsmgrdounlink(SMgrRelationreln,boolisRedo);
84+
externvoidsmgrdounlinkfork(SMgrRelationreln,ForkNumberforknum,boolisRedo);
8585
externvoidsmgrextend(SMgrRelationreln,ForkNumberforknum,
8686
BlockNumberblocknum,char*buffer,boolskipFsync);
8787
externvoidsmgrprefetch(SMgrRelationreln,ForkNumberforknum,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp