diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-06-07 17:42:27 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-06-07 17:43:11 -0400 |
commit | ece01aae479227d9836294b287d872c5a6146a11 (patch) | |
tree | c079ac4532474ccd3803f21a95ffb08fb8373dd9 /src/backend/storage/buffer/bufmgr.c | |
parent | 5baf6da71701abcb76487d9de68f7d7dc6c365e9 (diff) | |
download | postgresql-ece01aae479227d9836294b287d872c5a6146a11.tar.gz postgresql-ece01aae479227d9836294b287d872c5a6146a11.zip |
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
Diffstat (limited to 'src/backend/storage/buffer/bufmgr.c')
-rw-r--r-- | src/backend/storage/buffer/bufmgr.c | 42 |
1 files changed, 41 insertions, 1 deletions
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 @@ -2090,6 +2090,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 * * This function removes all the buffers in the buffer cache for a |