From: Massimo Dal Zotto <dz@cs.unitn.it>
authorMarc G. Fournier <scrappy@hub.org>
Tue, 25 Aug 1998 21:34:10 +0000 (21:34 +0000)
committerMarc G. Fournier <scrappy@hub.org>
Tue, 25 Aug 1998 21:34:10 +0000 (21:34 +0000)
> tprintf.patch
>
>       tprintf.patch
>
>       adds functions and macros which implement a conditional trace package
>       with the ability to change flags and numeric options of running
>       backends at runtime.
>       Options/flags can be specified in the command line and/or read from
>       the file pg_options in the data directory.

src/backend/access/nbtree/nbtree.c
src/backend/access/nbtree/nbtsort.c
src/backend/postmaster/postmaster.c
src/backend/storage/ipc/ipc.c
src/backend/storage/ipc/spin.c
src/backend/tcop/postgres.c
src/backend/utils/error/assert.c
src/backend/utils/error/elog.c
src/backend/utils/misc/Makefile

index 406cd4677351e31a6da80a069c9f135f20346bba..582988c1b07eec50f01a4b0ee773027defad776c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.29 1998/08/19 02:01:16 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.30 1998/08/25 21:33:56 scrappy Exp $
  *
  * NOTES
  *   This file contains only the public interface routines.
@@ -35,8 +35,8 @@
 
 #ifdef BTREE_BUILD_STATS
 #include <tcop/tcopprot.h>
-extern int ShowExecutorStats;
-
+#include <utils/trace.h>
+#define ShowExecutorStats pg_options[TRACE_EXECUTORSTATS]
 #endif
 
 
index 12effb71eb42dff78caeea073550e45cccce8e3c..404653f8e9c92d066013e2c17e48ee7438fad144 100644 (file)
@@ -5,7 +5,7 @@
  *
  *
  * IDENTIFICATION
- *   $Id: nbtsort.c,v 1.30 1998/06/15 19:27:59 momjian Exp $
+ *   $Id: nbtsort.c,v 1.31 1998/08/25 21:33:57 scrappy Exp $
  *
  * NOTES
  *
@@ -64,8 +64,8 @@
 
 #ifdef BTREE_BUILD_STATS
 #include "tcop/tcopprot.h"
-extern int ShowExecutorStats;
-
+#include <utils/trace.h>
+#define ShowExecutorStats pg_options[TRACE_EXECUTORSTATS]
 #endif
 
 static BTItem _bt_buildadd(Relation index, void *pstate, BTItem bti, int flags);
index 0525282fd501a1e9c72128800d335a7575f88c75..6ef32523e79de7d132cb9b8fc9c0e798d6daa348 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.94 1998/08/25 21:04:36 scrappy Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.95 1998/08/25 21:33:59 scrappy Exp $
  *
  * NOTES
  *
@@ -92,6 +92,7 @@
 #include "port-protos.h"       /* For gethostname() */
 #endif
 #include "storage/fd.h"
+#include "utils/trace.h"
 
 #if !defined(MAXINT)
 #define MAXINT        INT_MAX
@@ -116,6 +117,8 @@ typedef struct bkend
    long        cancel_key;     /* cancel key for cancels for this backend */
 } Backend;
 
+Port *MyBackendPort = NULL;
+
 /* list of active backends.  For garbage collection only now. */
 
 static Dllist *BackendList;
@@ -232,6 +235,7 @@ static int processCancelRequest(Port *port, PacketLen len, void *pkt);
 static int initMasks(fd_set *rmask, fd_set *wmask);
 static long PostmasterRandom(void);
 static void RandomSalt(char *salt);
+static void SignalChildren(SIGNAL_ARGS);
 
 #ifdef CYR_RECODE
 void GetCharSetByHost(char *, int, char *);
@@ -314,16 +318,16 @@ PostmasterMain(int argc, char *argv[])
     *  We need three params so we can display status.  If we don't
     *  get them from the user, let's make them ourselves.
     */
-   if (argc < 4)
+   if (argc < 5)
    {
        int i;
-       char *new_argv[5];
+       char *new_argv[6];
 
        for (i=0; i < argc; i++)
            new_argv[i] = argv[i];
-       for (; i < 4; i++)
+       for (; i < 5; i++)
            new_argv[i] = "";
-       new_argv[4] = NULL;
+       new_argv[5] = NULL;
 
        if (!Execfile[0] && FindExec(Execfile, argv[0], "postmaster") < 0)
        {
@@ -363,6 +367,7 @@ PostmasterMain(int argc, char *argv[])
        hostName = hostbuf;
    }
 
+   MyProcPid = getpid();
    DataDir = getenv("PGDATA"); /* default value */
 
    opterr = 0;
@@ -424,6 +429,7 @@ PostmasterMain(int argc, char *argv[])
                }
                else
                    DebugLvl = 1;
+               pg_options[TRACE_VERBOSE] = DebugLvl;
                break;
            case 'i':
                NetServer = true;
@@ -535,14 +541,17 @@ PostmasterMain(int argc, char *argv[])
     * Set up signal handlers for the postmaster process.
     */
 
-   pqsignal(SIGINT, pmdie);
-   pqsignal(SIGCHLD, reaper);
-   pqsignal(SIGTTIN, SIG_IGN);
-   pqsignal(SIGTTOU, SIG_IGN);
-   pqsignal(SIGHUP, pmdie);
-   pqsignal(SIGTERM, pmdie);
-   pqsignal(SIGCONT, dumpstatus);
-   pqsignal(SIGPIPE, SIG_IGN);
+   pqsignal(SIGHUP,   pmdie);      /* send SIGHUP, don't die */
+   pqsignal(SIGINT,   pmdie);      /* die */
+   pqsignal(SIGQUIT,  pmdie);      /* send SIGTERM and die */
+   pqsignal(SIGTERM,  pmdie);      /* send SIGTERM,SIGKILL and die */
+   pqsignal(SIGPIPE,  SIG_IGN);    /* ignored */
+   pqsignal(SIGUSR1,  pmdie);      /* send SIGUSR1 and die */
+   pqsignal(SIGUSR2,  pmdie);      /* send SIGUSR2, don't die */
+   pqsignal(SIGCHLD,  reaper);     /* handle child termination */
+   pqsignal(SIGTTIN,  SIG_IGN);    /* ignored */
+   pqsignal(SIGTTOU,  SIG_IGN);    /* ignored */
+   pqsignal(SIGWINCH, dumpstatus); /* dump port status */
 
    status = ServerLoop();
 
@@ -980,6 +989,52 @@ reset_shared(short port)
 static void
 pmdie(SIGNAL_ARGS)
 {
+   int i;
+
+   TPRINTF(TRACE_VERBOSE, "pmdie %d", postgres_signal_arg);
+
+   /*
+    * Kill self and/or children processes depending on signal number.
+    */
+   switch (postgres_signal_arg) {
+       case SIGHUP:
+           /* Send SIGHUP to all children (update options flags) */
+           SignalChildren(SIGHUP);
+           /* Don't die */
+           return;
+       case SIGINT:
+           /* Die without killing children */
+           break;
+       case SIGQUIT:
+           /* Shutdown all children with SIGTERM */
+           SignalChildren(SIGTERM);
+           /* Don't die */
+           return;
+       case SIGTERM:
+           /* Shutdown all children with SIGTERM and SIGKILL, then die */
+           SignalChildren(SIGTERM);
+           for (i=0; i<10; i++) {
+               if (!DLGetHead(BackendList)) {
+                   break;
+               }
+               sleep(1);
+           }
+           if (DLGetHead(BackendList)) {
+               SignalChildren(SIGKILL);
+           }
+           break;
+       case SIGUSR1:
+           /* Quick die all children with SIGUSR1 and die */
+           SignalChildren(SIGUSR1);
+           break;
+       case SIGUSR2:
+           /* Send SIGUSR2 to all children (AsyncNotifyHandler) */
+           SignalChildren(SIGUSR2);
+           /* Don't die */
+           return;
+   }
+
+   /* exit postmaster */
    proc_exit(0);
 }
 
@@ -1122,6 +1177,35 @@ CleanupProc(int pid,
    }
 }
 
+/*
+ * Send a signal to all chidren processes.
+ */
+static void
+SignalChildren(int signal)
+{
+   Dlelem      *curr,
+               *next;
+   Backend     *bp;
+   int         mypid = getpid();
+
+   curr = DLGetHead(BackendList);
+   while (curr)
+   {
+       next = DLGetSucc(curr);
+       bp = (Backend *) DLE_VAL(curr);
+
+       if (bp->pid != mypid)
+       {
+           TPRINTF(TRACE_VERBOSE,
+                   "SignalChildren: sending signal %d to process %d",
+                   signal, bp->pid);
+           kill(bp->pid, signal);
+       }
+
+       curr = next;
+   }
+}
+
 /*
  * BackendStartup -- start backend process
  *
@@ -1342,6 +1426,9 @@ DoBackend(Port *port)
        StreamClose(ServerSock_INET);
    StreamClose(ServerSock_UNIX);
 
+   /* Save port for ps status */
+   MyProcPort = port;
+
    /*
     * Don't want backend to be able to see the postmaster random number
     * generator state.  We have to clobber the static random_seed *and*
@@ -1368,7 +1455,13 @@ DoBackend(Port *port)
     *  a big win.
     */
    
+#ifndef linux
+   /*
+    * This doesn't work on linux and overwrites the only valid
+    * pointer to the argv buffer.  See PS_INIT_STATUS macro.
+    */
    real_argv[0] = Execfile;
+#endif
 
    /* Tell the backend it is being called from the postmaster */
    av[ac++] = "-p";
@@ -1386,8 +1479,6 @@ DoBackend(Port *port)
        sprintf(debugbuf, "-d%d", DebugLvl);
        av[ac++] = debugbuf;
    }
-   else
-       av[ac++] = "-Q";
 
    /* Pass the requested debugging output file */
    if (port->tty[0])
index debe3e5658ce6fcf1262bb08af641af5dbcc2d95..a9c56cf728f624b166f5f9fcca4e0c70ba17eb79 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.30 1998/07/12 04:43:28 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.31 1998/08/25 21:34:01 scrappy Exp $
  *
  * NOTES
  *
@@ -39,6 +39,7 @@
 #include <sys/shm.h>
 #include "utils/memutils.h"
 #include "libpq/libpq.h"
+#include "utils/trace.h"
 
 #if defined(solaris_sparc)
 #include <string.h>
@@ -113,17 +114,26 @@ proc_exit(int code)
 {
    int         i;
 
+   TPRINTF(TRACE_VERBOSE, "proc_exit(%d) [#%d]", code, proc_exit_inprogress);
+
+    /*
+    * If proc_exit is called too many times something bad is
+    * happenig, so exit immediately.
+    */
+   if (proc_exit_inprogress > 9) {
+       elog(ERROR, "infinite recursion in proc_exit");
+       goto exit;
+   }
+
    /* ----------------
     *  if proc_exit_inprocess is true, then it means that we
     *  are being invoked from within an on_exit() handler
     *  and so we return immediately to avoid recursion.
     * ----------------
     */
-   if (proc_exit_inprogress)
+   if (proc_exit_inprogress++)
        return;
 
-   proc_exit_inprogress = 1;
-
    /* do our shared memory exits first */
    shmem_exit(code);
    
@@ -134,6 +144,8 @@ proc_exit(int code)
    for (i = on_proc_exit_index - 1; i >= 0; --i)
        (*on_proc_exit_list[i].function) (code, on_proc_exit_list[i].arg);
 
+exit:
+   TPRINTF(TRACE_VERBOSE, "exit(%d)", code);
    exit(code);
 }
 
@@ -150,17 +162,27 @@ shmem_exit(int code)
 {
    int         i;
 
+   TPRINTF(TRACE_VERBOSE, "shmem_exit(%d) [#%d]",
+           code, shmem_exit_inprogress);
+
+   /*
+    * If shmem_exit is called too many times something bad is
+    * happenig, so exit immediately.
+    */
+   if (shmem_exit_inprogress > 9) {
+       elog(ERROR, "infinite recursion in shmem_exit");
+       exit(-1);
+   }
+
    /* ----------------
     *  if shmem_exit_inprocess is true, then it means that we
     *  are being invoked from within an on_exit() handler
     *  and so we return immediately to avoid recursion.
     * ----------------
     */
-   if (shmem_exit_inprogress)
+   if (shmem_exit_inprogress++)
        return;
 
-   shmem_exit_inprogress = 1;
-
    /* ----------------
     *  call all the callbacks registered before calling exit().
     * ----------------
@@ -315,7 +337,7 @@ IpcSemaphoreCreate(IpcSemaphoreKey semKey,
    {
        *status = IpcSemIdNotExist;     /* there doesn't exist a semaphore */
 #ifdef DEBUG_IPC
-       fprintf(stderr, "calling semget with %d, %d , %d\n",
+       EPRINTF("calling semget with %d, %d , %d\n",
                semKey,
                semNum,
                IPC_CREAT | permission);
@@ -324,8 +346,9 @@ IpcSemaphoreCreate(IpcSemaphoreKey semKey,
 
        if (semId < 0)
        {
-           perror("semget");
-           IpcConfigTip();
+           EPRINTF("IpcSemaphoreCreate: semget failed (%s) "
+                   "key=%d, num=%d, permission=%o",
+                   strerror(errno), semKey, semNum, permission);
            proc_exit(3);
        }
        for (i = 0; i < semNum; i++)
@@ -334,8 +357,8 @@ IpcSemaphoreCreate(IpcSemaphoreKey semKey,
        errStatus = semctl(semId, 0, SETALL, semun);
        if (errStatus == -1)
        {
-           perror("semctl");
-           IpcConfigTip();
+           EPRINTF("IpcSemaphoreCreate: semctl failed (%s) id=%d",
+                   strerror(errno), semId);
        }
 
        if (removeOnExit)
@@ -349,7 +372,7 @@ IpcSemaphoreCreate(IpcSemaphoreKey semKey,
    }
 
 #ifdef DEBUG_IPC
-   fprintf(stderr, "\nIpcSemaphoreCreate, status %d, returns %d\n",
+   EPRINTF("\nIpcSemaphoreCreate, status %d, returns %d\n",
            *status,
            semId);
    fflush(stdout);
@@ -379,8 +402,8 @@ IpcSemaphoreSet(int semId, int semno, int value)
 
    if (errStatus == -1)
    {
-       perror("semctl");
-       IpcConfigTip();
+       EPRINTF("IpcSemaphoreSet: semctl failed (%s) id=%d",
+               strerror(errno), semId);
    }
 }
 
@@ -441,8 +464,8 @@ IpcSemaphoreLock(IpcSemaphoreId semId, int sem, int lock)
 
    if (errStatus == -1)
    {
-       perror("semop");
-       IpcConfigTip();
+       EPRINTF("IpcSemaphoreLock: semop failed (%s) id=%d",
+               strerror(errno), semId);
        proc_exit(255);
    }
 }
@@ -486,8 +509,8 @@ IpcSemaphoreUnlock(IpcSemaphoreId semId, int sem, int lock)
 
    if (errStatus == -1)
    {
-       perror("semop");
-       IpcConfigTip();
+       EPRINTF("IpcSemaphoreUnlock: semop failed (%s) id=%d",
+               strerror(errno), semId);
        proc_exit(255);
    }
 }
@@ -534,10 +557,9 @@ IpcMemoryCreate(IpcMemoryKey memKey, uint32 size, int permission)
 
    if (shmid < 0)
    {
-       fprintf(stderr, "IpcMemoryCreate: memKey=%d , size=%d , permission=%d",
-               memKey, size, permission);
-       perror("IpcMemoryCreate: shmget(..., create, ...) failed");
-       IpcConfigTip();
+       EPRINTF("IpcMemoryCreate: shmget failed (%s) "
+               "key=%d, size=%d, permission=%o",
+               strerror(errno), memKey, size, permission);
        return (IpcMemCreationFailed);
    }
 
@@ -560,10 +582,9 @@ IpcMemoryIdGet(IpcMemoryKey memKey, uint32 size)
 
    if (shmid < 0)
    {
-       fprintf(stderr, "IpcMemoryIdGet: memKey=%d , size=%d , permission=%d",
-               memKey, size, 0);
-       perror("IpcMemoryIdGet:  shmget() failed");
-       IpcConfigTip();
+       EPRINTF("IpcMemoryIdGet: shmget failed (%s) "
+               "key=%d, size=%d, permission=%o",
+               strerror(errno), memKey, size, 0);
        return (IpcMemIdGetFailed);
    }
 
@@ -602,8 +623,8 @@ IpcMemoryAttach(IpcMemoryId memId)
    /* if ( *memAddress == -1) { XXX ??? */
    if (memAddress == (char *) -1)
    {
-       perror("IpcMemoryAttach: shmat() failed");
-       IpcConfigTip();
+       EPRINTF("IpcMemoryAttach: shmat failed (%s) id=%d",
+               strerror(errno), memId);
        return (IpcMemAttachFailed);
    }
 
index 40735a8786a05a8fb8500eb21b955c721ca2760e..7f8986e411a873571c30702b7153640c1726b37e 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.14 1998/06/27 15:47:45 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.15 1998/08/25 21:34:03 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -31,6 +31,7 @@
 #include "storage/shmem.h"
 #include "storage/spin.h"
 #include "storage/proc.h"
+#include "utils/trace.h"
 
 #ifndef HAS_TEST_AND_SET
 #include <sys/sem.h>
@@ -81,10 +82,12 @@ InitSpinLocks(int init, IPCKey key)
 }
 
 #ifdef LOCKDEBUG
-#define PRINT_LOCK(LOCK) printf("(locklock = %d, flag = %d, nshlocks = %d, \
-shlock = %d, exlock =%d)\n", LOCK->locklock, \
-                               LOCK->flag, LOCK->nshlocks, LOCK->shlock, \
-                               LOCK->exlock)
+#define PRINT_LOCK(LOCK) \
+    TPRINTF(TRACE_SPINLOCKS, \
+           "(locklock = %d, flag = %d, nshlocks = %d, shlock = %d, " \
+           "exlock =%d)\n", LOCK->locklock, \
+           LOCK->flag, LOCK->nshlocks, LOCK->shlock, \
+           LOCK->exlock)
 #endif
 
 /* from ipc.c */
@@ -98,8 +101,7 @@ SpinAcquire(SPINLOCK lockid)
    /* This used to be in ipc.c, but move here to reduce function calls */
    slckP = &(SLockArray[lockid]);
 #ifdef LOCKDEBUG
-   printf("SpinAcquire(%d)\n", lockid);
-   printf("IN: ");
+   TPRINTF(TRACE_SPINLOCKS, "SpinAcquire: %d", lockid);
    PRINT_LOCK(slckP);
 #endif
 ex_try_again:
@@ -112,7 +114,7 @@ ex_try_again:
            S_LOCK(&(slckP->shlock));
            S_UNLOCK(&(slckP->locklock));
 #ifdef LOCKDEBUG
-           printf("OUT: ");
+           TPRINTF(TRACE_SPINLOCKS, "OUT: ");
            PRINT_LOCK(slckP);
 #endif
            break;
@@ -124,6 +126,9 @@ ex_try_again:
            goto ex_try_again;
    }
    PROC_INCR_SLOCK(lockid);
+#ifdef LOCKDEBUG
+   TPRINTF(TRACE_SPINLOCKS, "SpinAcquire: got %d", lockid);
+#endif
 }
 
 void
@@ -131,13 +136,23 @@ SpinRelease(SPINLOCK lockid)
 {
    SLock      *slckP;
 
-   PROC_DECR_SLOCK(lockid);
-
    /* This used to be in ipc.c, but move here to reduce function calls */
    slckP = &(SLockArray[lockid]);
+
+#ifdef USE_ASSERT_CHECKING
+   /*
+    * Check that we are actually holding the lock we are releasing.
+    * This can be done only after MyProc has been initialized.
+    */
+   if (MyProc)
+       Assert(MyProc->sLocks[lockid] > 0);
+   Assert(slckP->flag != NOLOCK);
+#endif
+
+   PROC_DECR_SLOCK(lockid);
+
 #ifdef LOCKDEBUG
-   printf("SpinRelease(%d)\n", lockid);
-   printf("IN: ");
+   TPRINTF("SpinRelease: %d\n", lockid);
    PRINT_LOCK(slckP);
 #endif
    S_LOCK(&(slckP->locklock));
@@ -160,7 +175,7 @@ SpinRelease(SPINLOCK lockid)
    S_UNLOCK(&(slckP->exlock));
    S_UNLOCK(&(slckP->locklock));
 #ifdef LOCKDEBUG
-   printf("OUT: ");
+   TPRINTF(TRACE_SPINLOCKS, "SpinRelease: released %d", lockid);
    PRINT_LOCK(slckP);
 #endif
 }
index 838f4756d2a31c60c1c33e7ff34799b354add123..5ad49c8ac4e84a9c1f539fb42944a5c3a3e4e6ef 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.85 1998/08/25 21:04:38 scrappy Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.86 1998/08/25 21:34:04 scrappy Exp $
  *
  * NOTES
  *   this is the "main" module of the postgres backend and
@@ -36,7 +36,9 @@
 #if HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #endif                         /* aix */
-
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
 
 #include "postgres.h"
 #include "miscadmin.h"
@@ -66,6 +68,7 @@
 #include "tcop/utility.h"
 #include "utils/mcxt.h"
 #include "utils/rel.h"
+#include "utils/ps_status.h"
 
 #if FALSE
 #include "nodes/relation.h"
 #include "nodes/memnodes.h"
 #endif
 
+#include "utils/trace.h"
+
 #ifdef MULTIBYTE
 #include "mb/pg_wchar.h"
 #endif
 
+/*
+ * Trace flags, see backend/utils/misc/trace.c
+ */
+#define Verbose                pg_options[TRACE_VERBOSE]
+#define DebugPrintQuery        pg_options[TRACE_QUERY]
+#define DebugPrintPlan     pg_options[TRACE_PLAN]
+#define DebugPrintParse        pg_options[TRACE_PARSE]
+#define ShowParserStats        pg_options[TRACE_PARSERSTATS]
+#define ShowPlannerStats   pg_options[TRACE_PLANNERSTATS]
+#define ShowExecutorStats  pg_options[TRACE_EXECUTORSTATS]
+#define DebugPrintRewrittenParsetree \
+                           pg_options[TRACE_REWRITTEN]
+#ifdef LOCK_MGR_DEBUG
+#define LockDebug          pg_options[TRACE_LOCKS]
+#endif
+
+#define DeadlockCheckTimer pg_options[OPT_DEADLOCKTIMEOUT]
+#define HostnameLookup     pg_options[OPT_HOSTLOOKUP]
+#define ShowPortNumber     pg_options[OPT_SHOWPORTNUMBER]
+
 /* ----------------
  *     global variables
  * ----------------
  */
-static bool DebugPrintQuery = false;
-static bool DebugPrintPlan = false;
-static bool DebugPrintParse = false;
-static bool DebugPrintRewrittenParsetree = false;
 
 /*static bool  EnableRewrite = true; , never changes why have it*/
 CommandDest whereToSendOutput;
-const char **ps_status;    /* this is our 'ps' status, argv[3] */
 
-#ifdef LOCK_MGR_DEBUG
-extern int lockDebug;
+/* Define status buffer needed by PS_SET_STATUS */
+PS_DEFINE_BUFFER;
 
-#endif
 extern int lockingOff;
 extern int NBuffers;
 
@@ -129,9 +148,6 @@ extern int  NBuffers;
 static int EchoQuery = 0;      /* default don't echo */
 time_t     tim;
 char       pg_pathname[256];
-static int ShowParserStats;
-static int ShowPlannerStats;
-int            ShowExecutorStats;
 FILE      *StatFp;
 
 /* ----------------
@@ -260,7 +276,7 @@ InteractiveBackend(char *inBuf)
 
        if (end)
        {
-           if (!Quiet)
+           if (Verbose)
                puts("EOF");
            IsEmptyQuery = true;
            proc_exit(0);
@@ -278,7 +294,7 @@ InteractiveBackend(char *inBuf)
     * ----------------
     */
    if (EchoQuery)
-       printf("query is: %s\n", inBuf);
+       printf("query: %s\n", inBuf);
 
    return ('Q');
 }
@@ -521,9 +537,9 @@ pg_parse_and_plan(char *query_string,   /* string to execute */
        }
    }
 
-   if (DebugPrintRewrittenParsetree == true)
+   if (DebugPrintRewrittenParsetree)
    {
-       printf("\n---- \tafter rewriting:\n");
+       TPRINTF(TRACE_REWRITTEN, "after rewriting:");
 
        for (i = 0; i < querytree_list->len; i++)
        {
@@ -584,11 +600,10 @@ pg_parse_and_plan(char *query_string, /* string to execute */
             *  also for queries in functions.  DZ - 27-8-1996
             * ----------------
             */
-           if (DebugPrintPlan == true)
+           if (DebugPrintPlan)
            {
-               printf("\n---- \tplan is :\n");
+               TPRINTF(TRACE_PLAN, "plan:");
                nodeDisplay(plan);
-               printf("\n");
            }
 #endif
        }
@@ -696,11 +711,11 @@ pg_exec_query_dest(char *query_string,    /* string to execute */
             *   because that is done in ProcessUtility.
             * ----------------
             */
-           if (!Quiet)
-           {
-               time(&tim);
-               printf("\tProcessUtility() at %s\n", ctime(&tim));
-           }
+           if (DebugPrintQuery) {
+               TPRINTF(TRACE_QUERY, "ProcessUtility: %s", query_string);
+           } else if (Verbose) {
+               TPRINTF(TRACE_VERBOSE, "ProcessUtility");
+           } 
 
            ProcessUtility(querytree->utilityStmt, dest);
 
@@ -726,11 +741,10 @@ pg_exec_query_dest(char *query_string,    /* string to execute */
             *  print plan if debugging
             * ----------------
             */
-           if (DebugPrintPlan == true)
+           if (DebugPrintPlan)
            {
-               printf("\n---- plan is :\n");
+               TPRINTF(TRACE_PLAN, "plan:");
                nodeDisplay(plan);
-               printf("\n");
            }
 #endif
 
@@ -743,10 +757,9 @@ pg_exec_query_dest(char *query_string, /* string to execute */
 
            for (j = 0; j < _exec_repeat_; j++)
            {
-               if (!Quiet)
+               if (Verbose)
                {
-                   time(&tim);
-                   printf("\tProcessQuery() at %s\n", ctime(&tim));
+                   TPRINTF(TRACE_VERBOSE, "ProcessQuery");
                }
                ProcessQuery(querytree, plan, dest);
            }
@@ -775,7 +788,7 @@ pg_exec_query_dest(char *query_string,  /* string to execute */
 /* --------------------------------
  *     signal handler routines used in PostgresMain()
  *
- *     handle_warn() is used to catch kill(getpid(), SIGHUP) which
+ *     handle_warn() is used to catch kill(getpid(),SIGQUIT) which
  *     occurs when elog(ERROR) is called.
  *
  *     quickdie() occurs when signalled by the postmaster.
@@ -887,17 +900,20 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
                    flagEu = false;
    int             flag;
 
-   char       *DBName = NULL;
-   int         errs = 0;
+   char            *DBName = NULL;
+   int             errs = 0;
 
-   char        firstchar;
-   char        parser_input[MAX_PARSE_BUFFER];
-   char       *userName;
+   char            firstchar;
+   char            parser_input[MAX_PARSE_BUFFER];
+   char            *userName;
+   char            *remote_info;
+   char            *remote_host;
+   unsigned short  remote_port = 0;
 
-   char       *DBDate = NULL;
-   extern int  optind;
-   extern char *optarg;
-   extern short DebugLvl;
+   char            *DBDate = NULL;
+   extern int      optind;
+   extern char     *optarg;
+   extern short    DebugLvl;
 
    /* ----------------
     *  parse command line arguments
@@ -909,8 +925,9 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
     */
    ShowStats = 0;
    ShowParserStats = ShowPlannerStats = ShowExecutorStats = 0;
+   DeadlockCheckTimer = DEADLOCK_CHECK_TIMER;
 #ifdef LOCK_MGR_DEBUG
-   lockDebug = 0;
+   LockDebug = 0;
 #endif
 
    /*
@@ -944,6 +961,11 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
        else if (strcasecmp(DBDate, "EURO") == 0)
            EuroDates = TRUE;
    }
+   
+   /*
+    * Read default pg_options from file $DATADIR/pg_options.
+    */
+   read_pg_options(0);
 
     optind = 1; /* reset after postmaster usage */
    
@@ -994,10 +1016,20 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
            case 'd':           /* debug level */
                flagQ = false;
                DebugLvl = (short) atoi(optarg);
-               if (DebugLvl > 1)
-                   DebugPrintQuery = true;
-               if (DebugLvl > 2)
+               if (DebugLvl >= 1)
+               {
+                   Verbose = DebugLvl;
+               }
+               if (DebugLvl >= 2)
+               {
+                   DebugPrintQuery = true;
+               }
+               if (DebugLvl >= 3)
                {
+                   DebugPrintQuery = DebugLvl;
+               }
+               if (DebugLvl >= 4)
+               {
                    DebugPrintParse = true;
                    DebugPrintPlan = true;
                    DebugPrintRewrittenParsetree = true;
@@ -1061,7 +1093,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
 
            case 'K':
 #ifdef LOCK_MGR_DEBUG
-               lockDebug = atoi(optarg);
+               LockDebug = atoi(optarg);
 #else
                fprintf(stderr, "Lock debug not compiled in\n");
 #endif
@@ -1122,6 +1154,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
                 * ----------------
                 */
                flagQ = true;
+               Verbose = 0;
                break;
 
            case 'S':
@@ -1147,6 +1180,10 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
                StatFp = stderr;
                break;
 
+           case 'T':
+               parse_options(optarg);
+               break;
+
            case 't':
                /* ----------------
                 *  tell postgres to report usage statistics (timings) for
@@ -1278,47 +1315,79 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
    }
 
    Noversion = flagC;
-   Quiet = flagQ;
    EchoQuery = flagE;
    EuroDates = flagEu;
 
+   /*
+    * Find remote host name or address.
+    */
+   if (IsUnderPostmaster) {
+       switch (MyProcPort->raddr.sa.sa_family) {
+           struct hostent *host_ent;
+
+           case AF_INET:
+               remote_info = remote_host = malloc(48);
+               remote_port = ntohs(MyProcPort->raddr.in.sin_port);
+               strcpy(remote_host, inet_ntoa(MyProcPort->raddr.in.sin_addr));
+               if (HostnameLookup) {
+                   host_ent = \
+                       gethostbyaddr((char *)&MyProcPort->raddr.in.sin_addr,
+                                     sizeof(MyProcPort->raddr.in.sin_addr),
+                                     AF_INET);
+                   if (host_ent) {
+                       strncpy(remote_host, host_ent->h_name, 48);
+                       *(remote_host+47) = '\0';
+                   }
+               }
+               if (ShowPortNumber) {
+                   remote_info = malloc(strlen(remote_host)+6);
+                   sprintf(remote_info, "%s:%d", remote_host, remote_port);
+               }
+               break;
+           case AF_UNIX:
+               remote_info = remote_host = "localhost";
+               break;
+           default:
+               remote_info = remote_host = "unknown";
+               break;
+       }
+   }
+
    /* ----------------
-    *  print flags
+    *  set process params for ps
     * ----------------
     */
-   if (!Quiet)
-   {
-       puts("\t---debug info---");
-       printf("\tQuiet =        %c\n", Quiet ? 't' : 'f');
-       printf("\tNoversion =    %c\n", Noversion ? 't' : 'f');
-       printf("\ttimings   =    %c\n", ShowStats ? 't' : 'f');
-       printf("\tdates     =    %s\n", EuroDates ? "European" : "Normal");
-       printf("\tbufsize   =    %d\n", NBuffers);
-       printf("\tsortmem   =    %d\n", SortMem);
-
-       printf("\tquery echo =   %c\n", EchoQuery ? 't' : 'f');
-       printf("\tDatabaseName = [%s]\n", DBName);
-       puts("\t----------------\n");
+   if (IsUnderPostmaster) {
+       PS_INIT_STATUS(real_argc, real_argv, argv[0], 
+                      remote_info, userName, DBName);
+       PS_SET_STATUS("idle");
    }
 
    /* ----------------
-    *  set process params for ps
+    *  print flags
     * ----------------
     */
-   if (IsUnderPostmaster)
+   if (Verbose)
    {
-       int i;
-
-       Assert(real_argc >= 4);
-       real_argv[1] = userName;
-       real_argv[2] = DBName;
-       ps_status = (const char **)&real_argv[3];
-       *ps_status = "idle";
-       for (i = 4; i < real_argc; i++)
-           real_argv[i] = "";  /* blank them */
+       if (Verbose == 1) {
+           TPRINTF(TRACE_VERBOSE, "started: host=%s user=%s database=%s",
+                   remote_host, userName, DBName);
+       } else {
+           TPRINTF(TRACE_VERBOSE, "debug info:");
+           TPRINTF(TRACE_VERBOSE, "\tUser         = %s", userName);
+           TPRINTF(TRACE_VERBOSE, "\tRemoteHost   = %s", remote_host);
+           TPRINTF(TRACE_VERBOSE, "\tRemotePort   = %d", remote_port);
+           TPRINTF(TRACE_VERBOSE, "\tDatabaseName = %s", DBName);
+           TPRINTF(TRACE_VERBOSE, "\tVerbose      = %d", Verbose);
+           TPRINTF(TRACE_VERBOSE, "\tNoversion    = %c", Noversion ? 't' : 'f');
+           TPRINTF(TRACE_VERBOSE, "\ttimings      = %c", ShowStats ? 't' : 'f');
+           TPRINTF(TRACE_VERBOSE, "\tdates        = %s",
+                   EuroDates ? "European" : "Normal");
+           TPRINTF(TRACE_VERBOSE, "\tbufsize      = %d", NBuffers);
+           TPRINTF(TRACE_VERBOSE, "\tsortmem      = %d", SortMem);
+           TPRINTF(TRACE_VERBOSE, "\tquery echo   = %c", EchoQuery ? 't' : 'f');
+       }
    }
-   /* we just put a dummy here so we don't have to test everywhere */
-   else    ps_status = malloc(sizeof(char *));
 
    /* ----------------
     *  initialize portal file descriptors
@@ -1341,19 +1410,19 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
    SetProcessingMode(InitProcessing);
 
    /* initialize */
-   if (!Quiet)
-       puts("\tInitPostgres()..");
+   if (Verbose)
+       TPRINTF(TRACE_VERBOSE, "InitPostgres");
 
    InitPostgres(DBName);
 
 #ifdef MULTIBYTE
    /* set default client encoding */
-   if (!Quiet)
+   if (Verbose)
    {
        puts("\treset_client_encoding()..");
    }
    reset_client_encoding();
-   if (!Quiet)
+   if (Verbose)
    {
        puts("\treset_client_encoding() done.");
    }
@@ -1366,7 +1435,15 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
     * ----------------
     */
 
-   pqsignal(SIGINT, QueryCancelHandler);
+   pqsignal(SIGHUP,  read_pg_options);     /* upate pg_options from file */
+   pqsignal(SIGINT,  QueryCancelHandler);  /* cancel current query */
+   pqsignal(SIGQUIT, handle_warn);         /* handle error */
+   pqsignal(SIGTERM, die);
+   pqsignal(SIGPIPE, die);
+   pqsignal(SIGUSR1, quickdie);
+   pqsignal(SIGUSR2, Async_NotifyHandler); /* flush also sinval cache */
+   pqsignal(SIGCHLD, SIG_IGN);             /* ignored, sent by LockOwners */
+   pqsignal(SIGFPE,  FloatExceptionHandler);
 
    if (whereToSendOutput == Remote &&
        PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
@@ -1384,21 +1461,19 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
     *  so that the slaves signal the master to abort the transaction
     *  rather than calling AbortCurrentTransaction() themselves.
     *
-    *  Note:  elog(ERROR) causes a kill(getpid(), SIGHUP) to occur sending
-    *         us back here.
+    *  Note:  elog(ERROR) causes a kill(getpid(),SIGQUIT) to occur
+    *         sending us back here.
     * ----------------
     */
 
-   pqsignal(SIGHUP, handle_warn);
-
    if (sigsetjmp(Warn_restart, 1) != 0)
    {
        InError = true;
 
        time(&tim);
 
-       if (!Quiet)
-           printf("\tAbortCurrentTransaction() at %s\n", ctime(&tim));
+       if (Verbose)
+           TPRINTF(TRACE_VERBOSE, "AbortCurrentTransaction");
 
        MemSet(parser_input, 0, MAX_PARSE_BUFFER);
 
@@ -1415,7 +1490,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
    if (!IsUnderPostmaster)
    {
        puts("\nPOSTGRES backend interactive interface");
-       puts("$Revision: 1.85 $ $Date: 1998/08/25 21:04:38 $");
+       puts("$Revision: 1.86 $ $Date: 1998/08/25 21:34:04 $");
    }
 
    /* ----------------
@@ -1457,15 +1532,14 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
                IsEmptyQuery = false;
 
                /* start an xact for this function invocation */
-               if (!Quiet)
+               if (Verbose)
                {
-                   time(&tim);
-                   printf("\tStartTransactionCommand() at %s\n", ctime(&tim));
+                   TPRINTF(TRACE_VERBOSE, "StartTransactionCommand");
                }
 
                StartTransactionCommand();
                HandleFunctionRequest();
-               *ps_status = "idle";
+               PS_SET_STATUS("idle");
                break;
 
                /* ----------------
@@ -1495,16 +1569,15 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
                        ResetUsage();
 
                    /* start an xact for this query */
-                   if (!Quiet)
+                   if (Verbose)
                    {
-                       time(&tim);
-                       printf("\tStartTransactionCommand() at %s\n", ctime(&tim));
+                       TPRINTF(TRACE_VERBOSE, "StartTransactionCommand");
                    }
                    StartTransactionCommand();
 
                    pg_exec_query(parser_input);
 
-                   *ps_status = "idle";
+                   PS_SET_STATUS("idle");
 
                    if (ShowStats)
                        ShowUsage();
@@ -1533,12 +1606,13 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
         */
        if (!IsEmptyQuery)
        {
-           if (!Quiet)
+           if (Verbose)
            {
-               time(&tim);
-               printf("\tCommitTransactionCommand() at %s\n", ctime(&tim));
+               TPRINTF(TRACE_VERBOSE, "CommitTransactionCommand");
            }
+           PS_SET_STATUS("commit");
            CommitTransactionCommand();
+           PS_SET_STATUS("idle");
 
        }
        else
index 60b913474dddac103e5d3fb0258bc9913c3fa0c5..af36729582822003c40f1639fd702dc94faebd72 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/error/assert.c,v 1.9 1998/06/18 16:35:38 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/error/assert.c,v 1.10 1998/08/25 21:34:06 scrappy Exp $
  *
  * NOTE
  *   This should eventually work with elog(), dlog(), etc.
@@ -21,6 +21,7 @@
 #include "utils/module.h"
 
 #include "utils/exc.h"
+#include "utils/trace.h"
 
 int
 ExceptionalCondition(char *conditionName,
@@ -39,7 +40,7 @@ ExceptionalCondition(char *conditionName,
        || !PointerIsValid(fileName)
        || !PointerIsValid(exceptionP))
    {
-       fprintf(stderr, "ExceptionalCondition: bad arguments\n");
+       EPRINTF("TRAP: ExceptionalCondition: bad arguments\n");
 
        ExcAbort(exceptionP,
                 (ExcDetail) detail,
@@ -48,9 +49,9 @@ ExceptionalCondition(char *conditionName,
    }
    else
    {
-       fprintf(stderr,
-               "%s(\"%s:%s\", File: \"%s\", Line: %d)\n",
-       exceptionP->message, conditionName, detail == NULL ? "" : detail,
+       EPRINTF("TRAP: %s(\"%s:%s\", File: \"%s\", Line: %d)\n",
+               exceptionP->message, conditionName, 
+               (detail == NULL ? "" : detail),
                fileName, lineNumber);
    }
 
index 066af0e6d45b5a93e3234974ffae5dc6c1dbc588..97a90bcbb172b11d77c36ed13e724291900bc61a 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.31 1998/07/07 22:00:31 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.32 1998/08/25 21:34:08 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include <unistd.h>
 #include <signal.h>
 
+#ifdef USE_SYSLOG
+#include <syslog.h>
+#endif
+
 #include "postgres.h"
 #include "miscadmin.h"
 #include "libpq/libpq.h"
 #include "storage/proc.h"
+#include "utils/trace.h"
+
+#ifdef USE_SYSLOG
+/*
+ * Global option to control the use of syslog(3) for logging:
+ *
+ *     0   stdout/stderr only
+ *     1   stdout/stderr + syslog
+ *     2   syslog only
+ */
+#define UseSyslog pg_options[OPT_SYSLOG]
+#define PG_LOG_FACILITY    LOG_LOCAL0
+#else
+#define UseSyslog 0
+#endif
 
 static int Debugfile = -1;
 static int Err_file = -1;
@@ -52,12 +71,12 @@ elog(int lev, const char *fmt,...)
 
 #ifndef PG_STANDALONE
    extern FILE *Pfout;
+#endif
 
-#endif                         /* !PG_STANDALONE */
-#ifdef ELOG_TIMESTAMPS
-   time_t      tim;
-
+#ifdef USE_SYSLOG
+   int         log_level;
 #endif
+
    int         len;
    int         i = 0;
 
@@ -72,7 +91,7 @@ elog(int lev, const char *fmt,...)
                i = 0;
            if (i > 30)
                i = i % 30;
-           cp = "DEBUG:  ";
+           cp = "DEBUG: ";
            break;
        case DEBUG:
            i = ElogDebugIndentLevel;
@@ -80,27 +99,25 @@ elog(int lev, const char *fmt,...)
                i = 0;
            if (i > 30)
                i = i % 30;
-           cp = "DEBUG:  ";
+           cp = "DEBUG: ";
            break;
        case NOTICE:
-           cp = "NOTICE:  ";
+           cp = "NOTICE: ";
            break;
        case ERROR:
-           cp = "ERROR:  ";
+           cp = "ERROR: ";
            break;
        default:
-           sprintf(line, "FATAL %d:  ", lev);
+           sprintf(line, "FATAL %d: ", lev);
            cp = line;
    }
 #ifdef ELOG_TIMESTAMPS
-   time(&tim);
-   strcat(strcpy(buf, cp), ctime(&tim) + 4);
-   bp = buf + strlen(buf) - 6;
-   *bp++ = ':';
+   strcpy(buf, tprintf_timestamp());
+   strcat(buf, cp);
 #else
    strcpy(buf, cp);
-   bp = buf + strlen(buf);
 #endif
+   bp = buf + strlen(buf);
    while (i-- > 0)
        *bp++ = ' ';
    for (cp = fmt; *cp; cp++)
@@ -118,8 +135,31 @@ elog(int lev, const char *fmt,...)
    *bp = '\0';
    vsprintf(line, buf, ap);
    va_end(ap);
+
+#ifdef USE_SYSLOG
+   switch (lev) {
+   case NOIND:
+       log_level = LOG_DEBUG;
+       break;
+   case DEBUG:
+       log_level = LOG_DEBUG;
+       break;
+   case NOTICE:
+       log_level = LOG_NOTICE;
+       break;
+   case ERROR:
+       log_level = LOG_WARNING;
+       break;
+   case FATAL:
+   default:
+       log_level = LOG_ERR;
+       break;
+   }
+   write_syslog(log_level, line+TIMESTAMP_SIZE);
+#endif
+
    len = strlen(strcat(line, "\n"));
-   if (Debugfile > -1)
+   if ((Debugfile > -1) && (UseSyslog <= 1))
        write(Debugfile, line, len);
    if (lev == DEBUG || lev == NOIND)
        return;
@@ -135,7 +175,7 @@ elog(int lev, const char *fmt,...)
     * log.  This is a major pain.
     */
 
-   if (Err_file > -1 && Debugfile != Err_file)
+   if (Err_file > -1 && Debugfile != Err_file && (UseSyslog <= 1))
    {
        if (write(Err_file, line, len) < 0)
        {
@@ -157,7 +197,7 @@ elog(int lev, const char *fmt,...)
        else
            pq_putnchar("E", 1);
        /* pq_putint(-101, 4); *//* should be query id */
-       pq_putstr(line);
+       pq_putstr(line+TIMESTAMP_SIZE);     /* don't show timestamps */
        pq_flush();
    }
    if (Pfout == NULL)
@@ -178,7 +218,7 @@ elog(int lev, const char *fmt,...)
        ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */
        if (!InError)
        {
-           kill(MyProcPid, SIGHUP); /* abort to traffic cop */
+           kill(MyProcPid, SIGQUIT); /* abort to traffic cop */
            pause();
        }
 
index 737ff7036fadb9d29ae1f05fc223bcf78f6b793a..dc54a2cc66ca4ef484240c96cf2f258cda79058a 100644 (file)
@@ -4,7 +4,7 @@
 #    Makefile for utils/misc
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/backend/utils/misc/Makefile,v 1.8 1998/07/26 04:31:06 scrappy Exp $
+#    $Header: /cvsroot/pgsql/src/backend/utils/misc/Makefile,v 1.9 1998/08/25 21:34:10 scrappy Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -17,7 +17,7 @@ ifdef MULTIBYTE
 CFLAGS+= $(MBFLAGS)
 endif
 
-OBJS = database.o superuser.o 
+OBJS = database.o superuser.o trace.o 
 
 all: SUBSYS.o