From 7414d619507ed9e2cdb5113ff77df55feef786c4 Mon Sep 17 00:00:00 2001 From: "Marc G. Fournier" <scrappy@hub.org> Date: Tue, 25 Aug 1998 21:34:10 +0000 Subject: [PATCH] From: Massimo Dal Zotto <dz@cs.unitn.it> > 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 | 6 +- src/backend/access/nbtree/nbtsort.c | 6 +- src/backend/postmaster/postmaster.c | 121 +++++++++++-- src/backend/storage/ipc/ipc.c | 79 +++++--- src/backend/storage/ipc/spin.c | 41 +++-- src/backend/tcop/postgres.c | 268 ++++++++++++++++++---------- src/backend/utils/error/assert.c | 11 +- src/backend/utils/error/elog.c | 78 ++++++-- src/backend/utils/misc/Makefile | 4 +- 9 files changed, 428 insertions(+), 186 deletions(-) diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 406cd467735..582988c1b07 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -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 diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index 12effb71eb4..404653f8e9c 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -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); diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 0525282fd50..6ef32523e79 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -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]) diff --git a/src/backend/storage/ipc/ipc.c b/src/backend/storage/ipc/ipc.c index debe3e5658c..a9c56cf728f 100644 --- a/src/backend/storage/ipc/ipc.c +++ b/src/backend/storage/ipc/ipc.c @@ -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); } diff --git a/src/backend/storage/ipc/spin.c b/src/backend/storage/ipc/spin.c index 40735a8786a..7f8986e411a 100644 --- a/src/backend/storage/ipc/spin.c +++ b/src/backend/storage/ipc/spin.c @@ -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 } diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 838f4756d2a..5ad49c8ac4e 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -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" @@ -83,27 +86,43 @@ #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 diff --git a/src/backend/utils/error/assert.c b/src/backend/utils/error/assert.c index 60b913474dd..af367295828 100644 --- a/src/backend/utils/error/assert.c +++ b/src/backend/utils/error/assert.c @@ -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); } diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 066af0e6d45..97a90bcbb17 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -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 $ * *------------------------------------------------------------------------- */ @@ -24,10 +24,29 @@ #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(); } diff --git a/src/backend/utils/misc/Makefile b/src/backend/utils/misc/Makefile index 737ff7036fa..dc54a2cc66c 100644 --- a/src/backend/utils/misc/Makefile +++ b/src/backend/utils/misc/Makefile @@ -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 -- GitLab