aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/buffer/buf_init.c
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2014-08-30 14:03:21 +0200
committerAndres Freund <andres@anarazel.de>2014-08-30 14:03:21 +0200
commit4b4b680c3d6d8485155d4d4bf0a92d3a874b7a65 (patch)
tree849c128b54c5d67089b309027d5e0f95aceb5bdc /src/backend/storage/buffer/buf_init.c
parentc6eaa880eea67a711b30903a9ee2e996bccb775e (diff)
downloadpostgresql-4b4b680c3d6d8485155d4d4bf0a92d3a874b7a65.tar.gz
postgresql-4b4b680c3d6d8485155d4d4bf0a92d3a874b7a65.zip
Make backend local tracking of buffer pins memory efficient.
Since the dawn of time (aka Postgres95) multiple pins of the same buffer by one backend have been optimized not to modify the shared refcount more than once. This optimization has always used a NBuffer sized array in each backend keeping track of a backend's pins. That array (PrivateRefCount) was one of the biggest per-backend memory allocations, depending on the shared_buffers setting. Besides the waste of memory it also has proven to be a performance bottleneck when assertions are enabled as we make sure that there's no remaining pins left at the end of transactions. Also, on servers with lots of memory and a correspondingly high shared_buffers setting the amount of random memory accesses can also lead to poor cpu cache efficiency. Because of these reasons a backend's buffers pins are now kept track of in a small statically sized array that overflows into a hash table when necessary. Benchmarks have shown neutral to positive performance results with considerably lower memory usage. Patch by me, review by Robert Haas. Discussion: 20140321182231.GA17111@alap3.anarazel.de
Diffstat (limited to 'src/backend/storage/buffer/buf_init.c')
-rw-r--r--src/backend/storage/buffer/buf_init.c39
1 files changed, 3 insertions, 36 deletions
diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c
index e03394c08bc..ff6c713b4f6 100644
--- a/src/backend/storage/buffer/buf_init.c
+++ b/src/backend/storage/buffer/buf_init.c
@@ -20,7 +20,6 @@
BufferDesc *BufferDescriptors;
char *BufferBlocks;
-int32 *PrivateRefCount;
/*
@@ -50,16 +49,9 @@ int32 *PrivateRefCount;
*
* refcount -- Counts the number of processes holding pins on a buffer.
* A buffer is pinned during IO and immediately after a BufferAlloc().
- * Pins must be released before end of transaction.
- *
- * PrivateRefCount -- Each buffer also has a private refcount that keeps
- * track of the number of times the buffer is pinned in the current
- * process. This is used for two purposes: first, if we pin a
- * a buffer more than once, we only need to change the shared refcount
- * once, thus only lock the shared state once; second, when a transaction
- * aborts, it should only unpin the buffers exactly the number of times it
- * has pinned them, so that it will not blow away buffers of another
- * backend.
+ * Pins must be released before end of transaction. For efficiency the
+ * shared refcount isn't increased if a individual backend pins a buffer
+ * multiple times. Check the PrivateRefCount infrastructure in bufmgr.c.
*/
@@ -130,31 +122,6 @@ InitBufferPool(void)
}
/*
- * Initialize access to shared buffer pool
- *
- * This is called during backend startup (whether standalone or under the
- * postmaster). It sets up for this backend's access to the already-existing
- * buffer pool.
- *
- * NB: this is called before InitProcess(), so we do not have a PGPROC and
- * cannot do LWLockAcquire; hence we can't actually access stuff in
- * shared memory yet. We are only initializing local data here.
- * (See also InitBufferPoolBackend, over in bufmgr.c.)
- */
-void
-InitBufferPoolAccess(void)
-{
- /*
- * Allocate and zero local arrays of per-buffer info.
- */
- PrivateRefCount = (int32 *) calloc(NBuffers, sizeof(int32));
- if (!PrivateRefCount)
- ereport(FATAL,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
-}
-
-/*
* BufferShmemSize
*
* compute the size of shared memory for the buffer pool including