Keep track of the last active slot in the shared ProcState array, so
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 12 Nov 2000 20:51:52 +0000 (20:51 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 12 Nov 2000 20:51:52 +0000 (20:51 +0000)
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.

src/backend/commands/dbcommands.c
src/backend/postmaster/postmaster.c
src/backend/storage/ipc/sinval.c
src/backend/storage/ipc/sinvaladt.c
src/backend/utils/init/globals.c
src/backend/utils/init/postinit.c
src/include/miscadmin.h
src/include/storage/backendid.h
src/include/storage/sinval.h
src/include/storage/sinvaladt.h

index e2821d6237e4881958c9ad7059c02190efa2d372..2442679250f5efef73de1eadd44a6d74664bb2cd 100644 (file)
@@ -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);
index e2a1dec6fb8fab62b69064270592ce964f103c30..e50c0ee4d0eb1703c47d4c400188f1cdc1aac895 100644 (file)
@@ -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);
 
index c610147fc5f650effe221149163bb5748c584c01..fb2e4804dd3c23b8f4e865b791947cb11bcb4aab 100644 (file)
@@ -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;
 
index fcea99dd043f2a828aa6e7a316c24137c638415a..f4b2998343314e6eeb30188171d28074e3077b03 100644 (file)
@@ -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;
index 70bb40f328f687dde14d7c75cbbca1e9484b19cd..9f23d4272a55c709b9ebff581fb498b65bcde430 100644 (file)
@@ -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;
index fbc9cc2ab2cc21cb7ac8c63cd9d52ec9f1ca7d69..f786eb1d10dc2440f100032a63f3677858fad382 100644 (file)
@@ -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
index 6e6436d1528dc1b95bb95baae5526993cdf21d70..7b684291a33606008a7bca5edd9b6d7b0a4cf717 100644 (file)
@@ -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;
index ad7b1f079f571c47c19328b0788b1e1c618ea25d..22c52012f07769366af66e1fb7966702bf21531d 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
  *     -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 */
index 32b51b5f43b144826036d95f4c3249e48857caa4..4c80f760faa508899d6865a99f7fccdc0e92c257 100644 (file)
@@ -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);
 
index 30fe1e06daf0b8111dfb04d1ca70d010e66f9f60..b9704d34e4d9753056cbcbf360d43a7de124cb46 100644 (file)
@@ -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 */
 
    /*