1
0
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:
Tom Lane
2000-11-12 20:51:52 +00:00
parent c48025e799
commit ebb0a20149
10 changed files with 153 additions and 235 deletions

View File

@@ -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);