aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/transam/xact.c30
-rw-r--r--src/backend/access/transam/xlog.c12
-rw-r--r--src/backend/commands/trigger.c6
-rw-r--r--src/backend/libpq/pqcomm.c8
-rw-r--r--src/backend/storage/buffer/buf_init.c56
-rw-r--r--src/backend/storage/lmgr/proc.c13
-rw-r--r--src/backend/tcop/postgres.c100
-rw-r--r--src/backend/utils/error/elog.c26
-rw-r--r--src/backend/utils/init/postinit.c109
-rw-r--r--src/include/access/xlog.h4
-rw-r--r--src/include/commands/trigger.h4
-rw-r--r--src/include/libpq/libpq.h3
-rw-r--r--src/include/storage/bufmgr.h3
-rw-r--r--src/include/utils/elog.h20
14 files changed, 255 insertions, 139 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 6cd089fd959..c8c9e680f5f 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.88 2000/12/07 10:03:46 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.89 2000/12/18 00:44:45 tgl Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
@@ -1095,6 +1095,15 @@ AbortTransaction(void)
MyProc->xmin = InvalidTransactionId;
}
+ /*
+ * Release any spinlocks or buffer context locks we might be holding
+ * as quickly as possible. (Real locks, however, must be held till
+ * we finish aborting.) Releasing spinlocks is critical since we
+ * might try to grab them again while cleaning up!
+ */
+ ProcReleaseSpins(NULL);
+ UnlockBuffers();
+
/* ----------------
* check the current transaction state
* ----------------
@@ -1105,18 +1114,6 @@ AbortTransaction(void)
if (s->state != TRANS_INPROGRESS)
elog(NOTICE, "AbortTransaction and not in in-progress state");
- /*
- * Reset user id which might have been changed transiently
- */
- SetUserId(GetSessionUserId());
-
- /* ----------------
- * Tell the trigger manager that this transaction is about to be
- * aborted.
- * ----------------
- */
- DeferredTriggerAbortXact();
-
/* ----------------
* set the current transaction state information
* appropriately during the abort processing
@@ -1124,12 +1121,17 @@ AbortTransaction(void)
*/
s->state = TRANS_ABORT;
+ /*
+ * Reset user id which might have been changed transiently
+ */
+ SetUserId(GetSessionUserId());
+
/* ----------------
* do abort processing
* ----------------
*/
+ DeferredTriggerAbortXact();
lo_commit(false); /* 'false' means it's abort */
- UnlockBuffers();
AtAbort_Notify();
CloseSequences();
AtEOXact_portals();
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 3b2c5461dcd..ba85f4b60d0 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.42 2000/12/11 19:27:42 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.43 2000/12/18 00:44:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -40,7 +40,7 @@
int XLOGbuffers = 8;
XLogRecPtr MyLastRecPtr = {0, 0};
-uint32 StopIfError = 0;
+uint32 CritSectionCount = 0;
bool InRecovery = false;
StartUpID ThisStartUpID = 0;
@@ -1531,7 +1531,7 @@ StartupXLOG()
char buffer[MAXLOGRECSZ + SizeOfXLogRecord];
elog(LOG, "starting up");
- StopIfError++;
+ CritSectionCount++;
XLogCtl->xlblocks = (XLogRecPtr *) (((char *) XLogCtl) + sizeof(XLogCtlData));
XLogCtl->pages = ((char *) XLogCtl->xlblocks + sizeof(XLogRecPtr) * XLOGbuffers);
@@ -1748,7 +1748,7 @@ StartupXLOG()
XLogCtl->ThisStartUpID = ThisStartUpID;
elog(LOG, "database system is in production state");
- StopIfError--;
+ CritSectionCount--;
return;
}
@@ -1771,10 +1771,10 @@ ShutdownXLOG()
{
elog(LOG, "shutting down");
- StopIfError++;
+ CritSectionCount++;
CreateDummyCaches();
CreateCheckPoint(true);
- StopIfError--;
+ CritSectionCount--;
elog(LOG, "database system is shut down");
}
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index cc31a0eb48b..d5946ebd3eb 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.81 2000/11/20 20:36:47 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.82 2000/12/18 00:44:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1432,7 +1432,7 @@ deferredTriggerInvokeEvents(bool immediate_only)
* transactions.
* ----------
*/
-int
+void
DeferredTriggerInit(void)
{
deftrig_gcxt = AllocSetContextCreate(TopMemoryContext,
@@ -1440,8 +1440,6 @@ DeferredTriggerInit(void)
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
-
- return 0;
}
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 35d6802a5a5..0d2548c96af 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -29,7 +29,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pqcomm.c,v 1.114 2000/11/29 20:59:51 tgl Exp $
+ * $Id: pqcomm.c,v 1.115 2000/12/18 00:44:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -85,6 +85,9 @@
#endif
+static void pq_close(void);
+
+
/*
* Configuration options
*/
@@ -122,6 +125,7 @@ pq_init(void)
{
PqSendPointer = PqRecvPointer = PqRecvLength = 0;
DoingCopyOut = false;
+ on_proc_exit(pq_close, 0);
}
@@ -132,7 +136,7 @@ pq_init(void)
* don't crash during exit...
* --------------------------------
*/
-void
+static void
pq_close(void)
{
if (MyProcPort != NULL)
diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c
index 19b71933d76..54b9d02e160 100644
--- a/src/backend/storage/buffer/buf_init.c
+++ b/src/backend/storage/buffer/buf_init.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.39 2000/11/30 01:39:07 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.40 2000/12/18 00:44:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -36,6 +36,9 @@
#include "utils/hsearch.h"
#include "utils/memutils.h"
+
+static void ShutdownBufferPoolAccess(void);
+
/*
* if BMTRACE is defined, we trace the last 200 buffer allocations and
* deallocations in a circular buffer in shared memory.
@@ -73,7 +76,7 @@ bool *BufferDirtiedByMe; /* T if buf has been dirtied in cur xact */
* Two important notes. First, the buffer has to be
* available for lookup BEFORE an IO begins. Otherwise
* a second process trying to read the buffer will
- * allocate its own copy and the buffeer pool will
+ * allocate its own copy and the buffer pool will
* become inconsistent.
*
* Buffer Replacement:
@@ -126,10 +129,10 @@ long int LocalBufferFlushCount;
/*
- * Initialize module: called once during shared-memory initialization
+ * Initialize shared buffer pool
*
- * should calculate size of pool dynamically based on the
- * amount of available memory.
+ * This is called once during shared-memory initialization (either in the
+ * postmaster, or in a standalone backend).
*/
void
InitBufferPool(void)
@@ -144,6 +147,10 @@ InitBufferPool(void)
Lookup_List_Descriptor = Data_Descriptors + 1;
Num_Descriptors = Data_Descriptors + 1;
+ /*
+ * It's probably not really necessary to grab the lock --- if there's
+ * anyone else attached to the shmem at this point, we've got problems.
+ */
SpinAcquire(BufMgrLock);
#ifdef BMTRACE
@@ -203,12 +210,28 @@ InitBufferPool(void)
BufferDescriptors[Data_Descriptors - 1].freeNext = 0;
}
- /* Init the rest of the module */
+ /* Init other shared buffer-management stuff */
InitBufTable();
InitFreeList(!foundDescs);
SpinRelease(BufMgrLock);
+}
+
+/*
+ * Initialize access to shared buffer pool
+ *
+ * This is called during backend startup (whether standalone or under the
+ * postmaster). It sets up for this backend's access to the already-existing
+ * buffer pool.
+ */
+void
+InitBufferPoolAccess(void)
+{
+ int i;
+ /*
+ * Allocate and zero local arrays of per-buffer info.
+ */
BufferBlockPointers = (Block *) calloc(NBuffers, sizeof(Block));
PrivateRefCount = (long *) calloc(NBuffers, sizeof(long));
BufferLocks = (bits8 *) calloc(NBuffers, sizeof(bits8));
@@ -224,6 +247,27 @@ InitBufferPool(void)
{
BufferBlockPointers[i] = (Block) MAKE_PTR(BufferDescriptors[i].data);
}
+
+ /*
+ * Now that buffer access is initialized, set up a callback to shut it
+ * down again at backend exit.
+ */
+ on_shmem_exit(ShutdownBufferPoolAccess, 0);
+}
+
+/*
+ * Shut down buffer manager at backend exit.
+ *
+ * This is needed mainly to ensure that we don't leave any buffer reference
+ * counts set during an error exit.
+ */
+static void
+ShutdownBufferPoolAccess(void)
+{
+ /* Release any buffer context locks we are holding */
+ UnlockBuffers();
+ /* Release any buffer reference counts we are holding */
+ ResetBufferPool(false);
}
/* -----------------------------------------------------
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 29502c30161..a95432e0f82 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.86 2000/12/11 16:35:59 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.87 2000/12/18 00:44:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,7 +29,8 @@
*
* Interface (b):
*
- * ProcReleaseLocks -- frees the locks associated with this process,
+ * ProcReleaseLocks -- frees the locks associated with current transaction
+ *
* ProcKill -- destroys the shared memory state (and locks)
* associated with the process.
*
@@ -47,7 +48,7 @@
* This is so that we can support more backends. (system-wide semaphore
* sets run out pretty fast.) -ay 4/95
*
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.86 2000/12/11 16:35:59 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.87 2000/12/18 00:44:47 tgl Exp $
*/
#include "postgres.h"
@@ -332,7 +333,7 @@ GetOffWaitqueue(PROC *proc)
}
/*
- * ProcReleaseLocks() -- release all locks associated with this process
+ * ProcReleaseLocks() -- release all locks associated with current transaction
*
*/
void
@@ -340,7 +341,7 @@ ProcReleaseLocks()
{
if (!MyProc)
return;
- LockReleaseAll(1, &MyProc->lockQueue);
+ LockReleaseAll(DEFAULT_LOCKMETHOD, &MyProc->lockQueue);
GetOffWaitqueue(MyProc);
}
@@ -423,8 +424,6 @@ ProcKill(int exitStatus, Datum pid)
* ----------------
*/
GetOffWaitqueue(proc);
-
- return;
}
/*
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 3d74d187ff9..706b5d1fbf1 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.194 2000/12/03 10:27:27 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.195 2000/12/18 00:44:47 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@@ -61,7 +61,6 @@
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
-#include "utils/temprel.h"
#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
#endif
@@ -95,7 +94,7 @@ DLLIMPORT sigjmp_buf Warn_restart;
bool Warn_restart_ready = false;
bool InError = false;
-bool ExitAfterAbort = false;
+bool ProcDiePending = false;
static bool EchoQuery = false; /* default don't echo */
char pg_pathname[MAXPGPATH];
@@ -921,7 +920,8 @@ finish_xact_command(void)
void
handle_warn(SIGNAL_ARGS)
{
- if (StopIfError)
+ /* Don't joggle the elbow of a critical section */
+ if (CritSectionCount > 0)
{
QueryCancel = true;
return;
@@ -958,13 +958,15 @@ die(SIGNAL_ARGS)
{
PG_SETMASK(&BlockSig);
- ExitAfterAbort = true;
- if (StopIfError)
+ /* Don't joggle the elbow of a critical section */
+ if (CritSectionCount > 0)
{
QueryCancel = true;
+ ProcDiePending = true;
return;
}
- if (InError) /* If ERROR/FATAL is in progress... */
+ /* Don't joggle the elbow of proc_exit, either */
+ if (proc_exit_inprogress)
return;
elog(FATAL, "The system is shutting down");
}
@@ -1096,6 +1098,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
MemoryContextInit();
}
+ SetProcessingMode(InitProcessing);
+
/*
* Set default values for command-line options.
*/
@@ -1109,8 +1113,6 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
}
StatFp = stderr;
- SetProcessingMode(InitProcessing);
-
/* Check for PGDATESTYLE environment variable */
set_default_datestyle();
@@ -1428,11 +1430,16 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
break;
}
-
+ /*
+ * Post-processing for command line options.
+ *
+ * XXX It'd be nice if libpq were already running here, so we could do
+ * elog(NOTICE) instead of just writing on stderr...
+ */
if (Show_query_stats &&
(Show_parser_stats || Show_planner_stats || Show_executor_stats))
{
- elog(NOTICE, "Query statistics are disabled because parser, planner, or executor statistics are on.");
+ fprintf(stderr, "Query statistics are disabled because parser, planner, or executor statistics are on.\n");
Show_query_stats = false;
}
@@ -1528,7 +1535,13 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
XLOGPathInit();
BaseInit();
+
+ /*
+ * Start up xlog for standalone backend, and register to have it
+ * closed down at exit.
+ */
StartupXLOG();
+ on_shmem_exit(ShutdownXLOG, 0);
}
/*
@@ -1602,20 +1615,17 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
remote_host, username, DBName);
/*
- * general initialization
+ * General initialization.
+ *
+ * NOTE: if you are tempted to add code in this vicinity, consider
+ * putting it inside InitPostgres() instead. In particular, anything
+ * that involves database access should be there, not here.
*/
if (DebugLvl > 1)
elog(DEBUG, "InitPostgres");
InitPostgres(DBName, username);
-#ifdef MULTIBYTE
- /* set default client encoding */
- if (DebugLvl > 1)
- elog(DEBUG, "set_default_client_encoding");
- set_default_client_encoding();
-#endif
-
- on_shmem_exit(remove_all_temp_relations, 0);
+ SetProcessingMode(NormalProcessing);
/*
* Send this backend's cancellation info to the frontend.
@@ -1636,18 +1646,10 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface ");
- puts("$Revision: 1.194 $ $Date: 2000/12/03 10:27:27 $\n");
+ puts("$Revision: 1.195 $ $Date: 2000/12/18 00:44:47 $\n");
}
/*
- * Initialize the deferred trigger manager
- */
- if (DeferredTriggerInit() != 0)
- goto normalexit;
-
- SetProcessingMode(NormalProcessing);
-
- /*
* Create the memory context we will use in the main loop.
*
* QueryContext is reset once per iteration of the main loop,
@@ -1671,6 +1673,10 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
if (sigsetjmp(Warn_restart, 1) != 0)
{
/*
+ * NOTE: if you are tempted to add more code in this if-block,
+ * consider the probability that it should be in AbortTransaction()
+ * instead.
+ *
* Make sure we are in a valid memory context during recovery.
*
* We use ErrorContext in hopes that it will have some free space
@@ -1678,19 +1684,22 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
*/
MemoryContextSwitchTo(ErrorContext);
+ /* Do the recovery */
if (DebugLvl >= 1)
elog(DEBUG, "AbortCurrentTransaction");
AbortCurrentTransaction();
- if (ExitAfterAbort)
- goto errorexit;
-
/*
- * If we recovered successfully, return to normal top-level context
- * and clear ErrorContext for next time.
+ * Now return to normal top-level context and clear ErrorContext
+ * for next time.
*/
MemoryContextSwitchTo(TopMemoryContext);
MemoryContextResetAndDeleteChildren(ErrorContext);
+
+ /*
+ * Clear flag to indicate that we got out of error recovery mode
+ * successfully. (Flag was set in elog.c before longjmp().)
+ */
InError = false;
}
@@ -1775,7 +1784,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
if (HandleFunctionRequest() == EOF)
{
/* lost frontend connection during F message input */
- goto normalexit;
+ proc_exit(0);
}
/* commit the function-invocation transaction */
@@ -1830,7 +1839,14 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
*/
case 'X':
case EOF:
- goto normalexit;
+ /*
+ * NOTE: if you are tempted to add more code here, DON'T!
+ * Whatever you had in mind to do should be set up as
+ * an on_proc_exit or on_shmem_exit callback, instead.
+ * Otherwise it will fail to be called during other
+ * backend-shutdown scenarios.
+ */
+ proc_exit(0);
default:
elog(ERROR, "unknown frontend message was received");
@@ -1845,16 +1861,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
#endif
} /* end of input-reading loop */
-normalexit:
- ExitAfterAbort = true; /* ensure we will exit if elog during abort */
- AbortOutOfAnyTransaction();
- if (!IsUnderPostmaster)
- ShutdownXLOG();
-
-errorexit:
- pq_close();
- ProcReleaseLocks(); /* Just to be sure... */
- proc_exit(0);
+ /* can't get here because the above loop never exits */
+ Assert(false);
return 1; /* keep compiler quiet */
}
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index cb56f33c83c..6a9ef98f97a 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.73 2000/12/06 17:25:46 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.74 2000/12/18 00:44:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -159,7 +159,7 @@ elog(int lev, const char *fmt, ...)
/* this is probably redundant... */
if (IsInitProcessingMode())
lev = FATAL;
- if (StopIfError)
+ if (CritSectionCount > 0)
lev = STOP;
}
@@ -445,21 +445,26 @@ elog(int lev, const char *fmt, ...)
{
/*
+ * For a FATAL error, we let proc_exit clean up and exit.
+ *
* If we have not yet entered the main backend loop (ie, we are in
- * the postmaster or in backend startup), then go directly to
+ * the postmaster or in backend startup), we also go directly to
* proc_exit. The same is true if anyone tries to report an error
* after proc_exit has begun to run. (It's proc_exit's
* responsibility to see that this doesn't turn into infinite
* recursion!) But in the latter case, we exit with nonzero exit
* code to indicate that something's pretty wrong.
*/
- if (proc_exit_inprogress || !Warn_restart_ready)
+ if (lev == FATAL || !Warn_restart_ready || proc_exit_inprogress)
{
+ /*
+ * fflush here is just to improve the odds that we get to see
+ * the error message, in case things are so hosed that proc_exit
+ * crashes. Any other code you might be tempted to add here
+ * should probably be in an on_proc_exit callback instead.
+ */
fflush(stdout);
fflush(stderr);
- ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */
- ProcReleaseLocks(); /* get rid of real locks we hold */
- /* XXX shouldn't proc_exit be doing the above?? */
proc_exit((int) proc_exit_inprogress);
}
@@ -471,13 +476,8 @@ elog(int lev, const char *fmt, ...)
InError = true;
/*
- * Otherwise we can return to the main loop in postgres.c. In the
- * FATAL case, postgres.c will call proc_exit, but not till after
- * completing a standard transaction-abort sequence.
+ * Otherwise we can return to the main loop in postgres.c.
*/
- ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */
- if (lev == FATAL)
- ExitAfterAbort = true;
siglongjmp(Warn_restart, 1);
}
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index f213e561c1b..c8bd8a0d266 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.75 2000/12/14 23:51:35 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.76 2000/12/18 00:44:48 tgl Exp $
*
*
*-------------------------------------------------------------------------
@@ -28,6 +28,7 @@
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/pg_database.h"
+#include "commands/trigger.h"
#include "miscadmin.h"
#include "storage/backendid.h"
#include "storage/proc.h"
@@ -37,6 +38,7 @@
#include "utils/portal.h"
#include "utils/relcache.h"
#include "utils/syscache.h"
+#include "utils/temprel.h"
#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
@@ -44,6 +46,9 @@
static void ReverifyMyDatabase(const char *name);
static void InitCommunication(void);
+static void ShutdownPostgres(void);
+
+int lockingOff = 0; /* backend -L switch */
/*** InitPostgres support ***/
@@ -115,12 +120,8 @@ ReverifyMyDatabase(const char *name)
*/
dbform = (Form_pg_database) GETSTRUCT(tup);
if (! dbform->datallowconn)
- {
- heap_endscan(pgdbscan);
- heap_close(pgdbrel, AccessShareLock);
elog(FATAL, "Database \"%s\" is not currently accepting connections",
name);
- }
/*
* OK, we're golden. Only other to-do item is to save the MULTIBYTE
@@ -163,6 +164,28 @@ InitCommunication(void)
}
+/*
+ * Early initialization of a backend (either standalone or under postmaster).
+ * This happens even before InitPostgres.
+ */
+void
+BaseInit(void)
+{
+ /*
+ * Attach to shared memory and semaphores, and initialize our
+ * input/output/debugging file descriptors.
+ */
+ InitCommunication();
+ DebugFileOpen();
+
+ /* Do local initialization of storage and buffer managers */
+ smgrinit();
+ InitBufferPoolAccess();
+ InitLocalBuffer();
+
+ EnablePortalManager(); /* memory for portal/transaction stuff */
+}
+
/* --------------------------------
* InitPostgres
@@ -172,16 +195,13 @@ InitCommunication(void)
* Be very careful with the order of calls in the InitPostgres function.
* --------------------------------
*/
-int lockingOff = 0; /* backend -L switch */
-
-/*
- */
void
InitPostgres(const char *dbname, const char *username)
{
bool bootstrap = IsBootstrapProcessingMode();
SetDatabaseName(dbname);
+
/* ----------------
* initialize the database id used for system caches and lock tables
* ----------------
@@ -299,6 +319,12 @@ InitPostgres(const char *dbname, const char *username)
*/
InitCatalogCache();
+ /*
+ * Initialize the deferred trigger manager --- must happen before
+ * first transaction start.
+ */
+ DeferredTriggerInit();
+
/* start a new transaction here before access to db */
if (!bootstrap)
StartTransactionCommand();
@@ -322,27 +348,62 @@ InitPostgres(const char *dbname, const char *username)
/*
* Unless we are bootstrapping, double-check that InitMyDatabaseInfo()
- * got a correct result. We can't do this until essentially all the
- * infrastructure is up, so just do it at the end.
+ * got a correct result. We can't do this until all the database-access
+ * infrastructure is up.
*/
if (!bootstrap)
ReverifyMyDatabase(dbname);
-}
-void
-BaseInit(void)
-{
+#ifdef MULTIBYTE
+ /* set default client encoding --- uses info from ReverifyMyDatabase */
+ set_default_client_encoding();
+#endif
+
/*
- * Attach to shared memory and semaphores, and initialize our
- * input/output/debugging file descriptors.
+ * Set up process-exit callbacks to remove temp relations and then
+ * do pre-shutdown cleanup. This should be last because we want
+ * shmem_exit to call these routines before the exit callbacks that
+ * are registered by buffer manager, lock manager, etc. We need
+ * to run this code before we close down database access!
*/
- InitCommunication();
- DebugFileOpen();
-
- smgrinit();
+ on_shmem_exit(ShutdownPostgres, 0);
+ /* because callbacks are called in reverse order, this gets done first: */
+ on_shmem_exit(remove_all_temp_relations, 0);
- EnablePortalManager(); /* memory for portal/transaction stuff */
+ /* close the transaction we started above */
+ if (!bootstrap)
+ CommitTransactionCommand();
+}
- /* initialize the local buffer manager */
- InitLocalBuffer();
+/*
+ * Backend-shutdown callback. Do cleanup that we want to be sure happens
+ * before all the supporting modules begin to nail their doors shut via
+ * their own callbacks. Note that because this has to be registered very
+ * late in startup, it will not get called if we suffer a failure *during*
+ * startup.
+ *
+ * User-level cleanup, such as temp-relation removal and UNLISTEN, happens
+ * via separate callbacks that execute before this one. We don't combine the
+ * callbacks because we still want this one to happen if the user-level
+ * cleanup fails.
+ */
+static void
+ShutdownPostgres(void)
+{
+ /*
+ * 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 spinlocks that we may hold. This is a kluge to improve
+ * the odds that we won't get into a self-made stuck spinlock scenario
+ * while trying to shut down.
+ */
+ ProcReleaseSpins(NULL);
+ /*
+ * 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.
+ */
+ smgrDoPendingDeletes(false); /* delete as though aborting xact */
}
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 269315dc78e..1c10501fb7d 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -3,7 +3,7 @@
*
* PostgreSQL transaction log manager
*
- * $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.13 2000/12/03 10:27:28 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.14 2000/12/18 00:44:48 tgl Exp $
*/
#ifndef XLOG_H
#define XLOG_H
@@ -88,7 +88,7 @@ typedef XLogPageHeaderData *XLogPageHeader;
extern StartUpID ThisStartUpID; /* current SUI */
extern bool InRecovery;
extern XLogRecPtr MyLastRecPtr;
-extern uint32 StopIfError;
+extern uint32 CritSectionCount;
typedef struct RmgrData
{
diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h
index 22dac3f5fe3..c9fbcae54a3 100644
--- a/src/include/commands/trigger.h
+++ b/src/include/commands/trigger.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: trigger.h,v 1.21 2000/06/08 22:37:42 momjian Exp $
+ * $Id: trigger.h,v 1.22 2000/12/18 00:44:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -129,7 +129,7 @@ typedef struct DeferredTriggerEventData
typedef struct DeferredTriggerEventData *DeferredTriggerEvent;
-extern int DeferredTriggerInit(void);
+extern void DeferredTriggerInit(void);
extern void DeferredTriggerBeginXact(void);
extern void DeferredTriggerEndQuery(void);
extern void DeferredTriggerEndXact(void);
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
index c86862317c8..a8deb15eee2 100644
--- a/src/include/libpq/libpq.h
+++ b/src/include/libpq/libpq.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq.h,v 1.41 2000/11/14 01:15:04 momjian Exp $
+ * $Id: libpq.h,v 1.42 2000/12/18 00:44:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -60,7 +60,6 @@ extern int StreamServerPort(int family, char *hostName,
extern int StreamConnection(int server_fd, Port *port);
extern void StreamClose(int sock);
extern void pq_init(void);
-extern void pq_close(void);
extern int pq_getbytes(char *s, size_t len);
extern int pq_getstring(StringInfo s);
extern int pq_peekbyte(void);
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index 27bcc090ed9..7f1906441a8 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: bufmgr.h,v 1.46 2000/11/30 08:46:26 vadim Exp $
+ * $Id: bufmgr.h,v 1.47 2000/12/18 00:44:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -168,6 +168,7 @@ extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
extern int FlushBuffer(Buffer buffer, bool sync, bool release);
extern void InitBufferPool(void);
+extern void InitBufferPoolAccess(void);
extern void PrintBufferUsage(FILE *statfp);
extern void ResetBufferUsage(void);
extern void ResetBufferPool(bool isCommit);
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index acb82049730..37db2c7aaf8 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: elog.h,v 1.20 2000/12/06 17:25:45 tgl Exp $
+ * $Id: elog.h,v 1.21 2000/12/18 00:44:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,24 +28,24 @@ extern int Use_syslog;
#endif
/*
- * If StopIfError > 0 signal handlers mustn't do
+ * If CritSectionCount > 0, signal handlers mustn't do
* elog(ERROR|FATAL), instead remember what action is
- * required with QueryCancel & ExitAfterAbort.
+ * required with QueryCancel & ProcDiePending.
*/
-extern uint32 StopIfError; /* duplicates access/xlog.h */
+extern uint32 CritSectionCount; /* duplicates access/xlog.h */
extern bool QueryCancel; /* duplicates miscadmin.h */
-extern bool ExitAfterAbort;
+extern bool ProcDiePending;
-#define START_CRIT_CODE (StopIfError++)
+#define START_CRIT_CODE (CritSectionCount++)
#define END_CRIT_CODE \
do { \
- if (!StopIfError) \
+ if (CritSectionCount == 0) \
elog(STOP, "Not in critical section"); \
- StopIfError--; \
- if (!StopIfError && QueryCancel) \
+ CritSectionCount--; \
+ if (CritSectionCount == 0 && QueryCancel) \
{ \
- if (ExitAfterAbort) \
+ if (ProcDiePending) \
elog(FATAL, "The system is shutting down"); \
else \
elog(ERROR, "Query was cancelled."); \