From ece01aae479227d9836294b287d872c5a6146a11 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 7 Jun 2012 17:42:27 -0400 Subject: 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 --- src/backend/storage/buffer/bufmgr.c | 42 ++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'src/backend/storage/buffer/bufmgr.c') diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index b178eee2214..d46faaf958d 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -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 * -- cgit v1.2.3