aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-11-12 20:51:52 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-11-12 20:51:52 +0000
commitebb0a2014930034a89ae5f4953b52c9afbf585ae (patch)
tree2c8126548b1737e6312c40aa9aecfe9f549f11cb
parentc48025e799dd51a78c82193bc9ce6c63d7e6681f (diff)
downloadpostgresql-ebb0a2014930034a89ae5f4953b52c9afbf585ae.tar.gz
postgresql-ebb0a2014930034a89ae5f4953b52c9afbf585ae.zip
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.
-rw-r--r--src/backend/commands/dbcommands.c4
-rw-r--r--src/backend/postmaster/postmaster.c184
-rw-r--r--src/backend/storage/ipc/sinval.c24
-rw-r--r--src/backend/storage/ipc/sinvaladt.c65
-rw-r--r--src/backend/utils/init/globals.c3
-rw-r--r--src/backend/utils/init/postinit.c84
-rw-r--r--src/include/miscadmin.h3
-rw-r--r--src/include/storage/backendid.h9
-rw-r--r--src/include/storage/sinval.h4
-rw-r--r--src/include/storage/sinvaladt.h4
10 files changed, 151 insertions, 233 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index e2821d6237e..2442679250f 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -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);
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index e2a1dec6fb8..e50c0ee4d0e 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -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);
diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c
index c610147fc5f..fb2e4804dd3 100644
--- a/src/backend/storage/ipc/sinval.c
+++ b/src/backend/storage/ipc/sinval.c
@@ -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;
diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c
index fcea99dd043..f4b29983433 100644
--- a/src/backend/storage/ipc/sinvaladt.c
+++ b/src/backend/storage/ipc/sinvaladt.c
@@ -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;
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 70bb40f328f..9f23d4272a5 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -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;
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index fbc9cc2ab2c..f786eb1d10d 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -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
+ * initialize shared memory and semaphores appropriately.
* ----------------
*/
- 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
+ if (!IsUnderPostmaster) /* postmaster already did this */
{
/* ----------------
- * assume we're running a postgres backend by itself with
+ * 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 */
- {
+ 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
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 6e6436d1528..7b684291a33 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -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;
diff --git a/src/include/storage/backendid.h b/src/include/storage/backendid.h
index ad7b1f079f5..22c52012f07 100644
--- a/src/include/storage/backendid.h
+++ b/src/include/storage/backendid.h
@@ -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 */
diff --git a/src/include/storage/sinval.h b/src/include/storage/sinval.h
index 32b51b5f43b..4c80f760faa 100644
--- a/src/include/storage/sinval.h
+++ b/src/include/storage/sinval.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);
diff --git a/src/include/storage/sinvaladt.h b/src/include/storage/sinvaladt.h
index 30fe1e06daf..b9704d34e4d 100644
--- a/src/include/storage/sinvaladt.h
+++ b/src/include/storage/sinvaladt.h
@@ -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 */
/*