diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index e2821d6237e4881958c9ad7059c02190efa2d372..2442679250f5efef73de1eadd44a6d74664bb2cd 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 e2a1dec6fb8fab62b69064270592ce964f103c30..e50c0ee4d0eb1703c47d4c400188f1cdc1aac895 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 c610147fc5f650effe221149163bb5748c584c01..fb2e4804dd3c23b8f4e865b791947cb11bcb4aab 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 fcea99dd043f2a828aa6e7a316c24137c638415a..f4b2998343314e6eeb30188171d28074e3077b03 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 70bb40f328f687dde14d7c75cbbca1e9484b19cd..9f23d4272a55c709b9ebff581fb498b65bcde430 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 fbc9cc2ab2cc21cb7ac8c63cd9d52ec9f1ca7d69..f786eb1d10dc2440f100032a63f3677858fad382 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 6e6436d1528dc1b95bb95baae5526993cdf21d70..7b684291a33606008a7bca5edd9b6d7b0a4cf717 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 ad7b1f079f571c47c19328b0788b1e1c618ea25d..22c52012f07769366af66e1fb7966702bf21531d 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 32b51b5f43b144826036d95f4c3249e48857caa4..4c80f760faa508899d6865a99f7fccdc0e92c257 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 30fe1e06daf0b8111dfb04d1ca70d010e66f9f60..b9704d34e4d9753056cbcbf360d43a7de124cb46 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 */
 
 	/*