aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/postmaster/postmaster.c26
-rw-r--r--src/backend/storage/ipc/sinval.c14
-rw-r--r--src/backend/storage/ipc/sinvaladt.c14
-rw-r--r--src/backend/storage/lmgr/proc.c52
-rw-r--r--src/backend/utils/init/postinit.c68
-rw-r--r--src/include/storage/proc.h3
6 files changed, 85 insertions, 92 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 1a71378a2e3..3cb9e2938e8 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -28,7 +28,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.220 2001/06/14 19:59:24 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.221 2001/06/16 22:58:12 tgl Exp $
*
* NOTES
*
@@ -1280,8 +1280,16 @@ canAcceptConnections(void)
return "The Data Base System is starting up";
if (FatalError)
return "The Data Base System is in recovery mode";
- /* Can't start backend if max backend count is exceeded. */
- if (CountChildren() >= MaxBackends)
+ /*
+ * Don't start too many children.
+ *
+ * We allow more connections than we can have backends here because
+ * some might still be authenticating; they might fail auth, or some
+ * existing backend might exit before the auth cycle is completed.
+ * The exact MaxBackends limit is enforced when a new backend tries
+ * to join the shared-inval backend array.
+ */
+ if (CountChildren() >= 2 * MaxBackends)
return "Sorry, too many clients already";
return NULL;
@@ -1738,12 +1746,6 @@ CleanupProc(int pid,
GetRedoRecPtr();
}
}
- else
- {
- /* Why is this done here, and not by the backend itself? */
- if (!FatalError)
- ProcRemove(pid);
- }
return;
}
@@ -1765,7 +1767,6 @@ CleanupProc(int pid,
bp = (Backend *) DLE_VAL(curr);
if (bp->pid != pid)
{
-
/*
* This backend is still alive. Unless we did so already,
* tell it to commit hara-kiri.
@@ -1786,13 +1787,8 @@ CleanupProc(int pid,
}
else
{
-
/*
* Found entry for freshly-dead backend, so remove it.
- *
- * Don't call ProcRemove() here, since shmem may be corrupted! We
- * are going to reinitialize shmem and semaphores anyway once
- * all the children are dead, so no need for it.
*/
DLRemove(curr);
free(bp);
diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c
index d60e6198f51..9177a81604b 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.32 2001/06/01 20:07:16 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.33 2001/06/16 22:58:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -43,13 +43,15 @@ CreateSharedInvalidationState(int maxBackends)
void
InitBackendSharedInvalidationState(void)
{
+ int flag;
+
SpinAcquire(SInvalLock);
- if (!SIBackendInit(shmInvalBuffer))
- {
- SpinRelease(SInvalLock);
- elog(FATAL, "Backend cache invalidation initialization failed");
- }
+ flag = SIBackendInit(shmInvalBuffer);
SpinRelease(SInvalLock);
+ if (flag < 0) /* unexpected problem */
+ elog(FATAL, "Backend cache invalidation initialization failed");
+ if (flag == 0) /* expected problem: MaxBackends exceeded */
+ elog(FATAL, "Sorry, too many clients already");
}
/*
diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c
index 06ba354d94a..63bc037bc9a 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.38 2001/03/22 03:59:45 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.39 2001/06/16 22:58:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -79,6 +79,11 @@ SIBufferInit(int maxBackends)
* SIBackendInit
* Initialize a new backend to operate on the sinval buffer
*
+ * Returns:
+ * >0 A-OK
+ * 0 Failed to find a free procState slot (ie, MaxBackends exceeded)
+ * <0 Some other failure (not currently used)
+ *
* NB: this routine, and all following ones, must be executed with the
* SInvalLock spinlock held, since there may be multiple backends trying
* to access the buffer.
@@ -109,12 +114,7 @@ SIBackendInit(SISeg *segP)
}
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");
+ /* out of procState slots */
MyBackendId = InvalidBackendId;
return 0;
}
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index e64d3886aa4..d2a8fe10df8 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.102 2001/05/25 15:45:33 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.103 2001/06/16 22:58:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -390,45 +390,16 @@ ProcReleaseLocks(bool isCommit)
!isCommit, GetCurrentTransactionId());
}
-/*
- * ProcRemove -
- * called by the postmaster to clean up the global tables after a
- * backend exits. This also frees up the proc's wait semaphore.
- */
-bool
-ProcRemove(int pid)
-{
- SHMEM_OFFSET location;
- PROC *proc;
-
- location = ShmemPIDDestroy(pid);
- if (location == INVALID_OFFSET)
- return FALSE;
- proc = (PROC *) MAKE_PTR(location);
-
- SpinAcquire(ProcStructLock);
-
- ProcFreeSem(proc->sem.semId, proc->sem.semNum);
-
- /* Add PROC struct to freelist so space can be recycled in future */
- proc->links.next = ProcGlobal->freeProcs;
- ProcGlobal->freeProcs = MAKE_OFFSET(proc);
-
- SpinRelease(ProcStructLock);
-
- return TRUE;
-}
/*
* ProcKill() -- Destroy the per-proc data structure for
* this process. Release any of its held spin locks.
- *
- * This is done inside the backend process before it exits.
- * ProcRemove, above, will be done by the postmaster afterwards.
*/
static void
ProcKill(void)
{
+ SHMEM_OFFSET location;
+
Assert(MyProc);
/* Release any spinlocks I am holding */
@@ -445,9 +416,26 @@ ProcKill(void)
LockReleaseAll(USER_LOCKMETHOD, MyProc, true, InvalidTransactionId);
#endif
+ /* Remove my PROC struct from the shmem hash table */
+ location = ShmemPIDDestroy(MyProcPid);
+ Assert(location != INVALID_OFFSET);
+ Assert(MyProc == (PROC *) MAKE_PTR(location));
+
+ SpinAcquire(ProcStructLock);
+
+ /* Free up my wait semaphore */
+ ProcFreeSem(MyProc->sem.semId, MyProc->sem.semNum);
+
+ /* Add PROC struct to freelist so space can be recycled in future */
+ MyProc->links.next = ProcGlobal->freeProcs;
+ ProcGlobal->freeProcs = MAKE_OFFSET(MyProc);
+
+ SpinRelease(ProcStructLock);
+
MyProc = NULL;
}
+
/*
* ProcQueue package: routines for putting processes to sleep
* and waking them up
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index c3c3ad946ec..dedd9a8e765 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.86 2001/05/30 20:52:32 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.87 2001/06/16 22:58:16 tgl Exp $
*
*
*-------------------------------------------------------------------------
@@ -148,13 +148,11 @@ ReverifyMyDatabase(const char *name)
static void
InitCommunication(void)
{
-
/*
* initialize shared memory and semaphores appropriately.
*/
if (!IsUnderPostmaster) /* postmaster already did this */
{
-
/*
* we're running a postgres backend by itself with no front end or
* postmaster. Create private "shmem" and semaphores. Setting
@@ -168,11 +166,16 @@ InitCommunication(void)
/*
* Early initialization of a backend (either standalone or under postmaster).
* This happens even before InitPostgres.
+ *
+ * If you're wondering why this is separate from InitPostgres at all:
+ * the critical distinction is that this stuff has to happen before we can
+ * run XLOG-related initialization, which is done before InitPostgres --- in
+ * fact, for cases such as checkpoint creation processes, InitPostgres may
+ * never be done at all.
*/
void
BaseInit(void)
{
-
/*
* Attach to shared memory and semaphores, and initialize our
* input/output/debugging file descriptors.
@@ -184,8 +187,6 @@ BaseInit(void)
smgrinit();
InitBufferPoolAccess();
InitLocalBuffer();
-
- EnablePortalManager(); /* memory for portal/transaction stuff */
}
@@ -202,16 +203,18 @@ InitPostgres(const char *dbname, const char *username)
{
bool bootstrap = IsBootstrapProcessingMode();
- SetDatabaseName(dbname);
-
/*
- * initialize the database id used for system caches and lock tables
+ * Set up the global variables holding database name, id, and path.
+ *
+ * We take a shortcut in the bootstrap case, otherwise we have to look up
+ * the db name in pg_database.
*/
+ SetDatabaseName(dbname);
+
if (bootstrap)
{
MyDatabaseId = TemplateDbOid;
SetDatabasePath(GetDatabasePath(MyDatabaseId));
- LockDisable(true);
}
else
{
@@ -260,6 +263,28 @@ InitPostgres(const char *dbname, const char *username)
*/
/*
+ * Set up my per-backend PROC struct in shared memory. (We need to
+ * know MyDatabaseId before we can do this, since it's entered into
+ * the PROC struct.)
+ */
+ InitProcess();
+
+ /*
+ * Initialize my entry in the shared-invalidation manager's array of
+ * per-backend data. (Formerly this came before InitProcess, but now
+ * it must happen after, because it uses MyProc.) Once I have done
+ * this, I am visible to other backends!
+ *
+ * Sets up MyBackendId, a unique backend identifier.
+ */
+ MyBackendId = InvalidBackendId;
+
+ InitBackendSharedInvalidationState();
+
+ if (MyBackendId > MAXBACKENDS || MyBackendId <= 0)
+ elog(FATAL, "InitPostgres: bad backend id %d", MyBackendId);
+
+ /*
* Initialize the transaction system and the relation descriptor
* cache. Note we have to make certain the lock manager is off while
* we do this.
@@ -282,26 +307,6 @@ InitPostgres(const char *dbname, const char *username)
LockDisable(false);
/*
- * Set up my per-backend PROC struct in shared memory.
- */
- InitProcess();
-
- /*
- * Initialize my entry in the shared-invalidation manager's array of
- * per-backend data. (Formerly this came before InitProcess, but now
- * it must happen after, because it uses MyProc.) Once I have done
- * this, I am visible to other backends!
- *
- * Sets up MyBackendId, a unique backend identifier.
- */
- MyBackendId = InvalidBackendId;
-
- InitBackendSharedInvalidationState();
-
- if (MyBackendId > MAXBACKENDS || MyBackendId <= 0)
- elog(FATAL, "cinit2: bad backend id %d", MyBackendId);
-
- /*
* Initialize the access methods. Does not touch files (?) - thomas
* 1997-11-01
*/
@@ -315,6 +320,9 @@ InitPostgres(const char *dbname, const char *username)
*/
InitCatalogCache();
+ /* Initialize portal manager */
+ EnablePortalManager();
+
/*
* Initialize the deferred trigger manager --- must happen before
* first transaction start.
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 8118cf0e5ce..a35c8f4481e 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: proc.h,v 1.43 2001/05/25 15:45:34 momjian Exp $
+ * $Id: proc.h,v 1.44 2001/06/16 22:58:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -129,7 +129,6 @@ typedef struct procglobal
extern void InitProcGlobal(int maxBackends);
extern void InitProcess(void);
extern void ProcReleaseLocks(bool isCommit);
-extern bool ProcRemove(int pid);
extern void ProcQueueInit(PROC_QUEUE *queue);
extern int ProcSleep(LOCKMETHODTABLE *lockMethodTable, LOCKMODE lockmode,