mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
Keep track of the last active slot in the shared ProcState array, so
that search loops only have to scan that far and not through all maxBackends entries. This eliminates a performance penalty for setting maxBackends much higher than the average number of active backends. Also, eliminate no-longer-used 'backend tag' concept. Remove setting of environment variables at backend start (except for CYR_RECODE), since none of them are being examined by the backend any longer.
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.181 2000/11/09 11:25:59 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.182 2000/11/12 20:51:51 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
*
|
||||
@@ -107,55 +107,45 @@ typedef struct bkend
|
||||
Port *MyBackendPort = NULL;
|
||||
|
||||
/* list of active backends. For garbage collection only now. */
|
||||
|
||||
static Dllist *BackendList;
|
||||
|
||||
/* list of ports associated with still open, but incomplete connections */
|
||||
static Dllist *PortList;
|
||||
|
||||
/* The socket number we are listening for connections on */
|
||||
int PostPortName;
|
||||
|
||||
/*
|
||||
* This is a boolean indicating that there is at least one backend that
|
||||
* is accessing the current shared memory and semaphores. Between the
|
||||
* time that we start up, or throw away shared memory segments and start
|
||||
* over, and the time we generate the next backend (because we received a
|
||||
* connection request), it is false. Other times, it is true.
|
||||
*/
|
||||
/*
|
||||
* This is a sequence number that indicates how many times we've had to
|
||||
* throw away the shared memory and start over because we doubted its
|
||||
* integrity. It starts off at zero and is incremented every time we
|
||||
* start over. We use this to ensure that we use a new IPC shared memory
|
||||
* key for the new shared memory segment in case the old segment isn't
|
||||
* entirely gone yet.
|
||||
*
|
||||
* The sequence actually cycles back to 0 after 9, so pathologically there
|
||||
* could be an IPC failure if 10 sets of backends are all stuck and won't
|
||||
* release IPC resources.
|
||||
*/
|
||||
static short shmem_seq = 0;
|
||||
|
||||
/*
|
||||
* This is a sequence number that indicates how many times we've had to
|
||||
* throw away the shared memory and start over because we doubted its
|
||||
* integrity. It starts off at zero and is incremented every time we
|
||||
* start over. We use this to ensure that we use a new IPC shared memory
|
||||
* key for the new shared memory segment in case the old segment isn't
|
||||
* entirely gone yet.
|
||||
*
|
||||
* The sequence actually cycles back to 0 after 9, so pathologically there
|
||||
* could be an IPC failure if 10 sets of backends are all stuck and won't
|
||||
* release IPC resources.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is the base IPC shared memory key. Other keys are generated by
|
||||
* adding to this.
|
||||
*/
|
||||
static IpcMemoryKey ipc_key;
|
||||
|
||||
/*
|
||||
* This is the base IPC shared memory key. Other keys are generated by
|
||||
* adding to this.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
int MaxBackends = DEF_MAXBACKENDS;
|
||||
|
||||
/*
|
||||
* 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 = INT_MAX; /* XXX why count down not up? */
|
||||
static char *progname = (char *) NULL;
|
||||
static char **real_argv;
|
||||
static int real_argc;
|
||||
@@ -587,6 +577,22 @@ PostmasterMain(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (DebugLvl > 2)
|
||||
{
|
||||
extern char **environ;
|
||||
char **p;
|
||||
|
||||
fprintf(stderr, "%s: PostmasterMain: initial environ dump:\n",
|
||||
progname);
|
||||
fprintf(stderr, "-----------------------------------------\n");
|
||||
for (p = environ; *p; ++p)
|
||||
fprintf(stderr, "\t%s\n", *p);
|
||||
fprintf(stderr, "-----------------------------------------\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Establish input sockets.
|
||||
*/
|
||||
#ifdef USE_SSL
|
||||
if (EnableSSL && !NetServer)
|
||||
{
|
||||
@@ -600,7 +606,8 @@ PostmasterMain(int argc, char *argv[])
|
||||
|
||||
if (NetServer)
|
||||
{
|
||||
status = StreamServerPort(AF_INET, (unsigned short)PostPortName, &ServerSock_INET);
|
||||
status = StreamServerPort(AF_INET, (unsigned short) PostPortName,
|
||||
&ServerSock_INET);
|
||||
if (status != STATUS_OK)
|
||||
{
|
||||
fprintf(stderr, "%s: cannot create INET stream port\n",
|
||||
@@ -610,7 +617,8 @@ PostmasterMain(int argc, char *argv[])
|
||||
}
|
||||
|
||||
#ifdef HAVE_UNIX_SOCKETS
|
||||
status = StreamServerPort(AF_UNIX, (unsigned short)PostPortName, &ServerSock_UNIX);
|
||||
status = StreamServerPort(AF_UNIX, (unsigned short) PostPortName,
|
||||
&ServerSock_UNIX);
|
||||
if (status != STATUS_OK)
|
||||
{
|
||||
fprintf(stderr, "%s: cannot create UNIX stream port\n",
|
||||
@@ -618,10 +626,11 @@ PostmasterMain(int argc, char *argv[])
|
||||
ExitPostmaster(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set up shared memory and semaphores */
|
||||
reset_shared(PostPortName);
|
||||
|
||||
/* Init XLOG pathes */
|
||||
/* Init XLOG paths */
|
||||
snprintf(XLogDir, MAXPGPATH, "%s/pg_xlog", DataDir);
|
||||
snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
|
||||
|
||||
@@ -1706,43 +1715,7 @@ static int
|
||||
BackendStartup(Port *port)
|
||||
{
|
||||
Backend *bn; /* for backend cleanup */
|
||||
int pid,
|
||||
i;
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
#define NR_ENVIRONMENT_VBL 5
|
||||
char ChTable[80];
|
||||
|
||||
#else
|
||||
#define NR_ENVIRONMENT_VBL 4
|
||||
#endif
|
||||
|
||||
static char envEntry[NR_ENVIRONMENT_VBL][2 * ARGV_SIZE];
|
||||
|
||||
for (i = 0; i < NR_ENVIRONMENT_VBL; ++i)
|
||||
MemSet(envEntry[i], 0, 2 * ARGV_SIZE);
|
||||
|
||||
/*
|
||||
* Set up the necessary environment variables for the backend This
|
||||
* should really be some sort of message....
|
||||
*/
|
||||
sprintf(envEntry[0], "POSTPORT=%d", PostPortName);
|
||||
putenv(envEntry[0]);
|
||||
sprintf(envEntry[1], "POSTID=%d", NextBackendTag);
|
||||
putenv(envEntry[1]);
|
||||
sprintf(envEntry[2], "PGDATA=%s", DataDir);
|
||||
putenv(envEntry[2]);
|
||||
sprintf(envEntry[3], "IPC_KEY=%d", ipc_key);
|
||||
putenv(envEntry[3]);
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
GetCharSetByHost(ChTable, port->raddr.in.sin_addr.s_addr, DataDir);
|
||||
if (*ChTable != '\0')
|
||||
{
|
||||
sprintf(envEntry[4], "PG_RECODETABLE=%s", ChTable);
|
||||
putenv(envEntry[4]);
|
||||
}
|
||||
#endif
|
||||
int pid;
|
||||
|
||||
/*
|
||||
* Compute the cancel key that will be assigned to this backend. The
|
||||
@@ -1751,19 +1724,6 @@ BackendStartup(Port *port)
|
||||
*/
|
||||
MyCancelKey = PostmasterRandom();
|
||||
|
||||
if (DebugLvl > 2)
|
||||
{
|
||||
char **p;
|
||||
extern char **environ;
|
||||
|
||||
fprintf(stderr, "%s: BackendStartup: environ dump:\n",
|
||||
progname);
|
||||
fprintf(stderr, "-----------------------------------------\n");
|
||||
for (p = environ; *p; ++p)
|
||||
fprintf(stderr, "\t%s\n", *p);
|
||||
fprintf(stderr, "-----------------------------------------\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush stdio channels just before fork, to avoid double-output
|
||||
* problems. Ideally we'd use fflush(NULL) here, but there are still a
|
||||
@@ -1779,12 +1739,30 @@ BackendStartup(Port *port)
|
||||
/* Specific beos actions before backend startup */
|
||||
beos_before_backend_startup();
|
||||
#endif
|
||||
|
||||
if ((pid = fork()) == 0)
|
||||
{ /* child */
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos backend stratup actions */
|
||||
/* Specific beos backend startup actions */
|
||||
beos_backend_startup();
|
||||
#endif
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
{
|
||||
/* Save charset for this host while we still have client addr */
|
||||
char ChTable[80];
|
||||
static char cyrEnvironment[100];
|
||||
|
||||
GetCharSetByHost(ChTable, port->raddr.in.sin_addr.s_addr, DataDir);
|
||||
if (*ChTable != '\0')
|
||||
{
|
||||
snprintf(cyrEnvironment, sizeof(cyrEnvironment),
|
||||
"PG_RECODETABLE=%s", ChTable);
|
||||
putenv(cyrEnvironment);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (DoBackend(port))
|
||||
{
|
||||
fprintf(stderr, "%s child[%d]: BackendStartup: backend startup failed\n",
|
||||
@@ -1799,7 +1777,7 @@ BackendStartup(Port *port)
|
||||
if (pid < 0)
|
||||
{
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos backend stratup actions */
|
||||
/* Specific beos backend startup actions */
|
||||
beos_backend_startup_failed();
|
||||
#endif
|
||||
fprintf(stderr, "%s: BackendStartup: fork failed: %s\n",
|
||||
@@ -1812,14 +1790,6 @@ BackendStartup(Port *port)
|
||||
progname, pid, port->user, port->database,
|
||||
port->sock);
|
||||
|
||||
/* Generate a new backend tag for every backend we start */
|
||||
|
||||
/*
|
||||
* XXX theoretically this could wrap around, if you have the patience
|
||||
* to start 2^31 backends ...
|
||||
*/
|
||||
NextBackendTag -= 1;
|
||||
|
||||
/*
|
||||
* Everything's been successful, it's safe to add this backend to our
|
||||
* list of backends.
|
||||
@@ -2179,21 +2149,7 @@ static pid_t
|
||||
SSDataBase(int xlop)
|
||||
{
|
||||
pid_t pid;
|
||||
int i;
|
||||
Backend *bn;
|
||||
static char ssEntry[4][2 * ARGV_SIZE];
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
MemSet(ssEntry[i], 0, 2 * ARGV_SIZE);
|
||||
|
||||
sprintf(ssEntry[0], "POSTPORT=%d", PostPortName);
|
||||
putenv(ssEntry[0]);
|
||||
sprintf(ssEntry[1], "POSTID=%d", NextBackendTag);
|
||||
putenv(ssEntry[1]);
|
||||
sprintf(ssEntry[2], "PGDATA=%s", DataDir);
|
||||
putenv(ssEntry[2]);
|
||||
sprintf(ssEntry[3], "IPC_KEY=%d", ipc_key);
|
||||
putenv(ssEntry[3]);
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
@@ -2258,8 +2214,6 @@ SSDataBase(int xlop)
|
||||
ExitPostmaster(1);
|
||||
}
|
||||
|
||||
NextBackendTag -= 1;
|
||||
|
||||
if (xlop != BS_XLOG_CHECKPOINT)
|
||||
return(pid);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user