* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.205 2005/07/04 04:51:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.206 2005/08/08 03:11:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
BaseInit();
- /* needed to get LWLocks */
+ /*
+ * We aren't going to do the full InitPostgres pushups, but there
+ * are a couple of things that need to get lit up even in a dummy
+ * process.
+ */
if (IsUnderPostmaster)
{
+ /* set up proc.c to get use of LWLocks */
switch (xlogop)
{
case BS_XLOG_BGWRITER:
InitDummyProcess(DUMMY_PROC_DEFAULT);
break;
}
+
+ /* finish setting up bufmgr.c */
+ InitBufferPoolBackend();
}
/*
*
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.102 2005/07/29 19:30:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.103 2005/08/08 03:11:40 tgl Exp $
* ----------
*/
#include "postgres.h"
* pgstat_bestart() -
*
* Tell the collector that this new backend is soon ready to process
- * queries. Called from tcop/postgres.c before entering the mainloop.
+ * queries. Called from InitPostgres.
* ----------
*/
void
* Set up a process-exit hook to ensure we flush the last batch of
* statistics to the collector.
*/
- on_proc_exit(pgstat_beshutdown_hook, 0);
+ on_shmem_exit(pgstat_beshutdown_hook, 0);
}
/* ---------
/*
* Flush any remaining statistics counts out to the collector at process
* exit. Without this, operations triggered during backend exit (such as
- * temp table deletions) won't be counted. This is an on_proc_exit hook,
- * not on_shmem_exit, so that everything interesting must have happened
- * already.
+ * temp table deletions) won't be counted.
*/
static void
pgstat_beshutdown_hook(int code, Datum arg)
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.73 2005/05/19 21:35:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.74 2005/08/08 03:11:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* NB: this is called before InitProcess(), so we do not have a PGPROC and
* cannot do LWLockAcquire; hence we can't actually access stuff in
* shared memory yet. We are only initializing local data here.
+ * (See also InitBufferPoolBackend, over in bufmgr.c.)
*/
void
InitBufferPoolAccess(void)
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.190 2005/08/02 20:52:08 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.191 2005/08/08 03:11:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "storage/buf_internals.h"
#include "storage/bufmgr.h"
#include "storage/bufpage.h"
+#include "storage/ipc.h"
#include "storage/proc.h"
#include "storage/smgr.h"
#include "utils/relcache.h"
static BufferDesc *BufferAlloc(Relation reln, BlockNumber blockNum,
bool *foundPtr);
static void FlushBuffer(BufferDesc *buf, SMgrRelation reln);
+static void AtProcExit_Buffers(int code, Datum arg);
static void write_buffer(Buffer buffer, bool unpin);
}
/*
- * Ensure we have released all shared-buffer locks and pins during backend exit
+ * InitBufferPoolBackend --- second-stage initialization of a new backend
+ *
+ * This is called after we have acquired a PGPROC and so can safely get
+ * LWLocks. We don't currently need to do anything at this stage ...
+ * except register a shmem-exit callback. AtProcExit_Buffers needs LWLock
+ * access, and thereby has to be called at the corresponding phase of
+ * backend shutdown.
*/
void
-AtProcExit_Buffers(void)
+InitBufferPoolBackend(void)
+{
+ on_shmem_exit(AtProcExit_Buffers, 0);
+}
+
+/*
+ * Ensure we have released all shared-buffer locks and pins during backend exit
+ */
+static void
+AtProcExit_Buffers(int code, Datum arg)
{
int i;
Assert(PrivateRefCount[i] == 0);
}
}
+
+ /* localbuf.c needs a chance too */
+ AtProcExit_LocalBuffers();
}
/*
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.119 2005/08/07 18:47:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.120 2005/08/08 03:11:49 tgl Exp $
*
* NOTES:
*
return 0;
}
+/*
+ * InitFileAccess --- initialize this module during backend startup
+ *
+ * This is called during either normal or standalone backend start.
+ * It is *not* called in the postmaster.
+ */
+void
+InitFileAccess(void)
+{
+ Assert(SizeVfdCache == 0); /* call me only once */
+
+ /* initialize cache header entry */
+ VfdCache = (Vfd *) malloc(sizeof(Vfd));
+ if (VfdCache == NULL)
+ ereport(FATAL,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+
+ MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
+ VfdCache->fd = VFD_CLOSED;
+
+ SizeVfdCache = 1;
+
+ /* register proc-exit hook to ensure temp files are dropped at exit */
+ on_proc_exit(AtProcExit_Files, 0);
+}
+
/*
* count_usable_fds --- count how many FDs the system will let us open,
* and estimate how many are already open.
DO_DB(elog(LOG, "AllocateVfd. Size %d", SizeVfdCache));
- if (SizeVfdCache == 0)
- {
- /* initialize header entry first time through */
- VfdCache = (Vfd *) malloc(sizeof(Vfd));
- if (VfdCache == NULL)
- ereport(FATAL,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
- MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
- VfdCache->fd = VFD_CLOSED;
-
- SizeVfdCache = 1;
-
- /*
- * register proc-exit call to ensure temp files are dropped at
- * exit
- */
- on_proc_exit(AtProcExit_Files, 0);
- }
+ Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
if (VfdCache[0].nextFree == 0)
{
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.161 2005/07/31 17:19:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.162 2005/08/08 03:11:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &foundProcGlobal);
/*
- * Create or attach to the PGPROC structures for dummy (checkpoint)
+ * Create or attach to the PGPROC structures for dummy (bgwriter)
* processes, too. These do not get linked into the freeProcs list.
*/
DummyProcs = (PGPROC *)
/*
* InitDummyProcess -- create a dummy per-process data structure
*
- * This is called by checkpoint processes so that they will have a MyProc
- * value that's real enough to let them wait for LWLocks. The PGPROC and
- * sema that are assigned are the extra ones created during InitProcGlobal.
+ * This is called by bgwriter and similar processes so that they will have a
+ * MyProc value that's real enough to let them wait for LWLocks. The PGPROC
+ * and sema that are assigned are the extra ones created during
+ * InitProcGlobal.
*
* Dummy processes are presently not expected to wait for real (lockmgr)
* locks, nor to participate in sinval messaging.
Assert(MyProc != NULL);
- /* Release any LW locks I am holding */
- LWLockReleaseAll();
-
/*
- * Make real sure we release any buffer locks and pins we might be
- * holding, too. It is pretty ugly to do this here and not in a
- * shutdown callback registered by the bufmgr ... but we must do this
- * *after* LWLockReleaseAll and *before* zapping MyProc.
+ * Release any LW locks I am holding. There really shouldn't be any,
+ * but it's cheap to check again before we cut the knees off the LWLock
+ * facility by releasing our PGPROC ...
*/
- AtProcExit_Buffers();
-
- /* Get off any wait queue I might be on */
- LockWaitCancel();
-
- /* Remove from the standard lock table */
- LockReleaseAll(DEFAULT_LOCKMETHOD, true);
-
-#ifdef USER_LOCKS
- /* Remove from the user lock table */
- LockReleaseAll(USER_LOCKMETHOD, true);
-#endif
+ LWLockReleaseAll();
/* Remove our PGPROC from the PGPROC array in shared memory */
ProcArrayRemove(MyProc);
}
/*
- * DummyProcKill() -- Cut-down version of ProcKill for dummy (checkpoint)
+ * DummyProcKill() -- Cut-down version of ProcKill for dummy (bgwriter)
* processes. The PGPROC and sema are not released, only marked
* as not-in-use.
*/
Assert(MyProc == dummyproc);
- /* Release any LW locks I am holding */
+ /* Release any LW locks I am holding (see notes above) */
LWLockReleaseAll();
- /* Release buffer locks and pins, too */
- AtProcExit_Buffers();
-
- /* I can't be on regular lock queues, so needn't check */
-
/* Mark dummy proc no longer in use */
MyProc->pid = 0;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.91 2005/06/20 18:37:01 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.92 2005/08/08 03:12:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * smgrinit(), smgrshutdown() -- Initialize or shut down all storage
+ * smgrinit(), smgrshutdown() -- Initialize or shut down storage
* managers.
*
- * Note: in the normal multiprocess scenario with a postmaster, these are
- * called at postmaster start and stop, not per-backend.
+ * Note: smgrinit is called during backend startup (normal or standalone
+ * case), *not* during postmaster start. Therefore, any resources created
+ * here or destroyed in smgrshutdown are backend-local.
*/
void
smgrinit(void)
on_proc_exit(smgrshutdown, 0);
}
+/*
+ * on_proc_exit hook for smgr cleanup during backend shutdown
+ */
static void
smgrshutdown(int code, Datum arg)
{
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.455 2005/07/21 03:56:11 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.456 2005/08/08 03:12:12 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
- /* ----------
- * Tell the statistics collector that we're alive and
- * to which database we belong.
- * ----------
- */
- pgstat_bestart();
-
/*
* Remember stand-alone backend startup time
*/
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.155 2005/07/31 17:19:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.156 2005/08/08 03:12:14 tgl Exp $
*
*
*-------------------------------------------------------------------------
#include "utils/portal.h"
#include "utils/relcache.h"
#include "utils/syscache.h"
+#include "pgstat.h"
static bool FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace);
InitCommunication();
DebugFileOpen();
- /* Do local initialization of storage and buffer managers */
+ /* Do local initialization of file, storage and buffer managers */
+ InitFileAccess();
smgrinit();
InitBufferPoolAccess();
}
if (MyBackendId > MaxBackends || MyBackendId <= 0)
elog(FATAL, "bad backend id: %d", MyBackendId);
+ /*
+ * bufmgr needs another initialization call too
+ */
+ InitBufferPoolBackend();
+
/*
* Initialize local process's access to XLOG. In bootstrap case we
* may skip this since StartupXLOG() was run instead.
/* initialize client encoding */
InitializeClientEncoding();
+ /*
+ * Initialize statistics collection for this backend. We do this
+ * here because the shutdown hook it sets up needs to be invoked
+ * at the corresponding phase of backend shutdown: after
+ * ShutdownPostgres and before we drop access to shared memory.
+ */
+ if (IsUnderPostmaster)
+ pgstat_bestart();
+
/*
* Set up process-exit callback to do pre-shutdown cleanup. This
* should be last because we want shmem_exit to call this routine
return am_superuser;
}
+
/*
* Backend-shutdown callback. Do cleanup that we want to be sure happens
* before all the supporting modules begin to nail their doors shut via
static void
ShutdownPostgres(int code, Datum arg)
{
- /*
- * These operations are really just a minimal subset of
- * AbortTransaction(). We don't want to do any inessential cleanup,
- * since that just raises the odds of failure --- but there's some
- * stuff we need to do.
- *
- * Release any LW locks, buffer content locks, and buffer pins we might be
- * holding. This is a kluge to improve the odds that we won't get into a
- * self-made stuck-lock scenario while trying to shut down. We *must*
- * release buffer pins to make it safe to do file deletion, since we
- * might have some pins on pages of the target files.
- */
- LWLockReleaseAll();
- AtProcExit_Buffers();
- AtProcExit_LocalBuffers();
+ /* Make sure we've killed any active transaction */
+ AbortOutOfAnyTransaction();
/*
- * In case a transaction is open, delete any files it created. This
- * has to happen before bufmgr shutdown, so having smgr register a
- * callback for it wouldn't work.
+ * User locks are not released by transaction end, so be sure to
+ * release them explicitly.
*/
- smgrDoPendingDeletes(false); /* delete as though aborting xact */
+#ifdef USER_LOCKS
+ LockReleaseAll(USER_LOCKMETHOD, true);
+#endif
}
-
/*
* Returns true if at least one role is defined in this database cluster.
*/
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.93 2005/03/20 22:00:54 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.94 2005/08/08 03:12:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern void InitBufferPool(void);
extern void InitBufferPoolAccess(void);
+extern void InitBufferPoolBackend(void);
extern char *ShowBufferUsage(void);
extern void ResetBufferUsage(void);
extern void AtEOXact_Buffers(bool isCommit);
-extern void AtProcExit_Buffers(void);
extern void PrintBufferLeakWarning(Buffer buffer);
extern void FlushBufferPool(void);
extern BlockNumber BufferGetBlockNumber(Buffer buffer);
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/storage/fd.h,v 1.52 2005/06/19 21:34:03 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/storage/fd.h,v 1.53 2005/08/08 03:12:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern int BasicOpenFile(FileName fileName, int fileFlags, int fileMode);
/* Miscellaneous support routines */
+extern void InitFileAccess(void);
extern void set_max_safe_fds(void);
extern void closeAllVfds(void);
extern void AtEOXact_Files(void);