mirror of https://github.com/postgres/postgres
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
|
@ -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…
Reference in New Issue