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

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

View File

@ -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
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[])
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[])
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[])
} }
#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[])
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
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)
*/ */
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)
/* 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)
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)
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
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)
ExitPostmaster(1); ExitPostmaster(1);
} }
NextBackendTag -= 1;
if (xlop != BS_XLOG_CHECKPOINT) if (xlop != BS_XLOG_CHECKPOINT)
return(pid); return(pid);

View File

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

View File

@ -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)
/* 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)
{ {
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)
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)
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)
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,
{ {
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)
/* 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)
{ {
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;

View File

@ -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 */
char OutputFileName[MAXPGPATH] = ""; char OutputFileName[MAXPGPATH] = "";
BackendId MyBackendId; BackendId MyBackendId;
BackendTag MyBackendTag;
char *DatabaseName = NULL; char *DatabaseName = NULL;
char *DatabasePath = NULL; char *DatabasePath = NULL;

View File

@ -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)
* *
* 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
* ----------------
*/
MyBackendId = -1;
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
* no front end or postmaster.
* ----------------
*/
if (MyBackendTag == -1)
MyBackendTag = 1;
key = PrivateIPCKey;
}
/* ---------------- /* ----------------
* initialize shared memory and semaphores appropriately. * initialize shared memory and semaphores appropriately.
* ---------------- * ----------------
*/ */
if (!IsUnderPostmaster) /* postmaster already did this */ if (!IsUnderPostmaster) /* postmaster already did this */
{ {
/* ----------------
* we're running a postgres backend by itself with
* no front end or postmaster.
* ----------------
*/
char *ipc_key; /* value of environment variable */
IPCKey key;
ipc_key = getenv("IPC_KEY");
if (!PointerIsValid(ipc_key))
{
/* Normal standalone backend */
key = PrivateIPCKey;
}
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)
* *
* 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

View File

@ -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[];
* 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;

View File

@ -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 @@
* -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 */

View File

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

View File

@ -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
/* 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
*/ */
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 */
/* /*