aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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 */
/*