mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
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 we only do CacheInvalidateSmgr() once not once per fork. Simon Riggs, reviewed and somewhat revised by Tom Lane
This commit is contained in:
@ -2020,7 +2020,7 @@ BufferIsPermanent(Buffer buffer)
|
||||
* DropRelFileNodeBuffers
|
||||
*
|
||||
* This function removes from the buffer pool all the pages of the
|
||||
* specified relation that have block numbers >= firstDelBlock.
|
||||
* specified relation fork that have block numbers >= firstDelBlock.
|
||||
* (In particular, with firstDelBlock = 0, all pages are removed.)
|
||||
* Dirty pages are simply dropped, without bothering to write them
|
||||
* out first. Therefore, this is NOT rollback-able, and so should be
|
||||
@ -2089,6 +2089,46 @@ DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum,
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* DropRelFileNodeAllBuffers
|
||||
*
|
||||
* This function removes from the buffer pool all the pages of all
|
||||
* forks of the specified relation. It's equivalent to calling
|
||||
* DropRelFileNodeBuffers once per fork with firstDelBlock = 0.
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
DropRelFileNodeAllBuffers(RelFileNodeBackend rnode)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* If it's a local relation, it's localbuf.c's problem. */
|
||||
if (rnode.backend != InvalidBackendId)
|
||||
{
|
||||
if (rnode.backend == MyBackendId)
|
||||
DropRelFileNodeAllLocalBuffers(rnode.node);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < NBuffers; i++)
|
||||
{
|
||||
volatile BufferDesc *bufHdr = &BufferDescriptors[i];
|
||||
|
||||
/*
|
||||
* As in DropRelFileNodeBuffers, an unlocked precheck should be safe
|
||||
* and saves some cycles.
|
||||
*/
|
||||
if (!RelFileNodeEquals(bufHdr->tag.rnode, rnode.node))
|
||||
continue;
|
||||
|
||||
LockBufHdr(bufHdr);
|
||||
if (RelFileNodeEquals(bufHdr->tag.rnode, rnode.node))
|
||||
InvalidateBuffer(bufHdr); /* releases spinlock */
|
||||
else
|
||||
UnlockBufHdr(bufHdr);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* DropDatabaseBuffers
|
||||
*
|
||||
|
Reference in New Issue
Block a user