]> granicus.if.org Git - postgresql/commitdiff
Make the number of CLOG buffers adaptive, based on shared_buffers.
authorRobert Haas <rhaas@postgresql.org>
Fri, 6 Jan 2012 19:30:23 +0000 (14:30 -0500)
committerRobert Haas <rhaas@postgresql.org>
Fri, 6 Jan 2012 19:32:18 +0000 (14:32 -0500)
Previously, this was hardcoded: we always had 8.  Performance testing
shows that isn't enough, especially on big SMP systems, so we allow it
to scale up as high as 32 when there's adequate memory.  On the flip
side, when shared_buffers is very small, drop the number of CLOG buffers
down to as little as 4, so that we can start the postmaster even
when very little shared memory is available.

Per extensive discussion with Simon Riggs, Tom Lane, and others on
pgsql-hackers.

src/backend/access/transam/clog.c
src/backend/storage/lmgr/lwlock.c
src/include/access/clog.h

index 4060e600ff52a7868c884216ad763e4811876e24..69b6ef352b232600d69f04a1d0643b4ff88f04cd 100644 (file)
@@ -35,6 +35,7 @@
 #include "access/clog.h"
 #include "access/slru.h"
 #include "access/transam.h"
+#include "miscadmin.h"
 #include "pg_trace.h"
 
 /*
@@ -409,6 +410,34 @@ TransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn)
        return status;
 }
 
+/*
+ * Number of shared CLOG buffers.
+ *
+ * Testing during the PostgreSQL 9.2 development cycle revealed that on a
+ * large multi-processor system, it was possible to have more CLOG page
+ * requests in flight at one time than the numebr of CLOG buffers which existed
+ * at that time, which was hardcoded to 8.  Further testing revealed that
+ * performance dropped off with more than 32 CLOG buffers, possibly because
+ * the linear buffer search algorithm doesn't scale well.
+ *
+ * Unconditionally increasing the number of CLOG buffers to 32 did not seem
+ * like a good idea, because it would increase the minimum amount of shared
+ * memory required to start, which could be a problem for people running very
+ * small configurations.  The following formula seems to represent a reasonable
+ * compromise: people with very low values for shared_buffers will get fewer
+ * CLOG buffers as well, and everyone else will get 32.
+ *
+ * It is likely that some further work will be needed here in future releases;
+ * for example, on a 64-core server, the maximum number of CLOG requests that
+ * can be simultaneously in flight will be even larger.  But that will
+ * apparently require more than just changing the formula, so for now we take
+ * the easy way out.
+ */
+Size
+CLOGShmemBuffers(void)
+{
+       return Min(32, Max(4, NBuffers / 512));
+}
 
 /*
  * Initialization of shared memory for CLOG
@@ -416,14 +445,14 @@ TransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn)
 Size
 CLOGShmemSize(void)
 {
-       return SimpleLruShmemSize(NUM_CLOG_BUFFERS, CLOG_LSNS_PER_PAGE);
+       return SimpleLruShmemSize(CLOGShmemBuffers(), CLOG_LSNS_PER_PAGE);
 }
 
 void
 CLOGShmemInit(void)
 {
        ClogCtl->PagePrecedes = CLOGPagePrecedes;
-       SimpleLruInit(ClogCtl, "CLOG Ctl", NUM_CLOG_BUFFERS, CLOG_LSNS_PER_PAGE,
+       SimpleLruInit(ClogCtl, "CLOG Ctl", CLOGShmemBuffers(), CLOG_LSNS_PER_PAGE,
                                  CLogControlLock, "pg_clog");
 }
 
index 96f0d3822e41701690bd018697480c4e9e8b8fb4..cc4156826b59745545706dcaa660921486cbcdbc 100644 (file)
@@ -171,7 +171,7 @@ NumLWLocks(void)
        numLocks += MaxBackends + NUM_AUXILIARY_PROCS;
 
        /* clog.c needs one per CLOG buffer */
-       numLocks += NUM_CLOG_BUFFERS;
+       numLocks += CLOGShmemBuffers();
 
        /* subtrans.c needs one per SubTrans buffer */
        numLocks += NUM_SUBTRANS_BUFFERS;
index 9cf54a448696e451fce0ec09a9de69d687904dd7..bed3b8cf265212ba179be676183d18e268968de5 100644 (file)
@@ -28,14 +28,11 @@ typedef int XidStatus;
 #define TRANSACTION_STATUS_SUB_COMMITTED       0x03
 
 
-/* Number of SLRU buffers to use for clog */
-#define NUM_CLOG_BUFFERS       8
-
-
 extern void TransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
                                   TransactionId *subxids, XidStatus status, XLogRecPtr lsn);
 extern XidStatus TransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn);
 
+extern Size CLOGShmemBuffers(void);
 extern Size CLOGShmemSize(void);
 extern void CLOGShmemInit(void);
 extern void BootStrapCLOG(void);