From 9d197856dd5eda5cf85b15e564ae09ef8fef0e9e Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 21 Feb 1999 01:41:55 +0000 Subject: [PATCH] Rearrange handling of MAXBACKENDS a little bit. The default setting of MAXBACKENDS is now 1024, since all it's costing is about 32 bytes of memory per array slot. configure's --with-maxbackends switch now controls DEF_MAXBACKENDS which is simply the default value of the postmaster's -N switch. Thus, the out-of-the-box configuration will still limit you to 64 backends, but you can go up to 1024 backends simply by restarting the postmaster with a different -N switch --- no rebuild required. --- src/backend/postmaster/postmaster.c | 19 +++++++++-------- src/backend/storage/ipc/ipc.c | 11 +++++----- src/backend/storage/ipc/ipci.c | 11 ++++------ src/backend/storage/lmgr/lock.c | 21 ++++++++++--------- src/backend/storage/lmgr/proc.c | 41 +++++++++++++++++++++---------------- src/configure | 10 ++++----- src/configure.in | 10 ++++----- src/include/config.h.in | 11 ++++++++-- src/include/storage/ipc.h | 3 +-- src/include/storage/lock.h | 10 ++++----- 10 files changed, 79 insertions(+), 68 deletions(-) diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 41099d9c05..281b95fe90 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.102 1999/02/19 06:06:00 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.103 1999/02/21 01:41:43 tgl Exp $ * * NOTES * @@ -162,14 +162,15 @@ static IpcMemoryKey ipc_key; * adding to this. */ -static int MaxBackends = MAXBACKENDS; +static int MaxBackends = DEF_MAXBACKENDS; /* - * MaxBackends is the actual soft limit on the number of backends - * we will start. It defaults to the hard limit established at compilation - * time, but can be readjusted with postmaster's xxx switch. - * One reason to reduce MaxBackends is to allow startup under a kernel - * that won't let us get MAXBACKENDS semaphores! + * MaxBackends is the actual limit on the number of backends we will start. + * The default is established by configure, but it can be readjusted + * from 1..MAXBACKENDS with the postmaster -N switch. + * Note that a larger MaxBackends value will increase the size of the + * shared memory area as well as cause the postmaster to grab more + * kernel semaphores, even if you never actually use that many backends. */ static int NextBackendTag = MAXINT; /* XXX why count down not up? */ @@ -641,8 +642,8 @@ usage(const char *progname) fprintf(stderr, "\t-b backend\tuse a specific backend server executable\n"); fprintf(stderr, "\t-d [1|2|3]\tset debugging level\n"); fprintf(stderr, "\t-i \t\tlisten on TCP/IP sockets as well as Unix domain socket\n"); - fprintf(stderr, "\t-N nprocs\tset max number of backend servers (1..%d)\n", - MAXBACKENDS); + fprintf(stderr, "\t-N nprocs\tset max number of backends (1..%d, default %d)\n", + MAXBACKENDS, DEF_MAXBACKENDS); fprintf(stderr, "\t-n \t\tdon't reinitialize shared memory after abnormal exit\n"); fprintf(stderr, "\t-o option\tpass 'option' to each backend servers\n"); fprintf(stderr, "\t-p port\tspecify port for postmaster to listen on\n"); diff --git a/src/backend/storage/ipc/ipc.c b/src/backend/storage/ipc/ipc.c index 511893657f..62a38e14aa 100644 --- a/src/backend/storage/ipc/ipc.c +++ b/src/backend/storage/ipc/ipc.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.35 1999/02/13 23:18:09 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.36 1999/02/21 01:41:44 tgl Exp $ * * NOTES * @@ -677,9 +677,10 @@ struct ipcdummy SLock *free; int unused; slock_t memlock; - SLock slocks[NSLOCKS]; + SLock slocks[MAX_SPINS + 1]; }; -static int SLockMemorySize = sizeof(struct ipcdummy); + +#define SLOCKMEMORYSIZE sizeof(struct ipcdummy) void CreateAndInitSLockMemory(IPCKey key) @@ -688,7 +689,7 @@ CreateAndInitSLockMemory(IPCKey key) SLock *slckP; SLockMemoryId = IpcMemoryCreate(key, - SLockMemorySize, + SLOCKMEMORYSIZE, 0700); AttachSLockMemory(key); *FreeSLockPP = NULL; @@ -713,7 +714,7 @@ AttachSLockMemory(IPCKey key) struct ipcdummy *slockM; if (SLockMemoryId == -1) - SLockMemoryId = IpcMemoryIdGet(key, SLockMemorySize); + SLockMemoryId = IpcMemoryIdGet(key, SLOCKMEMORYSIZE); if (SLockMemoryId == -1) elog(FATAL, "SLockMemory not in shared memory"); slockM = (struct ipcdummy *) IpcMemoryAttach(SLockMemoryId); diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 460f0ee10b..49259807b4 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.20 1999/02/19 07:10:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.21 1999/02/21 01:41:44 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -72,7 +72,7 @@ CreateSharedMemoryAndSemaphores(IPCKey key, int maxBackends) * ---------------- */ CreateSpinlocks(IPCKeyGetSpinLockSemaphoreKey(key)); - size = BufferShmemSize() + LockShmemSize(); + size = BufferShmemSize() + LockShmemSize(maxBackends); #ifdef STABLE_MEMORY_STORAGE size += MMShmemSize(); @@ -113,15 +113,13 @@ CreateSharedMemoryAndSemaphores(IPCKey key, int maxBackends) void AttachSharedMemoryAndSemaphores(IPCKey key) { - int size; - /* ---------------- * create rather than attach if using private key * ---------------- */ if (key == PrivateIPCKey) { - CreateSharedMemoryAndSemaphores(key, 1); + CreateSharedMemoryAndSemaphores(key, 16); return; } @@ -136,8 +134,7 @@ AttachSharedMemoryAndSemaphores(IPCKey key) * attach the buffer manager buffer pool (and semaphore) * ---------------- */ - size = BufferShmemSize() + LockShmemSize(); - InitShmem(key, size); + InitShmem(key, 0); InitBufferPool(key); /* ---------------- diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 06f6fe7b4d..29424e060f 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.42 1999/02/19 06:06:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.43 1999/02/21 01:41:46 tgl Exp $ * * NOTES * Outside modules can create a lock table and acquire/release @@ -1478,36 +1478,37 @@ next_item: } int -LockShmemSize() +LockShmemSize(int maxBackends) { int size = 0; + int nLockEnts = NLOCKENTS(maxBackends); int nLockBuckets, nLockSegs; int nXidBuckets, nXidSegs; - nLockBuckets = 1 << (int) my_log2((NLOCKENTS - 1) / DEF_FFACTOR + 1); + nLockBuckets = 1 << (int) my_log2((nLockEnts - 1) / DEF_FFACTOR + 1); nLockSegs = 1 << (int) my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1); nXidBuckets = 1 << (int) my_log2((NLOCKS_PER_XACT - 1) / DEF_FFACTOR + 1); nXidSegs = 1 << (int) my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1); - size += MAXALIGN(MAXBACKENDS * sizeof(PROC)); /* each MyProc */ - size += MAXALIGN(MAXBACKENDS * sizeof(LOCKMETHODCTL)); /* each + size += MAXALIGN(maxBackends * sizeof(PROC)); /* each MyProc */ + size += MAXALIGN(maxBackends * sizeof(LOCKMETHODCTL)); /* each * lockMethodTable->ctl */ size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */ - size += MAXALIGN(my_log2(NLOCKENTS) * sizeof(void *)); + size += MAXALIGN(my_log2(nLockEnts) * sizeof(void *)); size += MAXALIGN(sizeof(HHDR)); size += nLockSegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT)); - size += NLOCKENTS * /* XXX not multiple of BUCKET_ALLOC_INCR? */ + size += nLockEnts * /* XXX not multiple of BUCKET_ALLOC_INCR? */ (MAXALIGN(sizeof(BUCKET_INDEX)) + MAXALIGN(sizeof(LOCK))); /* contains hash key */ - size += MAXALIGN(my_log2(MAXBACKENDS) * sizeof(void *)); + size += MAXALIGN(my_log2(maxBackends) * sizeof(void *)); size += MAXALIGN(sizeof(HHDR)); size += nXidSegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT)); - size += MAXBACKENDS * /* XXX not multiple of BUCKET_ALLOC_INCR? */ + size += maxBackends * /* XXX not multiple of BUCKET_ALLOC_INCR? */ (MAXALIGN(sizeof(BUCKET_INDEX)) + MAXALIGN(sizeof(XIDLookupEnt))); /* contains hash key */ @@ -1673,8 +1674,8 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check) break; if (j >= nprocs && lock != findlock) { + Assert(nprocs < MAXBACKENDS); checked_procs[nprocs++] = proc; - Assert(nprocs <= MAXBACKENDS); /* * For non-MyProc entries, we are looking only diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 7452270fdf..2bb66c09d6 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.50 1999/02/19 07:10:48 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.51 1999/02/21 01:41:45 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -46,7 +46,7 @@ * This is so that we can support more backends. (system-wide semaphore * sets run out pretty fast.) -ay 4/95 * - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.50 1999/02/19 07:10:48 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.51 1999/02/21 01:41:45 tgl Exp $ */ #include #include @@ -154,23 +154,28 @@ InitProcGlobal(IPCKey key, int maxBackends) */ on_shmem_exit(ProcFreeAllSemaphores, NULL); - /* Pre-create the semaphores for the first maxBackends processes */ - for (i = 0; - i < (maxBackends+PROC_NSEMS_PER_SET-1) / PROC_NSEMS_PER_SET; - i++) + /* Pre-create the semaphores for the first maxBackends processes, + * unless we are running as a standalone backend. + */ + if (key != PrivateIPCKey) { - IPCKey semKey = ProcGlobal->currKey + i; - int semId; - int semstat; - - semId = IpcSemaphoreCreate(semKey, - PROC_NSEMS_PER_SET, - IPCProtection, - IpcSemaphoreDefaultStartValue, - 0, - &semstat); - /* mark this sema set allocated */ - ProcGlobal->freeSemMap[i] = (1 << PROC_NSEMS_PER_SET); + for (i = 0; + i < (maxBackends+PROC_NSEMS_PER_SET-1) / PROC_NSEMS_PER_SET; + i++) + { + IPCKey semKey = ProcGlobal->currKey + i; + int semId; + int semstat; + + semId = IpcSemaphoreCreate(semKey, + PROC_NSEMS_PER_SET, + IPCProtection, + IpcSemaphoreDefaultStartValue, + 0, + &semstat); + /* mark this sema set allocated */ + ProcGlobal->freeSemMap[i] = (1 << PROC_NSEMS_PER_SET); + } } } } diff --git a/src/configure b/src/configure index 2f01fc2dc3..f72f96f09f 100755 --- a/src/configure +++ b/src/configure @@ -31,7 +31,7 @@ ac_help="$ac_help ac_help="$ac_help --with-pgport= change default startup port " ac_help="$ac_help - --with-maxbackends= set maximum number of server processes " + --with-maxbackends= set default maximum number of server processes " ac_help="$ac_help --with-tcl build Tcl interfaces and pgtclsh " ac_help="$ac_help @@ -879,18 +879,18 @@ EOF fi -echo $ac_n "checking setting MAXBACKENDS""... $ac_c" 1>&6 -echo "configure:884: checking setting MAXBACKENDS" >&5 +echo $ac_n "checking setting DEF_MAXBACKENDS""... $ac_c" 1>&6 +echo "configure:884: checking setting DEF_MAXBACKENDS" >&5 # Check whether --with-maxbackends or --without-maxbackends was given. if test "${with_maxbackends+set}" = set; then withval="$with_maxbackends" cat >> confdefs.h <&6 else cat >> confdefs.h <&6 diff --git a/src/configure.in b/src/configure.in index 40ccf127f7..33a67ec6b2 100644 --- a/src/configure.in +++ b/src/configure.in @@ -255,13 +255,13 @@ AC_ARG_WITH( AC_DEFINE_UNQUOTED(DEF_PGPORT, "5432") AC_MSG_RESULT(5432) ) -dnl MAXBACKENDS can be set by --with-maxbackends. Default value is 64. -AC_MSG_CHECKING(setting MAXBACKENDS) +dnl DEF_MAXBACKENDS can be set by --with-maxbackends. Default value is 64. +AC_MSG_CHECKING(setting DEF_MAXBACKENDS) AC_ARG_WITH( maxbackends, - [ --with-maxbackends= set maximum number of server processes ], - AC_DEFINE_UNQUOTED(MAXBACKENDS, ${withval}) AC_MSG_RESULT($with_maxbackends), - AC_DEFINE_UNQUOTED(MAXBACKENDS, 64) AC_MSG_RESULT(64) + [ --with-maxbackends= set default maximum number of server processes ], + AC_DEFINE_UNQUOTED(DEF_MAXBACKENDS, ${withval}) AC_MSG_RESULT($with_maxbackends), + AC_DEFINE_UNQUOTED(DEF_MAXBACKENDS, 64) AC_MSG_RESULT(64) ) dnl We exclude tcl support unless user says --with-tcl diff --git a/src/include/config.h.in b/src/include/config.h.in index ad277bd001..07e48851ff 100644 --- a/src/include/config.h.in +++ b/src/include/config.h.in @@ -9,10 +9,17 @@ #define CONFIG_H /* - * Maximum number of backend server processes per postmaster. + * Default runtime limit on number of backend server processes per postmaster; + * this is just the default setting for the postmaster's -N switch. * (Actual value is set by configure script.) */ -#undef MAXBACKENDS +#undef DEF_MAXBACKENDS + +/* + * Hard limit on number of backend server processes per postmaster. + * Increasing this costs about 32 bytes per process slot as of v 6.5. + */ +#define MAXBACKENDS (DEF_MAXBACKENDS > 1024 ? DEF_MAXBACKENDS : 1024) /* * Size of a disk block --- currently, this limits the size of a tuple. diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h index 76a11e5b13..e9a96c8190 100644 --- a/src/include/storage/ipc.h +++ b/src/include/storage/ipc.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: ipc.h,v 1.33 1999/02/19 06:06:33 tgl Exp $ + * $Id: ipc.h,v 1.34 1999/02/21 01:41:47 tgl Exp $ * * NOTES * This file is very architecture-specific. This stuff should actually @@ -96,7 +96,6 @@ extern void AttachSLockMemory(IPCKey key); #ifdef HAS_TEST_AND_SET -#define NSLOCKS 2048 #define NOLOCK 0 #define SHAREDLOCK 1 #define EXCLUSIVELOCK 2 diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index 85af296a5b..ce1f30133f 100644 --- a/src/include/storage/lock.h +++ b/src/include/storage/lock.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: lock.h,v 1.22 1999/02/19 06:06:35 tgl Exp $ + * $Id: lock.h,v 1.23 1999/02/21 01:41:47 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -28,14 +28,14 @@ typedef int MASK; /* ---------------------- * The following defines are used to estimate how much shared * memory the lock manager is going to require. + * See LockShmemSize() in lock.c. * - * MAXBACKENDS - The max number of concurrently running backends (config.h) * NLOCKS_PER_XACT - The number of unique locks acquired in a transaction * NLOCKENTS - The maximum number of lock entries in the lock table. * ---------------------- */ -#define NLOCKS_PER_XACT 40 -#define NLOCKENTS (NLOCKS_PER_XACT*MAXBACKENDS) +#define NLOCKS_PER_XACT 40 +#define NLOCKENTS(maxBackends) (NLOCKS_PER_XACT*(maxBackends)) typedef int LOCKMODE; typedef int LOCKMETHOD; @@ -242,7 +242,7 @@ extern bool LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode); extern void GrantLock(LOCK *lock, LOCKMODE lockmode); extern bool LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue); -extern int LockShmemSize(void); +extern int LockShmemSize(int maxBackends); extern bool LockingDisabled(void); extern bool DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check); -- 2.11.0