Commit ebb0a201 authored by Tom Lane's avatar Tom Lane

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.
parent c48025e7
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.65 2000/11/08 23:24:24 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.66 2000/11/12 20:51:50 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -225,7 +225,7 @@ dropdb(const char *dbname) ...@@ -225,7 +225,7 @@ dropdb(const char *dbname)
/* /*
* Check for active backends in the target database. * Check for active backends in the target database.
*/ */
if (DatabaseHasActiveBackends(db_id)) if (DatabaseHasActiveBackends(db_id, false))
{ {
heap_close(pgdbrel, AccessExclusiveLock); heap_close(pgdbrel, AccessExclusiveLock);
elog(ERROR, "DROP DATABASE: database \"%s\" is being accessed by other users", dbname); elog(ERROR, "DROP DATABASE: database \"%s\" is being accessed by other users", dbname);
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* *
...@@ -107,55 +107,45 @@ typedef struct bkend ...@@ -107,55 +107,45 @@ typedef struct bkend
Port *MyBackendPort = NULL; Port *MyBackendPort = NULL;
/* list of active backends. For garbage collection only now. */ /* list of active backends. For garbage collection only now. */
static Dllist *BackendList; static Dllist *BackendList;
/* list of ports associated with still open, but incomplete connections */ /* list of ports associated with still open, but incomplete connections */
static Dllist *PortList; static Dllist *PortList;
/* The socket number we are listening for connections on */
int PostPortName; int PostPortName;
/* /*
* This is a boolean indicating that there is at least one backend that * This is a sequence number that indicates how many times we've had to
* is accessing the current shared memory and semaphores. Between the * throw away the shared memory and start over because we doubted its
* time that we start up, or throw away shared memory segments and start * integrity. It starts off at zero and is incremented every time we
* over, and the time we generate the next backend (because we received a * start over. We use this to ensure that we use a new IPC shared memory
* connection request), it is false. Other times, it is true. * 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; static short shmem_seq = 0;
/* /*
* This is a sequence number that indicates how many times we've had to * This is the base IPC shared memory key. Other keys are generated by
* throw away the shared memory and start over because we doubted its * adding to this.
* 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 IpcMemoryKey ipc_key; static IpcMemoryKey ipc_key;
/* /*
* This is the base IPC shared memory key. Other keys are generated by * MaxBackends is the actual limit on the number of backends we will
* adding to this. * 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; 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 *progname = (char *) NULL;
static char **real_argv; static char **real_argv;
static int real_argc; static int real_argc;
...@@ -587,6 +577,22 @@ PostmasterMain(int argc, char *argv[]) ...@@ -587,6 +577,22 @@ PostmasterMain(int argc, char *argv[])
exit(1); 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 #ifdef USE_SSL
if (EnableSSL && !NetServer) if (EnableSSL && !NetServer)
{ {
...@@ -600,7 +606,8 @@ PostmasterMain(int argc, char *argv[]) ...@@ -600,7 +606,8 @@ PostmasterMain(int argc, char *argv[])
if (NetServer) if (NetServer)
{ {
status = StreamServerPort(AF_INET, (unsigned short)PostPortName, &ServerSock_INET); status = StreamServerPort(AF_INET, (unsigned short) PostPortName,
&ServerSock_INET);
if (status != STATUS_OK) if (status != STATUS_OK)
{ {
fprintf(stderr, "%s: cannot create INET stream port\n", fprintf(stderr, "%s: cannot create INET stream port\n",
...@@ -610,7 +617,8 @@ PostmasterMain(int argc, char *argv[]) ...@@ -610,7 +617,8 @@ PostmasterMain(int argc, char *argv[])
} }
#ifdef HAVE_UNIX_SOCKETS #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) if (status != STATUS_OK)
{ {
fprintf(stderr, "%s: cannot create UNIX stream port\n", fprintf(stderr, "%s: cannot create UNIX stream port\n",
...@@ -618,10 +626,11 @@ PostmasterMain(int argc, char *argv[]) ...@@ -618,10 +626,11 @@ PostmasterMain(int argc, char *argv[])
ExitPostmaster(1); ExitPostmaster(1);
} }
#endif #endif
/* set up shared memory and semaphores */ /* set up shared memory and semaphores */
reset_shared(PostPortName); reset_shared(PostPortName);
/* Init XLOG pathes */ /* Init XLOG paths */
snprintf(XLogDir, MAXPGPATH, "%s/pg_xlog", DataDir); snprintf(XLogDir, MAXPGPATH, "%s/pg_xlog", DataDir);
snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir); snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
...@@ -1706,43 +1715,7 @@ static int ...@@ -1706,43 +1715,7 @@ static int
BackendStartup(Port *port) BackendStartup(Port *port)
{ {
Backend *bn; /* for backend cleanup */ Backend *bn; /* for backend cleanup */
int pid, 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
/* /*
* Compute the cancel key that will be assigned to this backend. The * Compute the cancel key that will be assigned to this backend. The
...@@ -1751,19 +1724,6 @@ BackendStartup(Port *port) ...@@ -1751,19 +1724,6 @@ BackendStartup(Port *port)
*/ */
MyCancelKey = PostmasterRandom(); 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 * Flush stdio channels just before fork, to avoid double-output
* problems. Ideally we'd use fflush(NULL) here, but there are still a * problems. Ideally we'd use fflush(NULL) here, but there are still a
...@@ -1779,12 +1739,30 @@ BackendStartup(Port *port) ...@@ -1779,12 +1739,30 @@ BackendStartup(Port *port)
/* Specific beos actions before backend startup */ /* Specific beos actions before backend startup */
beos_before_backend_startup(); beos_before_backend_startup();
#endif #endif
if ((pid = fork()) == 0) if ((pid = fork()) == 0)
{ /* child */ { /* child */
#ifdef __BEOS__ #ifdef __BEOS__
/* Specific beos backend stratup actions */ /* Specific beos backend startup actions */
beos_backend_startup(); beos_backend_startup();
#endif #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)) if (DoBackend(port))
{ {
fprintf(stderr, "%s child[%d]: BackendStartup: backend startup failed\n", fprintf(stderr, "%s child[%d]: BackendStartup: backend startup failed\n",
...@@ -1799,7 +1777,7 @@ BackendStartup(Port *port) ...@@ -1799,7 +1777,7 @@ BackendStartup(Port *port)
if (pid < 0) if (pid < 0)
{ {
#ifdef __BEOS__ #ifdef __BEOS__
/* Specific beos backend stratup actions */ /* Specific beos backend startup actions */
beos_backend_startup_failed(); beos_backend_startup_failed();
#endif #endif
fprintf(stderr, "%s: BackendStartup: fork failed: %s\n", fprintf(stderr, "%s: BackendStartup: fork failed: %s\n",
...@@ -1812,14 +1790,6 @@ BackendStartup(Port *port) ...@@ -1812,14 +1790,6 @@ BackendStartup(Port *port)
progname, pid, port->user, port->database, progname, pid, port->user, port->database,
port->sock); 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 * Everything's been successful, it's safe to add this backend to our
* list of backends. * list of backends.
...@@ -2179,21 +2149,7 @@ static pid_t ...@@ -2179,21 +2149,7 @@ static pid_t
SSDataBase(int xlop) SSDataBase(int xlop)
{ {
pid_t pid; pid_t pid;
int i;
Backend *bn; 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(stdout);
fflush(stderr); fflush(stderr);
...@@ -2258,8 +2214,6 @@ SSDataBase(int xlop) ...@@ -2258,8 +2214,6 @@ SSDataBase(int xlop)
ExitPostmaster(1); ExitPostmaster(1);
} }
NextBackendTag -= 1;
if (xlop != BS_XLOG_CHECKPOINT) if (xlop != BS_XLOG_CHECKPOINT)
return(pid); return(pid);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.22 2000/11/05 22:50:20 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.23 2000/11/12 20:51:51 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -185,6 +185,9 @@ void ...@@ -185,6 +185,9 @@ void
/* /*
* DatabaseHasActiveBackends -- are there any backends running in the given DB * DatabaseHasActiveBackends -- are there any backends running in the given DB
* *
* If 'ignoreMyself' is TRUE, ignore this particular backend while checking
* for backends in the target database.
*
* This function is used to interlock DROP DATABASE against there being * This function is used to interlock DROP DATABASE against there being
* any active backends in the target DB --- dropping the DB while active * any active backends in the target DB --- dropping the DB while active
* backends remain would be a Bad Thing. Note that we cannot detect here * backends remain would be a Bad Thing. Note that we cannot detect here
...@@ -194,7 +197,7 @@ void ...@@ -194,7 +197,7 @@ void
*/ */
bool bool
DatabaseHasActiveBackends(Oid databaseId) DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself)
{ {
bool result = false; bool result = false;
SISeg *segP = shmInvalBuffer; SISeg *segP = shmInvalBuffer;
...@@ -203,7 +206,7 @@ DatabaseHasActiveBackends(Oid databaseId) ...@@ -203,7 +206,7 @@ DatabaseHasActiveBackends(Oid databaseId)
SpinAcquire(SInvalLock); SpinAcquire(SInvalLock);
for (index = 0; index < segP->maxBackends; index++) for (index = 0; index < segP->lastBackend; index++)
{ {
SHMEM_OFFSET pOffset = stateP[index].procStruct; SHMEM_OFFSET pOffset = stateP[index].procStruct;
...@@ -213,6 +216,9 @@ DatabaseHasActiveBackends(Oid databaseId) ...@@ -213,6 +216,9 @@ DatabaseHasActiveBackends(Oid databaseId)
if (proc->databaseId == databaseId) if (proc->databaseId == databaseId)
{ {
if (ignoreMyself && proc == MyProc)
continue;
result = true; result = true;
break; break;
} }
...@@ -237,7 +243,7 @@ TransactionIdIsInProgress(TransactionId xid) ...@@ -237,7 +243,7 @@ TransactionIdIsInProgress(TransactionId xid)
SpinAcquire(SInvalLock); SpinAcquire(SInvalLock);
for (index = 0; index < segP->maxBackends; index++) for (index = 0; index < segP->lastBackend; index++)
{ {
SHMEM_OFFSET pOffset = stateP[index].procStruct; SHMEM_OFFSET pOffset = stateP[index].procStruct;
...@@ -275,7 +281,7 @@ GetXmaxRecent(TransactionId *XmaxRecent) ...@@ -275,7 +281,7 @@ GetXmaxRecent(TransactionId *XmaxRecent)
SpinAcquire(SInvalLock); SpinAcquire(SInvalLock);
for (index = 0; index < segP->maxBackends; index++) for (index = 0; index < segP->lastBackend; index++)
{ {
SHMEM_OFFSET pOffset = stateP[index].procStruct; SHMEM_OFFSET pOffset = stateP[index].procStruct;
...@@ -309,11 +315,11 @@ GetSnapshotData(bool serializable) ...@@ -309,11 +315,11 @@ GetSnapshotData(bool serializable)
int count = 0; int count = 0;
/* /*
* There can be no more than maxBackends active transactions, so this * There can be no more than lastBackend active transactions, so this
* is enough space: * is enough space:
*/ */
snapshot->xip = (TransactionId *) snapshot->xip = (TransactionId *)
malloc(segP->maxBackends * sizeof(TransactionId)); malloc(segP->lastBackend * sizeof(TransactionId));
snapshot->xmin = GetCurrentTransactionId(); snapshot->xmin = GetCurrentTransactionId();
SpinAcquire(SInvalLock); SpinAcquire(SInvalLock);
...@@ -326,7 +332,7 @@ GetSnapshotData(bool serializable) ...@@ -326,7 +332,7 @@ GetSnapshotData(bool serializable)
*/ */
ReadNewTransactionId(&(snapshot->xmax)); ReadNewTransactionId(&(snapshot->xmax));
for (index = 0; index < segP->maxBackends; index++) for (index = 0; index < segP->lastBackend; index++)
{ {
SHMEM_OFFSET pOffset = stateP[index].procStruct; SHMEM_OFFSET pOffset = stateP[index].procStruct;
...@@ -386,7 +392,7 @@ GetUndoRecPtr(void) ...@@ -386,7 +392,7 @@ GetUndoRecPtr(void)
SpinAcquire(SInvalLock); SpinAcquire(SInvalLock);
for (index = 0; index < segP->maxBackends; index++) for (index = 0; index < segP->lastBackend; index++)
{ {
SHMEM_OFFSET pOffset = stateP[index].procStruct; SHMEM_OFFSET pOffset = stateP[index].procStruct;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.34 2000/10/02 21:45:32 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.35 2000/11/12 20:51:51 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -117,6 +117,7 @@ SISegInit(SISeg *segP, int maxBackends) ...@@ -117,6 +117,7 @@ SISegInit(SISeg *segP, int maxBackends)
/* Clear message counters, save size of procState array */ /* Clear message counters, save size of procState array */
segP->minMsgNum = 0; segP->minMsgNum = 0;
segP->maxMsgNum = 0; segP->maxMsgNum = 0;
segP->lastBackend = 0;
segP->maxBackends = maxBackends; segP->maxBackends = maxBackends;
/* The buffer[] array is initially all unused, so we need not fill it */ /* The buffer[] array is initially all unused, so we need not fill it */
...@@ -126,7 +127,6 @@ SISegInit(SISeg *segP, int maxBackends) ...@@ -126,7 +127,6 @@ SISegInit(SISeg *segP, int maxBackends)
{ {
segP->procState[i].nextMsgNum = -1; /* inactive */ segP->procState[i].nextMsgNum = -1; /* inactive */
segP->procState[i].resetState = false; segP->procState[i].resetState = false;
segP->procState[i].tag = InvalidBackendTag;
segP->procState[i].procStruct = INVALID_OFFSET; segP->procState[i].procStruct = INVALID_OFFSET;
} }
} }
...@@ -145,47 +145,45 @@ SIBackendInit(SISeg *segP) ...@@ -145,47 +145,45 @@ SIBackendInit(SISeg *segP)
int index; int index;
ProcState *stateP = NULL; ProcState *stateP = NULL;
Assert(MyBackendTag > 0);
/* Check for duplicate backend tags (should never happen) */
for (index = 0; index < segP->maxBackends; index++)
{
if (segP->procState[index].tag == MyBackendTag)
elog(FATAL, "SIBackendInit: tag %d already in use", MyBackendTag);
}
/* Look for a free entry in the procState array */ /* Look for a free entry in the procState array */
for (index = 0; index < segP->maxBackends; index++) for (index = 0; index < segP->lastBackend; index++)
{ {
if (segP->procState[index].tag == InvalidBackendTag) if (segP->procState[index].nextMsgNum < 0) /* inactive slot? */
{ {
stateP = &segP->procState[index]; stateP = &segP->procState[index];
break; break;
} }
} }
/*
* elog() with spinlock held is probably not too cool, but this
* condition should never happen anyway.
*/
if (stateP == NULL) if (stateP == NULL)
{ {
elog(NOTICE, "SIBackendInit: no free procState slot available"); if (segP->lastBackend < segP->maxBackends)
MyBackendId = InvalidBackendTag; {
return 0; stateP = &segP->procState[segP->lastBackend];
Assert(stateP->nextMsgNum < 0);
segP->lastBackend++;
}
else
{
/*
* elog() with spinlock held is probably not too cool, but this
* condition should never happen anyway.
*/
elog(NOTICE, "SIBackendInit: no free procState slot available");
MyBackendId = InvalidBackendId;
return 0;
}
} }
MyBackendId = (stateP - &segP->procState[0]) + 1; MyBackendId = (stateP - &segP->procState[0]) + 1;
#ifdef INVALIDDEBUG #ifdef INVALIDDEBUG
elog(DEBUG, "SIBackendInit: backend tag %d; backend id %d.", elog(DEBUG, "SIBackendInit: backend id %d", MyBackendId);
MyBackendTag, MyBackendId);
#endif /* INVALIDDEBUG */ #endif /* INVALIDDEBUG */
/* mark myself active, with all extant messages already read */ /* mark myself active, with all extant messages already read */
stateP->nextMsgNum = segP->maxMsgNum; stateP->nextMsgNum = segP->maxMsgNum;
stateP->resetState = false; stateP->resetState = false;
stateP->tag = MyBackendTag;
stateP->procStruct = MAKE_OFFSET(MyProc); stateP->procStruct = MAKE_OFFSET(MyProc);
/* register exit routine to mark my entry inactive at exit */ /* register exit routine to mark my entry inactive at exit */
...@@ -206,17 +204,26 @@ SIBackendInit(SISeg *segP) ...@@ -206,17 +204,26 @@ SIBackendInit(SISeg *segP)
static void static void
CleanupInvalidationState(int status, Datum arg) CleanupInvalidationState(int status, Datum arg)
{ {
SISeg *segP = (void*) DatumGetPointer(arg); SISeg *segP = (SISeg *) DatumGetPointer(arg);
int i;
Assert(PointerIsValid(segP)); Assert(PointerIsValid(segP));
SpinAcquire(SInvalLock); SpinAcquire(SInvalLock);
/* Mark myself inactive */
segP->procState[MyBackendId - 1].nextMsgNum = -1; segP->procState[MyBackendId - 1].nextMsgNum = -1;
segP->procState[MyBackendId - 1].resetState = false; segP->procState[MyBackendId - 1].resetState = false;
segP->procState[MyBackendId - 1].tag = InvalidBackendTag;
segP->procState[MyBackendId - 1].procStruct = INVALID_OFFSET; segP->procState[MyBackendId - 1].procStruct = INVALID_OFFSET;
/* Recompute index of last active backend */
for (i = segP->lastBackend; i > 0; i--)
{
if (segP->procState[i - 1].nextMsgNum >= 0)
break;
}
segP->lastBackend = i;
SpinRelease(SInvalLock); SpinRelease(SInvalLock);
} }
...@@ -299,7 +306,7 @@ SISetProcStateInvalid(SISeg *segP) ...@@ -299,7 +306,7 @@ SISetProcStateInvalid(SISeg *segP)
segP->minMsgNum = 0; segP->minMsgNum = 0;
segP->maxMsgNum = 0; segP->maxMsgNum = 0;
for (i = 0; i < segP->maxBackends; i++) for (i = 0; i < segP->lastBackend; i++)
{ {
if (segP->procState[i].nextMsgNum >= 0) /* active backend? */ if (segP->procState[i].nextMsgNum >= 0) /* active backend? */
{ {
...@@ -325,8 +332,6 @@ SIGetDataEntry(SISeg *segP, int backendId, ...@@ -325,8 +332,6 @@ SIGetDataEntry(SISeg *segP, int backendId,
{ {
ProcState *stateP = &segP->procState[backendId - 1]; ProcState *stateP = &segP->procState[backendId - 1];
Assert(stateP->tag == MyBackendTag);
if (stateP->resetState) if (stateP->resetState)
{ {
...@@ -373,7 +378,7 @@ SIDelExpiredDataEntries(SISeg *segP) ...@@ -373,7 +378,7 @@ SIDelExpiredDataEntries(SISeg *segP)
/* Recompute minMsgNum = minimum of all backends' nextMsgNum */ /* Recompute minMsgNum = minimum of all backends' nextMsgNum */
for (i = 0; i < segP->maxBackends; i++) for (i = 0; i < segP->lastBackend; i++)
{ {
h = segP->procState[i].nextMsgNum; h = segP->procState[i].nextMsgNum;
if (h >= 0) if (h >= 0)
...@@ -392,7 +397,7 @@ SIDelExpiredDataEntries(SISeg *segP) ...@@ -392,7 +397,7 @@ SIDelExpiredDataEntries(SISeg *segP)
{ {
segP->minMsgNum -= MSGNUMWRAPAROUND; segP->minMsgNum -= MSGNUMWRAPAROUND;
segP->maxMsgNum -= MSGNUMWRAPAROUND; segP->maxMsgNum -= MSGNUMWRAPAROUND;
for (i = 0; i < segP->maxBackends; i++) for (i = 0; i < segP->lastBackend; i++)
{ {
if (segP->procState[i].nextMsgNum >= 0) if (segP->procState[i].nextMsgNum >= 0)
segP->procState[i].nextMsgNum -= MSGNUMWRAPAROUND; segP->procState[i].nextMsgNum -= MSGNUMWRAPAROUND;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.46 2000/09/06 14:15:22 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.47 2000/11/12 20:51:52 tgl Exp $
* *
* NOTES * NOTES
* Globals used all over the place should be declared here and not * Globals used all over the place should be declared here and not
...@@ -52,7 +52,6 @@ Relation reldesc; /* current relation descriptor */ ...@@ -52,7 +52,6 @@ Relation reldesc; /* current relation descriptor */
char OutputFileName[MAXPGPATH] = ""; char OutputFileName[MAXPGPATH] = "";
BackendId MyBackendId; BackendId MyBackendId;
BackendTag MyBackendTag;
char *DatabaseName = NULL; char *DatabaseName = NULL;
char *DatabasePath = NULL; char *DatabasePath = NULL;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.69 2000/10/28 16:20:58 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.70 2000/11/12 20:51:52 tgl Exp $
* *
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
...@@ -138,75 +138,37 @@ ReverifyMyDatabase(const char *name) ...@@ -138,75 +138,37 @@ ReverifyMyDatabase(const char *name)
* *
* This routine initializes stuff needed for ipc, locking, etc. * This routine initializes stuff needed for ipc, locking, etc.
* it should be called something more informative. * it should be called something more informative.
*
* Note:
* This does not set MyBackendId. MyBackendTag is set, however.
* -------------------------------- * --------------------------------
*/ */
static void static void
InitCommunication() InitCommunication()
{ {
char *postid; /* value of environment variable */
char *postport; /* value of environment variable */
char *ipc_key; /* value of environemnt variable */
IPCKey key = 0;
/* ---------------- /* ----------------
* try and get the backend tag from POSTID * initialize shared memory and semaphores appropriately.
* ---------------- * ----------------
*/ */
MyBackendId = -1; if (!IsUnderPostmaster) /* postmaster already did this */
postid = getenv("POSTID");
if (!PointerIsValid(postid))
MyBackendTag = -1;
else
{
MyBackendTag = atoi(postid);
Assert(MyBackendTag >= 0);
}
ipc_key = getenv("IPC_KEY");
if (!PointerIsValid(ipc_key))
key = -1;
else
{
key = atoi(ipc_key);
Assert(MyBackendTag >= 0);
}
postport = getenv("POSTPORT");
if (PointerIsValid(postport))
{
if (MyBackendTag == -1)
elog(FATAL, "InitCommunication: missing POSTID");
}
else if (IsUnderPostmaster)
{
elog(FATAL,
"InitCommunication: under postmaster and POSTPORT not set");
}
else
{ {
/* ---------------- /* ----------------
* assume we're running a postgres backend by itself with * we're running a postgres backend by itself with
* no front end or postmaster. * no front end or postmaster.
* ---------------- * ----------------
*/ */
if (MyBackendTag == -1) char *ipc_key; /* value of environment variable */
MyBackendTag = 1; IPCKey key;
key = PrivateIPCKey; ipc_key = getenv("IPC_KEY");
}
if (!PointerIsValid(ipc_key))
/* ---------------- {
* initialize shared memory and semaphores appropriately. /* Normal standalone backend */
* ---------------- key = PrivateIPCKey;
*/ }
if (!IsUnderPostmaster) /* postmaster already did this */ else
{ {
/* Allow standalone's IPC key to be set */
key = atoi(ipc_key);
}
PostgresIpcKey = key; PostgresIpcKey = key;
AttachSharedMemoryAndSemaphores(key); AttachSharedMemoryAndSemaphores(key);
} }
...@@ -343,14 +305,12 @@ InitPostgres(const char *dbname, const char *username) ...@@ -343,14 +305,12 @@ InitPostgres(const char *dbname, const char *username)
* *
* Sets up MyBackendId, a unique backend identifier. * Sets up MyBackendId, a unique backend identifier.
*/ */
MyBackendId = InvalidBackendId;
InitSharedInvalidationState(); InitSharedInvalidationState();
if (MyBackendId > MAXBACKENDS || MyBackendId <= 0) if (MyBackendId > MAXBACKENDS || MyBackendId <= 0)
{ elog(FATAL, "cinit2: bad backend id %d", MyBackendId);
elog(FATAL, "cinit2: bad backend id %d (%d)",
MyBackendTag,
MyBackendId);
}
/* /*
* Initialize the access methods. Does not touch files (?) - thomas * Initialize the access methods. Does not touch files (?) - thomas
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: miscadmin.h,v 1.69 2000/11/04 12:43:24 petere Exp $ * $Id: miscadmin.h,v 1.70 2000/11/12 20:51:52 tgl Exp $
* *
* NOTES * NOTES
* some of the information in this file will be moved to * some of the information in this file will be moved to
...@@ -55,7 +55,6 @@ extern char OutputFileName[]; ...@@ -55,7 +55,6 @@ extern char OutputFileName[];
* done in storage/backendid.h for now. * done in storage/backendid.h for now.
* *
* extern BackendId MyBackendId; * extern BackendId MyBackendId;
* extern BackendTag MyBackendTag;
*/ */
extern bool MyDatabaseIdIsInitialized; extern bool MyDatabaseIdIsInitialized;
extern Oid MyDatabaseId; extern Oid MyDatabaseId;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: backendid.h,v 1.7 2000/01/26 05:58:32 momjian Exp $ * $Id: backendid.h,v 1.8 2000/11/12 20:51:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -18,16 +18,11 @@ ...@@ -18,16 +18,11 @@
* -cim 8/17/90 * -cim 8/17/90
* ---------------- * ----------------
*/ */
typedef int16 BackendId; /* unique currently active backend typedef int BackendId; /* unique currently active backend
* identifier */ * identifier */
#define InvalidBackendId (-1) #define InvalidBackendId (-1)
typedef int32 BackendTag; /* unique backend identifier */
#define InvalidBackendTag (-1)
extern BackendId MyBackendId; /* backend id of this backend */ extern BackendId MyBackendId; /* backend id of this backend */
extern BackendTag MyBackendTag; /* backend tag of this backend */
#endif /* BACKENDID_H */ #endif /* BACKENDID_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: sinval.h,v 1.14 2000/01/26 05:58:33 momjian Exp $ * $Id: sinval.h,v 1.15 2000/11/12 20:51:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -27,7 +27,7 @@ extern void RegisterSharedInvalid(int cacheId, Index hashIndex, ...@@ -27,7 +27,7 @@ extern void RegisterSharedInvalid(int cacheId, Index hashIndex,
extern void InvalidateSharedInvalid(void (*invalFunction) (), extern void InvalidateSharedInvalid(void (*invalFunction) (),
void (*resetFunction) ()); void (*resetFunction) ());
extern bool DatabaseHasActiveBackends(Oid databaseId); extern bool DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself);
extern bool TransactionIdIsInProgress(TransactionId xid); extern bool TransactionIdIsInProgress(TransactionId xid);
extern void GetXmaxRecent(TransactionId *XmaxRecent); extern void GetXmaxRecent(TransactionId *XmaxRecent);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: sinvaladt.h,v 1.22 2000/06/15 03:33:00 momjian Exp $ * $Id: sinvaladt.h,v 1.23 2000/11/12 20:51:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -77,7 +77,6 @@ typedef struct ProcState ...@@ -77,7 +77,6 @@ typedef struct ProcState
/* nextMsgNum is -1 in an inactive ProcState array entry. */ /* nextMsgNum is -1 in an inactive ProcState array entry. */
int nextMsgNum; /* next message number to read, or -1 */ int nextMsgNum; /* next message number to read, or -1 */
bool resetState; /* true, if backend has to reset its state */ bool resetState; /* true, if backend has to reset its state */
int tag; /* backend tag received from postmaster */
SHMEM_OFFSET procStruct; /* location of backend's PROC struct */ SHMEM_OFFSET procStruct; /* location of backend's PROC struct */
} ProcState; } ProcState;
...@@ -90,6 +89,7 @@ typedef struct SISeg ...@@ -90,6 +89,7 @@ typedef struct SISeg
*/ */
int minMsgNum; /* oldest message still needed */ int minMsgNum; /* oldest message still needed */
int maxMsgNum; /* next message number to be assigned */ int maxMsgNum; /* next message number to be assigned */
int lastBackend; /* index of last active procState entry, +1 */
int maxBackends; /* size of procState array */ int maxBackends; /* size of procState array */
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment