aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/buffer/bufmgr.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-06-07 17:42:27 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-06-07 17:43:11 -0400
commitece01aae479227d9836294b287d872c5a6146a11 (patch)
treec079ac4532474ccd3803f21a95ffb08fb8373dd9 /src/backend/storage/buffer/bufmgr.c
parent5baf6da71701abcb76487d9de68f7d7dc6c365e9 (diff)
downloadpostgresql-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.c42
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