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:
parent
c48025e799
commit
ebb0a20149
src
backend
commands
postmaster
storage/ipc
utils/init
include
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
if (DatabaseHasActiveBackends(db_id))
|
||||
if (DatabaseHasActiveBackends(db_id, false))
|
||||
{
|
||||
heap_close(pgdbrel, AccessExclusiveLock);
|
||||
elog(ERROR, "DROP DATABASE: database \"%s\" is being accessed by other users", dbname);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
@ -194,7 +197,7 @@ void
|
||||
*/
|
||||
|
||||
bool
|
||||
DatabaseHasActiveBackends(Oid databaseId)
|
||||
DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself)
|
||||
{
|
||||
bool result = false;
|
||||
SISeg *segP = shmInvalBuffer;
|
||||
@ -203,7 +206,7 @@ DatabaseHasActiveBackends(Oid databaseId)
|
||||
|
||||
SpinAcquire(SInvalLock);
|
||||
|
||||
for (index = 0; index < segP->maxBackends; index++)
|
||||
for (index = 0; index < segP->lastBackend; index++)
|
||||
{
|
||||
SHMEM_OFFSET pOffset = stateP[index].procStruct;
|
||||
|
||||
@ -213,6 +216,9 @@ DatabaseHasActiveBackends(Oid databaseId)
|
||||
|
||||
if (proc->databaseId == databaseId)
|
||||
{
|
||||
if (ignoreMyself && proc == MyProc)
|
||||
continue;
|
||||
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
@ -237,7 +243,7 @@ TransactionIdIsInProgress(TransactionId xid)
|
||||
|
||||
SpinAcquire(SInvalLock);
|
||||
|
||||
for (index = 0; index < segP->maxBackends; index++)
|
||||
for (index = 0; index < segP->lastBackend; index++)
|
||||
{
|
||||
SHMEM_OFFSET pOffset = stateP[index].procStruct;
|
||||
|
||||
@ -275,7 +281,7 @@ GetXmaxRecent(TransactionId *XmaxRecent)
|
||||
|
||||
SpinAcquire(SInvalLock);
|
||||
|
||||
for (index = 0; index < segP->maxBackends; index++)
|
||||
for (index = 0; index < segP->lastBackend; index++)
|
||||
{
|
||||
SHMEM_OFFSET pOffset = stateP[index].procStruct;
|
||||
|
||||
@ -309,11 +315,11 @@ GetSnapshotData(bool serializable)
|
||||
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:
|
||||
*/
|
||||
snapshot->xip = (TransactionId *)
|
||||
malloc(segP->maxBackends * sizeof(TransactionId));
|
||||
malloc(segP->lastBackend * sizeof(TransactionId));
|
||||
snapshot->xmin = GetCurrentTransactionId();
|
||||
|
||||
SpinAcquire(SInvalLock);
|
||||
@ -326,7 +332,7 @@ GetSnapshotData(bool serializable)
|
||||
*/
|
||||
ReadNewTransactionId(&(snapshot->xmax));
|
||||
|
||||
for (index = 0; index < segP->maxBackends; index++)
|
||||
for (index = 0; index < segP->lastBackend; index++)
|
||||
{
|
||||
SHMEM_OFFSET pOffset = stateP[index].procStruct;
|
||||
|
||||
@ -386,7 +392,7 @@ GetUndoRecPtr(void)
|
||||
|
||||
SpinAcquire(SInvalLock);
|
||||
|
||||
for (index = 0; index < segP->maxBackends; index++)
|
||||
for (index = 0; index < segP->lastBackend; index++)
|
||||
{
|
||||
SHMEM_OFFSET pOffset = stateP[index].procStruct;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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 */
|
||||
segP->minMsgNum = 0;
|
||||
segP->maxMsgNum = 0;
|
||||
segP->lastBackend = 0;
|
||||
segP->maxBackends = maxBackends;
|
||||
|
||||
/* 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].resetState = false;
|
||||
segP->procState[i].tag = InvalidBackendTag;
|
||||
segP->procState[i].procStruct = INVALID_OFFSET;
|
||||
}
|
||||
}
|
||||
@ -145,47 +145,45 @@ SIBackendInit(SISeg *segP)
|
||||
int index;
|
||||
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 */
|
||||
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];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* elog() with spinlock held is probably not too cool, but this
|
||||
* condition should never happen anyway.
|
||||
*/
|
||||
if (stateP == NULL)
|
||||
{
|
||||
elog(NOTICE, "SIBackendInit: no free procState slot available");
|
||||
MyBackendId = InvalidBackendTag;
|
||||
return 0;
|
||||
if (segP->lastBackend < segP->maxBackends)
|
||||
{
|
||||
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;
|
||||
|
||||
#ifdef INVALIDDEBUG
|
||||
elog(DEBUG, "SIBackendInit: backend tag %d; backend id %d.",
|
||||
MyBackendTag, MyBackendId);
|
||||
elog(DEBUG, "SIBackendInit: backend id %d", MyBackendId);
|
||||
#endif /* INVALIDDEBUG */
|
||||
|
||||
/* mark myself active, with all extant messages already read */
|
||||
stateP->nextMsgNum = segP->maxMsgNum;
|
||||
stateP->resetState = false;
|
||||
stateP->tag = MyBackendTag;
|
||||
stateP->procStruct = MAKE_OFFSET(MyProc);
|
||||
|
||||
/* register exit routine to mark my entry inactive at exit */
|
||||
@ -206,17 +204,26 @@ SIBackendInit(SISeg *segP)
|
||||
static void
|
||||
CleanupInvalidationState(int status, Datum arg)
|
||||
{
|
||||
SISeg *segP = (void*) DatumGetPointer(arg);
|
||||
SISeg *segP = (SISeg *) DatumGetPointer(arg);
|
||||
int i;
|
||||
|
||||
Assert(PointerIsValid(segP));
|
||||
|
||||
SpinAcquire(SInvalLock);
|
||||
|
||||
/* Mark myself inactive */
|
||||
segP->procState[MyBackendId - 1].nextMsgNum = -1;
|
||||
segP->procState[MyBackendId - 1].resetState = false;
|
||||
segP->procState[MyBackendId - 1].tag = InvalidBackendTag;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -299,7 +306,7 @@ SISetProcStateInvalid(SISeg *segP)
|
||||
segP->minMsgNum = 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? */
|
||||
{
|
||||
@ -325,8 +332,6 @@ SIGetDataEntry(SISeg *segP, int backendId,
|
||||
{
|
||||
ProcState *stateP = &segP->procState[backendId - 1];
|
||||
|
||||
Assert(stateP->tag == MyBackendTag);
|
||||
|
||||
if (stateP->resetState)
|
||||
{
|
||||
|
||||
@ -373,7 +378,7 @@ SIDelExpiredDataEntries(SISeg *segP)
|
||||
|
||||
/* 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;
|
||||
if (h >= 0)
|
||||
@ -392,7 +397,7 @@ SIDelExpiredDataEntries(SISeg *segP)
|
||||
{
|
||||
segP->minMsgNum -= MSGNUMWRAPAROUND;
|
||||
segP->maxMsgNum -= MSGNUMWRAPAROUND;
|
||||
for (i = 0; i < segP->maxBackends; i++)
|
||||
for (i = 0; i < segP->lastBackend; i++)
|
||||
{
|
||||
if (segP->procState[i].nextMsgNum >= 0)
|
||||
segP->procState[i].nextMsgNum -= MSGNUMWRAPAROUND;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* Globals used all over the place should be declared here and not
|
||||
@ -52,7 +52,6 @@ Relation reldesc; /* current relation descriptor */
|
||||
char OutputFileName[MAXPGPATH] = "";
|
||||
|
||||
BackendId MyBackendId;
|
||||
BackendTag MyBackendTag;
|
||||
|
||||
char *DatabaseName = NULL;
|
||||
char *DatabasePath = NULL;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
* it should be called something more informative.
|
||||
*
|
||||
* Note:
|
||||
* This does not set MyBackendId. MyBackendTag is set, however.
|
||||
* --------------------------------
|
||||
*/
|
||||
static void
|
||||
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.
|
||||
* ----------------
|
||||
*/
|
||||
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;
|
||||
AttachSharedMemoryAndSemaphores(key);
|
||||
}
|
||||
@ -343,14 +305,12 @@ InitPostgres(const char *dbname, const char *username)
|
||||
*
|
||||
* Sets up MyBackendId, a unique backend identifier.
|
||||
*/
|
||||
MyBackendId = InvalidBackendId;
|
||||
|
||||
InitSharedInvalidationState();
|
||||
|
||||
if (MyBackendId > MAXBACKENDS || MyBackendId <= 0)
|
||||
{
|
||||
elog(FATAL, "cinit2: bad backend id %d (%d)",
|
||||
MyBackendTag,
|
||||
MyBackendId);
|
||||
}
|
||||
elog(FATAL, "cinit2: bad backend id %d", MyBackendId);
|
||||
|
||||
/*
|
||||
* Initialize the access methods. Does not touch files (?) - thomas
|
||||
|
@ -12,7 +12,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* extern BackendId MyBackendId;
|
||||
* extern BackendTag MyBackendTag;
|
||||
*/
|
||||
extern bool MyDatabaseIdIsInitialized;
|
||||
extern Oid MyDatabaseId;
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* 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
|
||||
* ----------------
|
||||
*/
|
||||
typedef int16 BackendId; /* unique currently active backend
|
||||
typedef int BackendId; /* unique currently active backend
|
||||
* identifier */
|
||||
|
||||
#define InvalidBackendId (-1)
|
||||
|
||||
typedef int32 BackendTag; /* unique backend identifier */
|
||||
|
||||
#define InvalidBackendTag (-1)
|
||||
|
||||
extern BackendId MyBackendId; /* backend id of this backend */
|
||||
extern BackendTag MyBackendTag; /* backend tag of this backend */
|
||||
|
||||
#endif /* BACKENDID_H */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* 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) (),
|
||||
void (*resetFunction) ());
|
||||
|
||||
extern bool DatabaseHasActiveBackends(Oid databaseId);
|
||||
extern bool DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself);
|
||||
extern bool TransactionIdIsInProgress(TransactionId xid);
|
||||
extern void GetXmaxRecent(TransactionId *XmaxRecent);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* 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. */
|
||||
int nextMsgNum; /* next message number to read, or -1 */
|
||||
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 */
|
||||
} ProcState;
|
||||
|
||||
@ -90,6 +89,7 @@ typedef struct SISeg
|
||||
*/
|
||||
int minMsgNum; /* oldest message still needed */
|
||||
int maxMsgNum; /* next message number to be assigned */
|
||||
int lastBackend; /* index of last active procState entry, +1 */
|
||||
int maxBackends; /* size of procState array */
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user