提交 9d197856 编写于 作者: T Tom Lane

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.
上级 75cccd0a
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* *
...@@ -162,14 +162,15 @@ static IpcMemoryKey ipc_key; ...@@ -162,14 +162,15 @@ static IpcMemoryKey ipc_key;
* adding to this. * adding to this.
*/ */
static int MaxBackends = MAXBACKENDS; static int MaxBackends = DEF_MAXBACKENDS;
/* /*
* MaxBackends is the actual soft limit on the number of backends * MaxBackends is the actual limit on the number of backends we will start.
* we will start. It defaults to the hard limit established at compilation * The default is established by configure, but it can be readjusted
* time, but can be readjusted with postmaster's xxx switch. * from 1..MAXBACKENDS with the postmaster -N switch.
* One reason to reduce MaxBackends is to allow startup under a kernel * Note that a larger MaxBackends value will increase the size of the
* that won't let us get MAXBACKENDS semaphores! * 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? */ static int NextBackendTag = MAXINT; /* XXX why count down not up? */
...@@ -641,8 +642,8 @@ usage(const char *progname) ...@@ -641,8 +642,8 @@ usage(const char *progname)
fprintf(stderr, "\t-b backend\tuse a specific backend server executable\n"); 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-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-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", fprintf(stderr, "\t-N nprocs\tset max number of backends (1..%d, default %d)\n",
MAXBACKENDS); MAXBACKENDS, DEF_MAXBACKENDS);
fprintf(stderr, "\t-n \t\tdon't reinitialize shared memory after abnormal exit\n"); 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-o option\tpass 'option' to each backend servers\n");
fprintf(stderr, "\t-p port\tspecify port for postmaster to listen on\n"); fprintf(stderr, "\t-p port\tspecify port for postmaster to listen on\n");
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* *
...@@ -677,9 +677,10 @@ struct ipcdummy ...@@ -677,9 +677,10 @@ struct ipcdummy
SLock *free; SLock *free;
int unused; int unused;
slock_t memlock; slock_t memlock;
SLock slocks[NSLOCKS]; SLock slocks[MAX_SPINS + 1];
}; };
static int SLockMemorySize = sizeof(struct ipcdummy);
#define SLOCKMEMORYSIZE sizeof(struct ipcdummy)
void void
CreateAndInitSLockMemory(IPCKey key) CreateAndInitSLockMemory(IPCKey key)
...@@ -688,7 +689,7 @@ CreateAndInitSLockMemory(IPCKey key) ...@@ -688,7 +689,7 @@ CreateAndInitSLockMemory(IPCKey key)
SLock *slckP; SLock *slckP;
SLockMemoryId = IpcMemoryCreate(key, SLockMemoryId = IpcMemoryCreate(key,
SLockMemorySize, SLOCKMEMORYSIZE,
0700); 0700);
AttachSLockMemory(key); AttachSLockMemory(key);
*FreeSLockPP = NULL; *FreeSLockPP = NULL;
...@@ -713,7 +714,7 @@ AttachSLockMemory(IPCKey key) ...@@ -713,7 +714,7 @@ AttachSLockMemory(IPCKey key)
struct ipcdummy *slockM; struct ipcdummy *slockM;
if (SLockMemoryId == -1) if (SLockMemoryId == -1)
SLockMemoryId = IpcMemoryIdGet(key, SLockMemorySize); SLockMemoryId = IpcMemoryIdGet(key, SLOCKMEMORYSIZE);
if (SLockMemoryId == -1) if (SLockMemoryId == -1)
elog(FATAL, "SLockMemory not in shared memory"); elog(FATAL, "SLockMemory not in shared memory");
slockM = (struct ipcdummy *) IpcMemoryAttach(SLockMemoryId); slockM = (struct ipcdummy *) IpcMemoryAttach(SLockMemoryId);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -72,7 +72,7 @@ CreateSharedMemoryAndSemaphores(IPCKey key, int maxBackends)
* ---------------- * ----------------
*/ */
CreateSpinlocks(IPCKeyGetSpinLockSemaphoreKey(key)); CreateSpinlocks(IPCKeyGetSpinLockSemaphoreKey(key));
size = BufferShmemSize() + LockShmemSize(); size = BufferShmemSize() + LockShmemSize(maxBackends);
#ifdef STABLE_MEMORY_STORAGE #ifdef STABLE_MEMORY_STORAGE
size += MMShmemSize(); size += MMShmemSize();
...@@ -113,15 +113,13 @@ CreateSharedMemoryAndSemaphores(IPCKey key, int maxBackends) ...@@ -113,15 +113,13 @@ CreateSharedMemoryAndSemaphores(IPCKey key, int maxBackends)
void void
AttachSharedMemoryAndSemaphores(IPCKey key) AttachSharedMemoryAndSemaphores(IPCKey key)
{ {
int size;
/* ---------------- /* ----------------
* create rather than attach if using private key * create rather than attach if using private key
* ---------------- * ----------------
*/ */
if (key == PrivateIPCKey) if (key == PrivateIPCKey)
{ {
CreateSharedMemoryAndSemaphores(key, 1); CreateSharedMemoryAndSemaphores(key, 16);
return; return;
} }
...@@ -136,8 +134,7 @@ AttachSharedMemoryAndSemaphores(IPCKey key) ...@@ -136,8 +134,7 @@ AttachSharedMemoryAndSemaphores(IPCKey key)
* attach the buffer manager buffer pool (and semaphore) * attach the buffer manager buffer pool (and semaphore)
* ---------------- * ----------------
*/ */
size = BufferShmemSize() + LockShmemSize(); InitShmem(key, 0);
InitShmem(key, size);
InitBufferPool(key); InitBufferPool(key);
/* ---------------- /* ----------------
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* Outside modules can create a lock table and acquire/release * Outside modules can create a lock table and acquire/release
...@@ -1478,36 +1478,37 @@ next_item: ...@@ -1478,36 +1478,37 @@ next_item:
} }
int int
LockShmemSize() LockShmemSize(int maxBackends)
{ {
int size = 0; int size = 0;
int nLockEnts = NLOCKENTS(maxBackends);
int nLockBuckets, int nLockBuckets,
nLockSegs; nLockSegs;
int nXidBuckets, int nXidBuckets,
nXidSegs; 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); nLockSegs = 1 << (int) my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1);
nXidBuckets = 1 << (int) my_log2((NLOCKS_PER_XACT - 1) / DEF_FFACTOR + 1); nXidBuckets = 1 << (int) my_log2((NLOCKS_PER_XACT - 1) / DEF_FFACTOR + 1);
nXidSegs = 1 << (int) my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1); nXidSegs = 1 << (int) my_log2((nLockBuckets - 1) / DEF_SEGSIZE + 1);
size += MAXALIGN(MAXBACKENDS * sizeof(PROC)); /* each MyProc */ size += MAXALIGN(maxBackends * sizeof(PROC)); /* each MyProc */
size += MAXALIGN(MAXBACKENDS * sizeof(LOCKMETHODCTL)); /* each size += MAXALIGN(maxBackends * sizeof(LOCKMETHODCTL)); /* each
* lockMethodTable->ctl */ * lockMethodTable->ctl */
size += MAXALIGN(sizeof(PROC_HDR)); /* ProcGlobal */ 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 += MAXALIGN(sizeof(HHDR));
size += nLockSegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT)); 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(BUCKET_INDEX)) +
MAXALIGN(sizeof(LOCK))); /* contains hash key */ 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 += MAXALIGN(sizeof(HHDR));
size += nXidSegs * MAXALIGN(DEF_SEGSIZE * sizeof(SEGMENT)); 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(BUCKET_INDEX)) +
MAXALIGN(sizeof(XIDLookupEnt))); /* contains hash key */ MAXALIGN(sizeof(XIDLookupEnt))); /* contains hash key */
...@@ -1673,8 +1674,8 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check) ...@@ -1673,8 +1674,8 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check)
break; break;
if (j >= nprocs && lock != findlock) if (j >= nprocs && lock != findlock)
{ {
Assert(nprocs < MAXBACKENDS);
checked_procs[nprocs++] = proc; checked_procs[nprocs++] = proc;
Assert(nprocs <= MAXBACKENDS);
/* /*
* For non-MyProc entries, we are looking only * For non-MyProc entries, we are looking only
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -46,7 +46,7 @@
* This is so that we can support more backends. (system-wide semaphore * This is so that we can support more backends. (system-wide semaphore
* sets run out pretty fast.) -ay 4/95 * 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 <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
...@@ -154,23 +154,28 @@ InitProcGlobal(IPCKey key, int maxBackends) ...@@ -154,23 +154,28 @@ InitProcGlobal(IPCKey key, int maxBackends)
*/ */
on_shmem_exit(ProcFreeAllSemaphores, NULL); on_shmem_exit(ProcFreeAllSemaphores, NULL);
/* Pre-create the semaphores for the first maxBackends processes */ /* Pre-create the semaphores for the first maxBackends processes,
for (i = 0; * unless we are running as a standalone backend.
i < (maxBackends+PROC_NSEMS_PER_SET-1) / PROC_NSEMS_PER_SET; */
i++) if (key != PrivateIPCKey)
{ {
IPCKey semKey = ProcGlobal->currKey + i; for (i = 0;
int semId; i < (maxBackends+PROC_NSEMS_PER_SET-1) / PROC_NSEMS_PER_SET;
int semstat; i++)
{
semId = IpcSemaphoreCreate(semKey, IPCKey semKey = ProcGlobal->currKey + i;
PROC_NSEMS_PER_SET, int semId;
IPCProtection, int semstat;
IpcSemaphoreDefaultStartValue,
0, semId = IpcSemaphoreCreate(semKey,
&semstat); PROC_NSEMS_PER_SET,
/* mark this sema set allocated */ IPCProtection,
ProcGlobal->freeSemMap[i] = (1 << PROC_NSEMS_PER_SET); IpcSemaphoreDefaultStartValue,
0,
&semstat);
/* mark this sema set allocated */
ProcGlobal->freeSemMap[i] = (1 << PROC_NSEMS_PER_SET);
}
} }
} }
} }
......
...@@ -31,7 +31,7 @@ ac_help="$ac_help ...@@ -31,7 +31,7 @@ ac_help="$ac_help
ac_help="$ac_help ac_help="$ac_help
--with-pgport=<portnum> change default startup port " --with-pgport=<portnum> change default startup port "
ac_help="$ac_help ac_help="$ac_help
--with-maxbackends=<n> set maximum number of server processes " --with-maxbackends=<n> set default maximum number of server processes "
ac_help="$ac_help ac_help="$ac_help
--with-tcl build Tcl interfaces and pgtclsh " --with-tcl build Tcl interfaces and pgtclsh "
ac_help="$ac_help ac_help="$ac_help
...@@ -879,18 +879,18 @@ EOF ...@@ -879,18 +879,18 @@ EOF
fi fi
echo $ac_n "checking setting MAXBACKENDS""... $ac_c" 1>&6 echo $ac_n "checking setting DEF_MAXBACKENDS""... $ac_c" 1>&6
echo "configure:884: checking setting MAXBACKENDS" >&5 echo "configure:884: checking setting DEF_MAXBACKENDS" >&5
# Check whether --with-maxbackends or --without-maxbackends was given. # Check whether --with-maxbackends or --without-maxbackends was given.
if test "${with_maxbackends+set}" = set; then if test "${with_maxbackends+set}" = set; then
withval="$with_maxbackends" withval="$with_maxbackends"
cat >> confdefs.h <<EOF cat >> confdefs.h <<EOF
#define MAXBACKENDS ${withval} #define DEF_MAXBACKENDS ${withval}
EOF EOF
echo "$ac_t""$with_maxbackends" 1>&6 echo "$ac_t""$with_maxbackends" 1>&6
else else
cat >> confdefs.h <<EOF cat >> confdefs.h <<EOF
#define MAXBACKENDS 64 #define DEF_MAXBACKENDS 64
EOF EOF
echo "$ac_t""64" 1>&6 echo "$ac_t""64" 1>&6
......
...@@ -255,13 +255,13 @@ AC_ARG_WITH( ...@@ -255,13 +255,13 @@ AC_ARG_WITH(
AC_DEFINE_UNQUOTED(DEF_PGPORT, "5432") AC_MSG_RESULT(5432) AC_DEFINE_UNQUOTED(DEF_PGPORT, "5432") AC_MSG_RESULT(5432)
) )
dnl MAXBACKENDS can be set by --with-maxbackends. Default value is 64. dnl DEF_MAXBACKENDS can be set by --with-maxbackends. Default value is 64.
AC_MSG_CHECKING(setting MAXBACKENDS) AC_MSG_CHECKING(setting DEF_MAXBACKENDS)
AC_ARG_WITH( AC_ARG_WITH(
maxbackends, maxbackends,
[ --with-maxbackends=<n> set maximum number of server processes ], [ --with-maxbackends=<n> set default maximum number of server processes ],
AC_DEFINE_UNQUOTED(MAXBACKENDS, ${withval}) AC_MSG_RESULT($with_maxbackends), AC_DEFINE_UNQUOTED(DEF_MAXBACKENDS, ${withval}) AC_MSG_RESULT($with_maxbackends),
AC_DEFINE_UNQUOTED(MAXBACKENDS, 64) AC_MSG_RESULT(64) AC_DEFINE_UNQUOTED(DEF_MAXBACKENDS, 64) AC_MSG_RESULT(64)
) )
dnl We exclude tcl support unless user says --with-tcl dnl We exclude tcl support unless user says --with-tcl
......
...@@ -9,10 +9,17 @@ ...@@ -9,10 +9,17 @@
#define CONFIG_H #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.) * (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. * Size of a disk block --- currently, this limits the size of a tuple.
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* This file is very architecture-specific. This stuff should actually * This file is very architecture-specific. This stuff should actually
...@@ -96,7 +96,6 @@ extern void AttachSLockMemory(IPCKey key); ...@@ -96,7 +96,6 @@ extern void AttachSLockMemory(IPCKey key);
#ifdef HAS_TEST_AND_SET #ifdef HAS_TEST_AND_SET
#define NSLOCKS 2048
#define NOLOCK 0 #define NOLOCK 0
#define SHAREDLOCK 1 #define SHAREDLOCK 1
#define EXCLUSIVELOCK 2 #define EXCLUSIVELOCK 2
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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; ...@@ -28,14 +28,14 @@ typedef int MASK;
/* ---------------------- /* ----------------------
* The following defines are used to estimate how much shared * The following defines are used to estimate how much shared
* memory the lock manager is going to require. * 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 * NLOCKS_PER_XACT - The number of unique locks acquired in a transaction
* NLOCKENTS - The maximum number of lock entries in the lock table. * NLOCKENTS - The maximum number of lock entries in the lock table.
* ---------------------- * ----------------------
*/ */
#define NLOCKS_PER_XACT 40 #define NLOCKS_PER_XACT 40
#define NLOCKENTS (NLOCKS_PER_XACT*MAXBACKENDS) #define NLOCKENTS(maxBackends) (NLOCKS_PER_XACT*(maxBackends))
typedef int LOCKMODE; typedef int LOCKMODE;
typedef int LOCKMETHOD; typedef int LOCKMETHOD;
...@@ -242,7 +242,7 @@ extern bool LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, ...@@ -242,7 +242,7 @@ extern bool LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag,
LOCKMODE lockmode); LOCKMODE lockmode);
extern void GrantLock(LOCK *lock, LOCKMODE lockmode); extern void GrantLock(LOCK *lock, LOCKMODE lockmode);
extern bool LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue); extern bool LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue);
extern int LockShmemSize(void); extern int LockShmemSize(int maxBackends);
extern bool LockingDisabled(void); extern bool LockingDisabled(void);
extern bool DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, extern bool DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock,
bool skip_check); bool skip_check);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册