diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 4060e600ff..69b6ef352b 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -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"); } diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index 96f0d3822e..cc4156826b 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -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; diff --git a/src/include/access/clog.h b/src/include/access/clog.h index 9cf54a4486..bed3b8cf26 100644 --- a/src/include/access/clog.h +++ b/src/include/access/clog.h @@ -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);