Commit 6a68f426 authored by Peter Eisentraut's avatar Peter Eisentraut

The heralded `Grand Unified Configuration scheme' (GUC)

That means you can now set your options in either or all of $PGDATA/configuration,
some postmaster option (--enable-fsync=off), or set a SET command. The list of
options is in backend/utils/misc/guc.c, documentation will be written post haste.

pg_options is gone, so is that pq_geqo config file. Also removed were backend -K,
-Q, and -T options (no longer applicable, although -d0 does the same as -Q).

Added to configure an --enable-syslog option.

changed all callers from TPRINTF to elog(DEBUG)
parent 5e4d554b
......@@ -34,7 +34,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/Makefile,v 1.51 2000/05/30 16:36:14 momjian Exp $
# $Header: /cvsroot/pgsql/src/backend/Makefile,v 1.52 2000/05/31 00:28:13 petere Exp $
#
#-------------------------------------------------------------------------
......@@ -205,9 +205,7 @@ endif
install-templates: $(TEMPLATEDIR) \
global1.bki.source local1_template1.bki.source \
global1.description local1_template1.description \
libpq/pg_hba.conf.sample libpq/pg_ident.conf.sample \
optimizer/geqo/pg_geqo.sample \
pg_options.sample
libpq/pg_hba.conf.sample libpq/pg_ident.conf.sample
$(INSTALL) $(INSTLOPTS) global1.bki.source \
$(TEMPLATEDIR)/global1.bki.source
$(INSTALL) $(INSTLOPTS) global1.description \
......@@ -220,10 +218,6 @@ install-templates: $(TEMPLATEDIR) \
$(TEMPLATEDIR)/pg_hba.conf.sample
$(INSTALL) $(INSTLOPTS) libpq/pg_ident.conf.sample \
$(TEMPLATEDIR)/pg_ident.conf.sample
$(INSTALL) $(INSTLOPTS) optimizer/geqo/pg_geqo.sample \
$(TEMPLATEDIR)/pg_geqo.sample
$(INSTALL) $(INSTLOPTS) pg_options.sample \
$(TEMPLATEDIR)/pg_options.sample
install-headers: prebuildheaders $(SRCDIR)/include/config.h
-@if [ ! -d $(HEADERDIR) ]; then mkdir $(HEADERDIR); fi
......
......@@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.54 2000/04/12 17:14:49 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.55 2000/05/31 00:28:14 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -25,11 +25,8 @@
#include "catalog/index.h"
#include "executor/executor.h"
#include "miscadmin.h"
#ifdef BTREE_BUILD_STATS
#define ShowExecutorStats pg_options[TRACE_EXECUTORSTATS]
#endif
#include "tcop/tcopprot.h"
#include "utils/guc.h"
bool BuildingBtree = false; /* see comment in btbuild() */
bool FastBuild = true; /* use sort/build instead of insertion
......@@ -96,9 +93,9 @@ btbuild(Relation heap,
usefast = (FastBuild && IsNormalProcessingMode());
#ifdef BTREE_BUILD_STATS
if (ShowExecutorStats)
if (Show_btree_build_stats)
ResetUsage();
#endif
#endif /* BTREE_BUILD_STATS */
/* see if index is unique */
isunique = IndexIsUniqueNoCache(RelationGetRelid(index));
......@@ -287,13 +284,13 @@ btbuild(Relation heap,
}
#ifdef BTREE_BUILD_STATS
if (ShowExecutorStats)
if (Show_btree_build_stats)
{
fprintf(stderr, "! BtreeBuild Stats:\n");
fprintf(stderr, "BTREE BUILD STATS\n");
ShowUsage();
ResetUsage();
}
#endif
#endif /* BTREE_BUILD_STATS */
/*
* Since we just counted the tuples in the heap, we update its stats
......
......@@ -28,7 +28,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.52 2000/04/12 17:14:49 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.53 2000/05/31 00:28:14 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -36,13 +36,11 @@
#include "postgres.h"
#include "access/nbtree.h"
#include "tcop/tcopprot.h"
#include "utils/guc.h"
#include "utils/tuplesort.h"
#ifdef BTREE_BUILD_STATS
#define ShowExecutorStats pg_options[TRACE_EXECUTORSTATS]
#endif
/*
* turn on debugging output.
*
......@@ -136,13 +134,13 @@ void
_bt_leafbuild(BTSpool *btspool)
{
#ifdef BTREE_BUILD_STATS
if (ShowExecutorStats)
if (Show_btree_build_stats)
{
fprintf(stderr, "! BtreeBuild (Spool) Stats:\n");
fprintf(StatFp, "BTREE BUILD (Spool) STATISTICS\n");
ShowUsage();
ResetUsage();
}
#endif
#endif /* BTREE_BUILD_STATS */
tuplesort_performsort(btspool->sortstate);
_bt_load(btspool->index, btspool);
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.83 2000/05/30 04:24:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.84 2000/05/31 00:28:14 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -267,7 +267,7 @@ BootstrapMain(int argc, char *argv[])
Noversion = true;
break;
case 'F':
disableFsync = true;
enableFsync = false;
break;
case 'Q':
Quiet = true;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.61 2000/05/28 17:55:54 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.62 2000/05/31 00:28:15 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -90,7 +90,7 @@
#include "utils/fmgroids.h"
#include "utils/ps_status.h"
#include "utils/syscache.h"
#include "utils/trace.h"
/* stuff that we really ought not be touching directly :-( */
extern TransactionState CurrentTransactionState;
......@@ -128,6 +128,8 @@ static void NotifyMyFrontEnd(char *relname, int32 listenerPID);
static int AsyncExistsPendingNotify(char *relname);
static void ClearPendingNotifies(void);
bool Trace_notify = false;
/*
*--------------------------------------------------------------
......@@ -149,7 +151,8 @@ Async_Notify(char *relname)
{
char *notifyName;
TPRINTF(TRACE_NOTIFY, "Async_Notify: %s", relname);
if (Trace_notify)
elog(DEBUG, "Async_Notify: %s", relname);
if (!pendingNotifies)
pendingNotifies = DLNewList();
......@@ -202,7 +205,8 @@ Async_Listen(char *relname, int pid)
int alreadyListener = 0;
TupleDesc tupDesc;
TPRINTF(TRACE_NOTIFY, "Async_Listen: %s", relname);
if (Trace_notify)
elog(DEBUG, "Async_Listen: %s", relname);
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
......@@ -304,7 +308,8 @@ Async_Unlisten(char *relname, int pid)
return;
}
TPRINTF(TRACE_NOTIFY, "Async_Unlisten %s", relname);
if (Trace_notify)
elog(DEBUG, "Async_Unlisten %s", relname);
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
/* Note we assume there can be only one matching tuple. */
......@@ -346,7 +351,8 @@ Async_UnlistenAll()
HeapTuple lTuple;
ScanKeyData key[1];
TPRINTF(TRACE_NOTIFY, "Async_UnlistenAll");
if (Trace_notify)
elog(DEBUG, "Async_UnlistenAll");
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
......@@ -452,7 +458,8 @@ AtCommit_Notify()
return;
}
TPRINTF(TRACE_NOTIFY, "AtCommit_Notify");
if (Trace_notify)
elog(DEBUG, "AtCommit_Notify");
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
......@@ -485,13 +492,16 @@ AtCommit_Notify()
* be bad for applications that ignore self-notify
* messages.
*/
TPRINTF(TRACE_NOTIFY, "AtCommit_Notify: notifying self");
if (Trace_notify)
elog(DEBUG, "AtCommit_Notify: notifying self");
NotifyMyFrontEnd(relname, listenerPID);
}
else
{
TPRINTF(TRACE_NOTIFY, "AtCommit_Notify: notifying pid %d",
listenerPID);
if (Trace_notify)
elog(DEBUG, "AtCommit_Notify: notifying pid %d", listenerPID);
/*
* If someone has already notified this listener, we don't
......@@ -551,7 +561,8 @@ AtCommit_Notify()
ClearPendingNotifies();
TPRINTF(TRACE_NOTIFY, "AtCommit_Notify: done");
if (Trace_notify)
elog(DEBUG, "AtCommit_Notify: done");
}
/*
......@@ -624,10 +635,13 @@ Async_NotifyHandler(SIGNAL_ARGS)
if (notifyInterruptOccurred)
{
/* Here, it is finally safe to do stuff. */
TPRINTF(TRACE_NOTIFY,
"Async_NotifyHandler: perform async notify");
if (Trace_notify)
elog(DEBUG, "Async_NotifyHandler: perform async notify");
ProcessIncomingNotify();
TPRINTF(TRACE_NOTIFY, "Async_NotifyHandler: done");
if (Trace_notify)
elog(DEBUG, "Async_NotifyHandler: done");
}
}
}
......@@ -693,10 +707,13 @@ EnableNotifyInterrupt(void)
notifyInterruptEnabled = 0;
if (notifyInterruptOccurred)
{
TPRINTF(TRACE_NOTIFY,
"EnableNotifyInterrupt: perform async notify");
if (Trace_notify)
elog(DEBUG, "EnableNotifyInterrupt: perform async notify");
ProcessIncomingNotify();
TPRINTF(TRACE_NOTIFY, "EnableNotifyInterrupt: done");
if (Trace_notify)
elog(DEBUG, "EnableNotifyInterrupt: done");
}
}
}
......@@ -751,7 +768,9 @@ ProcessIncomingNotify(void)
char *relname;
int32 sourcePID;
TPRINTF(TRACE_NOTIFY, "ProcessIncomingNotify");
if (Trace_notify)
elog(DEBUG, "ProcessIncomingNotify");
PS_SET_STATUS("async_notify");
notifyInterruptOccurred = 0;
......@@ -784,8 +803,11 @@ ProcessIncomingNotify(void)
d = heap_getattr(lTuple, Anum_pg_listener_relname, tdesc, &isnull);
relname = (char *) DatumGetPointer(d);
/* Notify the frontend */
TPRINTF(TRACE_NOTIFY, "ProcessIncomingNotify: received %s from %d",
if (Trace_notify)
elog(DEBUG, "ProcessIncomingNotify: received %s from %d",
relname, (int) sourcePID);
NotifyMyFrontEnd(relname, sourcePID);
/* Rewrite the tuple with 0 in notification column */
rTuple = heap_modifytuple(lTuple, lRel, value, nulls, repl);
......@@ -820,7 +842,9 @@ ProcessIncomingNotify(void)
pq_flush();
PS_SET_STATUS("idle");
TPRINTF(TRACE_NOTIFY, "ProcessIncomingNotify: done");
if (Trace_notify)
elog(DEBUG, "ProcessIncomingNotify: done");
}
/* Send NOTIFY message to my front end. */
......
This diff is collapsed.
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: nodeHash.c,v 1.45 2000/04/18 05:43:01 tgl Exp $
* $Id: nodeHash.c,v 1.46 2000/05/31 00:28:17 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -27,10 +27,9 @@
#include "executor/executor.h"
#include "executor/nodeHash.h"
#include "executor/nodeHashjoin.h"
#include "miscadmin.h"
#include "utils/portal.h"
extern int SortMem;
static int hashFunc(Datum key, int len, bool byVal);
/* ----------------------------------------------------------------
......
......@@ -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.92 2000/05/26 01:26:19 tgl Exp $
* $Id: pqcomm.c,v 1.93 2000/05/31 00:28:18 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -75,7 +75,6 @@
#include "postgres.h"
#include "libpq/libpq.h"
#include "utils/trace.h" /* needed for HAVE_FCNTL_SETLK */
#include "miscadmin.h"
......@@ -130,7 +129,7 @@ pq_getport(void)
if (envport)
return atoi(envport);
return atoi(DEF_PGPORT);
return DEF_PGPORT;
}
/* --------------------------------
......@@ -246,13 +245,8 @@ StreamServerPort(char *hostName, unsigned short portName, int *fdP)
lck.l_whence = SEEK_SET;
lck.l_start = lck.l_len = 0;
lck.l_type = F_WRLCK;
if (fcntl(lock_fd, F_SETLK, &lck) == 0)
{
TPRINTF(TRACE_VERBOSE, "flock on %s, deleting", sock_path);
if (fcntl(lock_fd, F_SETLK, &lck) != -1)
unlink(sock_path);
}
else
TPRINTF(TRACE_VERBOSE, "flock failed for %s", sock_path);
close(lock_fd);
}
#endif /* HAVE_FCNTL_SETLK */
......@@ -305,7 +299,7 @@ StreamServerPort(char *hostName, unsigned short portName, int *fdP)
lck.l_start = lck.l_len = 0;
lck.l_type = F_WRLCK;
if (fcntl(lock_fd, F_SETLK, &lck) != 0)
TPRINTF(TRACE_VERBOSE, "flock error for %s", sock_path);
elog(DEBUG, "flock error on %s: %s", sock_path, strerror(errno));
}
#endif /* HAVE_FCNTL_SETLK */
}
......
......@@ -5,7 +5,7 @@
#
# Copyright (c) 1994, Regents of the University of California
#
# $Id: Makefile,v 1.14 2000/05/29 05:44:48 tgl Exp $
# $Id: Makefile,v 1.15 2000/05/31 00:28:19 petere Exp $
#
#-------------------------------------------------------------------------
......@@ -17,7 +17,7 @@ CFLAGS+= -Wno-error
endif
OBJS = geqo_copy.o geqo_eval.o geqo_main.o geqo_misc.o \
geqo_params.o geqo_pool.o geqo_recombination.o \
geqo_pool.o geqo_recombination.o \
geqo_selection.o \
geqo_erx.o geqo_pmx.o geqo_cx.o geqo_px.o geqo_ox1.o geqo_ox2.o
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: geqo_main.c,v 1.20 2000/01/26 05:56:33 momjian Exp $
* $Id: geqo_main.c,v 1.21 2000/05/31 00:28:19 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -23,12 +23,30 @@
/* -- parts of this are adapted from D. Whitley's Genitor algorithm -- */
#include "postgres.h"
#include <time.h>
#include <math.h>
#include "optimizer/geqo.h"
#include "optimizer/geqo_misc.h"
#include "optimizer/geqo_pool.h"
#include "optimizer/geqo_selection.h"
/*
* Configuration options
*/
int Geqo_pool_size;
int Geqo_effort;
int Geqo_generations;
double Geqo_selection_bias;
int Geqo_random_seed;
static int gimme_pool_size(int nr_rel);
static int gimme_number_generations(int pool_size, int effort);
/* define edge recombination crossover [ERX] per default */
#if !defined(ERX) && \
!defined(PMX) && \
......@@ -81,13 +99,16 @@ geqo(Query *root)
number_of_rels = length(root->base_rel_list);
/* set GA parameters */
geqo_params(number_of_rels);/* read "$PGDATA/pg_geqo" file */
pool_size = PoolSize;
number_generations = Generations;
pool_size = gimme_pool_size(number_of_rels);
number_generations = gimme_number_generations(pool_size, Geqo_effort);
status_interval = 10;
/* seed random number generator */
srandom(RandomSeed);
/* XXX why is this done every time around? */
if (Geqo_random_seed >= 0)
srandom(Geqo_random_seed);
else
srandom(time(NULL));
/* initialize plan evaluator */
geqo_eval_startup();
......@@ -146,7 +167,7 @@ geqo(Query *root)
{
/* SELECTION */
geqo_selection(momma, daddy, pool, SelectionBias); /* using linear bias
geqo_selection(momma, daddy, pool, Geqo_selection_bias);/* using linear bias
* function */
......@@ -263,3 +284,52 @@ print_plan(best_plan, root);
return best_rel;
}
/*
* Return either configured pool size or
* a good default based on query size (no. of relations)
* = 2^(QS+1)
* also constrain between 128 and 1024
*/
static int
gimme_pool_size(int nr_rel)
{
double size;
if (Geqo_pool_size != 0)
{
if (Geqo_pool_size < MIN_GEQO_POOL_SIZE)
return MIN_GEQO_POOL_SIZE;
else if (Geqo_pool_size > MAX_GEQO_POOL_SIZE)
return MAX_GEQO_POOL_SIZE;
else
return Geqo_pool_size;
}
size = pow(2.0, nr_rel + 1.0);
if (size < MIN_GEQO_POOL_SIZE)
return MIN_GEQO_POOL_SIZE;
else if (size > MAX_GEQO_POOL_SIZE)
return MAX_GEQO_POOL_SIZE;
else
return (int) ceil(size);
}
/*
* Return either configured number of generations or
* some reasonable default calculated on the fly.
* = Effort * Log2(PoolSize)
*/
static int
gimme_number_generations(int pool_size, int effort)
{
if (Geqo_generations <= 0)
return effort * (int) ceil(log((double) pool_size) / log(2.0));
else
return Geqo_generations;
}
/*------------------------------------------------------------------------
*
* geqo_params.c
* routines for determining necessary genetic optimization parameters
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: geqo_params.c,v 1.22 2000/01/26 05:56:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
* Martin Utesch * Institute of Automatic Control *
= = University of Mining and Technology =
* utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
#include <time.h>
#include <math.h>
#include <ctype.h>
#include "postgres.h"
#include "miscadmin.h"
#include "nodes/pg_list.h"
#include "nodes/primnodes.h"
#include "nodes/relation.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
#include "optimizer/geqo.h"
#include "optimizer/geqo_gene.h"
#include "optimizer/internal.h"
#include "optimizer/pathnode.h"
#include "optimizer/paths.h"
#include "storage/fd.h"
/*
* Parameter values read from the config file (or defaulted) are stored here
* by geqo_params().
*/
int PoolSize;
int Generations;
long RandomSeed;
double SelectionBias;
#define POOL_TAG "Pool_Size"
#define TRIAL_TAG "Generations"
#define RAND_TAG "Random_Seed"
#define BIAS_TAG "Selection_Bias"
#define EFFORT_TAG "Effort"/* optimization effort and */
#define LOW "low" /* corresponding tags */
#define MEDIUM "medium"
#define HIGH "high"
#define MAX_TOKEN 80 /* Maximum size of one token in the *
* configuration file */
static int gimme_pool_size(int string_length);
static int gimme_number_generations(int pool_size, int effort);
static int next_token(FILE *, char *, int);
static double geqo_log(double x, double b);
/*
* geqo_param
* get ga parameters out of "$PGDATA/pg_geqo" file.
*/
void
geqo_params(int string_length)
{
int i;
char buf[MAX_TOKEN];
FILE *file;
char *conf_file;
/* these flag variables signal that a value has been set from the file */
int pool_size = 0;
int number_trials = 0;
int random_seed = 0;
int selection_bias = 0;
int effort = 0;
/* put together the full pathname to the config file */
conf_file = (char *) palloc((strlen(DataDir) + strlen(GEQO_FILE) + 2) * sizeof(char));
sprintf(conf_file, "%s/%s", DataDir, GEQO_FILE);
/* open the config file */
#ifndef __CYGWIN32__
file = AllocateFile(conf_file, "r");
#else
file = AllocateFile(conf_file, "rb");
#endif
if (file)
{
/*
* empty and comment line stuff
*/
while ((i = next_token(file, buf, sizeof(buf))) != EOF)
{
/* If only token on the line, ignore */
if (i == '\n')
continue;
/* Comment -- read until end of line then next line */
if (buf[0] == '#')
{
while (next_token(file, buf, sizeof(buf)) == 0);
continue;
}
/*
* get ga parameters by parsing
*/
/*------------------------------------------------- pool size */
if (strcmp(buf, POOL_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf)); /* get next token */
if (i != EOF) /* only ignore if we got no text at all */
{
if (sscanf(buf, "%d", &PoolSize) == 1)
pool_size = 1;
}
}
/*------------------------------------------------- number of trials */
else if (strcmp(buf, TRIAL_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf));
if (i != EOF)
{
if (sscanf(buf, "%d", &Generations) == 1)
number_trials = 1;
}
}
/*------------------------------------------------- optimization effort */
else if (strcmp(buf, EFFORT_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf));
if (i != EOF)
{
if (strcmp(buf, LOW) == 0)
effort = LOW_EFFORT;
else if (strcmp(buf, MEDIUM) == 0)
effort = MEDIUM_EFFORT;
else if (strcmp(buf, HIGH) == 0)
effort = HIGH_EFFORT;
/* undocumented extension: specify effort numerically */
else if (isdigit(buf[0]))
effort = atoi(buf);
}
}
/*------------------------------------------- random seed */
else if (strcmp(buf, RAND_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf));
if (i != EOF)
{
if (sscanf(buf, "%ld", &RandomSeed) == 1)
random_seed = 1;
}
}
/*------------------------------------------- selection bias */
else if (strcmp(buf, BIAS_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf));
if (i != EOF)
{
if (sscanf(buf, "%lf", &SelectionBias) == 1)
selection_bias = 1;
}
}
/* unrecognized tags */
else
{
if (i != EOF)
{
}
elog(DEBUG, "geqo_params: unknown parameter type \"%s\"\nin file \'%s\'", buf, conf_file);
/* if not at end-of-line, keep reading til we are */
while (i == 0)
i = next_token(file, buf, sizeof(buf));
}
}
FreeFile(file);
pfree(conf_file);
}
else
elog(DEBUG, "geqo_params: ga parameter file\n\'%s\'\ndoes not exist or permissions are not setup correctly", conf_file);
/*
* parameter checkings follow
*/
/**************** PoolSize: essential ****************/
if (!(pool_size))
{
PoolSize = gimme_pool_size(string_length);
elog(DEBUG, "geqo_params: no pool size specified;\nusing computed value of %d", PoolSize);
}
/**************** Effort: essential ****************/
if (!(effort))
{
effort = MEDIUM_EFFORT;
elog(DEBUG, "geqo_params: no optimization effort specified;\nusing value of %d", effort);
}
/**************** Generations: essential ****************/
if (!(number_trials))
{
Generations = gimme_number_generations(PoolSize, effort);
elog(DEBUG, "geqo_params: no number of trials specified;\nusing computed value of %d", Generations);
}
/* RandomSeed: */
if (!(random_seed))
{
RandomSeed = (long) time(NULL);
elog(DEBUG, "geqo_params: no random seed specified;\nusing computed value of %ld", RandomSeed);
}
/* SelectionBias: */
if (!(selection_bias))
{
SelectionBias = SELECTION_BIAS;
elog(DEBUG, "geqo_params: no selection bias specified;\nusing default value of %f", SelectionBias);
}
}
/*
* Grab one token out of fp. Defined as the next string of non-whitespace
* in the file. After we get the token, continue reading until EOF, end of
* line or the next token. If it's the last token on the line, return '\n'
* for the value. If we get EOF before reading a token, return EOF. In all
* other cases return 0.
*/
static int
next_token(FILE *fp, char *buf, int bufsz)
{
int c;
char *eb = buf + (bufsz - 1);
/* Discard inital whitespace */
while (isspace(c = getc(fp)));
/* EOF seen before any token so return EOF */
if (c == EOF)
return -1;
/* Form a token in buf */
do
{
if (buf < eb)
*buf++ = c;
c = getc(fp);
} while (!isspace(c) && c != EOF);
*buf = '\0';
/* Discard trailing tabs and spaces */
while (c == ' ' || c == '\t')
c = getc(fp);
/* Put back the char that was non-whitespace (putting back EOF is ok) */
ungetc(c, fp);
/* If we ended with a newline, return that, otherwise return 0 */
return c == '\n' ? '\n' : 0;
}
/* gimme_pool_size
* compute good estimation for pool size
* according to number of involved rels in a query
*/
static int
gimme_pool_size(int string_length)
{
double exponent;
double size;
exponent = (double) string_length + 1.0;
size = pow(2.0, exponent);
if (size < MIN_POOL)
return MIN_POOL;
else if (size > MAX_POOL)
return MAX_POOL;
else
return (int) ceil(size);
}
/* gimme_number_generations
* compute good estimation for number of generations size
* for convergence
*/
static int
gimme_number_generations(int pool_size, int effort)
{
int number_gens;
number_gens = (int) ceil(geqo_log((double) pool_size, 2.0));
return effort * number_gens;
}
static double
geqo_log(double x, double b)
{
return (log(x) / log(b));
}
#*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
# pg_geqo *
# ------- =
# *
# Example Genetic Algorithm config file =
# for the PostgreSQL *
# Genetic Query Optimization (GEQO) module =
# *
#*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
# Martin Utesch * Institute of Automatic Control *
# = University of Mining and Technology =
# utesch@aut.tu-freiberg.de * Freiberg, Germany *
#*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
# To make this file do something, copy it to '$PGDATA/pg_geqo'
# and edit parameters to taste.
# If '$PGDATA/pg_geqo' doesn't exist, the system will use default parameters.
# The file is re-read for every GEQO optimization, if it does exist.
# comment character is '#'
#
# separator between recognized tag and possible value
# must be white space
# QS: means query size, which is the number of relations
# contained in a query
#=================+===================+=============================+
# RECOGNIZED TAGS | POSSIBLE VALUES | DEFAULTS |
#=================+===================+=============================+
# 'Pool_Size' | positive int | 2^(QS+1), but not less than |
# | | 128 nor more than 1024. |
#-----------------+-------------------+-----------------------------+
# 'Effort' | [low,medium,high] | medium |
#-----------------+-------------------+-----------------------------+
# 'Generations' | positive int | Effort * log2(Pool_Size) |
#-----------------+-------------------+-----------------------------+
# 'Selection_Bias'| [1.50 .. 2.00] | 2.0 |
#-----------------+-------------------+-----------------------------+
# 'Random_Seed' | positive long | time(NULL) |
#=================+===================+=============================+
# 'Pool_Size' is essential for the genetic algorithm performance.
# It gives us the number of individuals within one population.
#
# 'Effort' 'low' means integer value of 1, 'medium' 40, and 'high' 80.
# Note: Effort is *only* used to derive a default value for Generations
# --- if you specify Generations then Effort does not matter.
#
# 'Generations' specifies the number of iterations in the genetic algorithm.
#
# GEQO runtime is roughly proportional to Pool_Size + Generations.
#
# 'Selection_Bias' gives us the selective pressure within the
# population.
#
# 'Random_Seed' is the random seed for the random() function.
# You don't have to set it. If you do set it, then successive GEQO
# runs will produce repeatable results, whereas if you don't set it
# there will be some randomness in the results...
# All parameters will be computed within the GEQO module when they
# are not set in the pg_geqo file.
# Example pg_geqo settings:
#
#Pool_Size 128
#Effort low
#Generations 200
#Random_Seed 830518260
#Selection_Bias 1.750000
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.61 2000/05/30 00:49:46 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.62 2000/05/31 00:28:22 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -21,15 +21,8 @@
#include "optimizer/paths.h"
#ifdef GEQO
bool enable_geqo = true;
#else
bool enable_geqo = false;
#endif
int geqo_rels = GEQO_RELS;
int geqo_rels = DEFAULT_GEQO_RELS;
static void set_base_rel_pathlist(Query *root);
......
......@@ -42,7 +42,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.60 2000/05/30 04:24:47 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.61 2000/05/31 00:28:22 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -63,11 +63,11 @@
#define LOG6(x) (log(x) / 1.79175946922805)
double effective_cache_size = DEFAULT_EFFECTIVE_CACHE_SIZE;
Cost random_page_cost = DEFAULT_RANDOM_PAGE_COST;
Cost cpu_tuple_cost = DEFAULT_CPU_TUPLE_COST;
Cost cpu_index_tuple_cost = DEFAULT_CPU_INDEX_TUPLE_COST;
Cost cpu_operator_cost = DEFAULT_CPU_OPERATOR_COST;
double effective_cache_size = DEFAULT_EFFECTIVE_CACHE_SIZE;
double random_page_cost = DEFAULT_RANDOM_PAGE_COST;
double cpu_tuple_cost = DEFAULT_CPU_TUPLE_COST;
double cpu_index_tuple_cost = DEFAULT_CPU_INDEX_TUPLE_COST;
double cpu_operator_cost = DEFAULT_CPU_OPERATOR_COST;
Cost disable_cost = 100000000.0;
......
......@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.168 2000/05/25 22:42:17 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.169 2000/05/31 00:28:24 petere Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
......@@ -323,7 +323,8 @@ static void doNegateFloat(Value *v);
IMMEDIATE, INITIALLY,
PENDANT,
RESTRICT,
TRIGGER
TRIGGER,
OFF
/* Keywords (in SQL92 non-reserved words) */
%token COMMITTED, SERIALIZABLE, TYPE_P
......@@ -715,67 +716,63 @@ opt_level: READ COMMITTED { $$ = "committed"; }
| SERIALIZABLE { $$ = "serializable"; }
;
var_value: Sconst
{
/* Plain old string (pointer to char) */
$$ = $1;
}
| FCONST
{
/* Floating numeric argument.
* This recently changed to preserve "stringiness",
* so we don't have any work to do at all. Nice.
* - thomas 2000-03-29
*/
$$ = $1;
}
| Iconst
{
char buf[64];
var_value: SCONST { $$ = $1; }
| ICONST
{
char buf[64];
sprintf(buf, "%d", $1);
$$ = pstrdup(buf);
}
| '-' ICONST
{
char buf[64];
sprintf(buf, "%d", -($2));
$$ = pstrdup(buf);
}
| FCONST { $$ = $1; }
| '-' FCONST
{
char * s = palloc(strlen($2)+2);
s[0] = '-';
strcpy(s + 1, $2);
$$ = s;
}
| TRUE_P { $$ = "true"; }
| FALSE_P { $$ = "false"; }
| ON { $$ = "on"; }
| OFF { $$ = "off"; }
/* Integer numeric argument.
*/
sprintf(buf, "%d", $1);
$$ = pstrdup(buf);
}
| name_list
{
List *n;
int slen = 0;
char *result;
| name_list
{
List *n;
int slen = 0;
char *result;
/* List of words? Then concatenate together */
if ($1 == NIL)
elog(ERROR, "SET must have at least one argument");
/* List of words? Then concatenate together */
if ($1 == NIL)
elog(ERROR, "SET must have at least one argument");
foreach (n, $1)
{
Value *p = (Value *) lfirst(n);
Assert(IsA(p, String));
/* keep track of room for string and trailing comma */
slen += (strlen(p->val.str) + 1);
}
result = palloc(slen + 1);
*result = '\0';
foreach (n, $1)
{
Value *p = (Value *) lfirst(n);
strcat(result, p->val.str);
strcat(result, ",");
}
/* remove the trailing comma from the last element */
*(result+strlen(result)-1) = '\0';
$$ = result;
}
/* "OFF" is not a token, so it is handled by the name_list production */
| ON
{
$$ = "on";
}
| DEFAULT
{
$$ = NULL;
}
foreach (n, $1)
{
Value *p = (Value *) lfirst(n);
Assert(IsA(p, String));
/* keep track of room for string and trailing comma */
slen += (strlen(p->val.str) + 1);
}
result = palloc(slen + 1);
*result = '\0';
foreach (n, $1)
{
Value *p = (Value *) lfirst(n);
strcat(result, p->val.str);
strcat(result, ",");
}
/* remove the trailing comma from the last element */
*(result+strlen(result)-1) = '\0';
$$ = result;
}
| DEFAULT { $$ = NULL; }
;
zone_value: Sconst { $$ = $1; }
......@@ -5534,6 +5531,7 @@ ColLabel: ColId { $$ = $1; }
| NULLIF { $$ = "nullif"; }
| NULL_P { $$ = "null"; }
| NUMERIC { $$ = "numeric"; }
| OFF { $$ = "off"; }
| OFFSET { $$ = "offset"; }
| ON { $$ = "on"; }
| OR { $$ = "or"; }
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.72 2000/05/29 05:44:54 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.73 2000/05/31 00:28:24 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -176,6 +176,7 @@ static ScanKeyword ScanKeywords[] = {
{"nullif", NULLIF},
{"numeric", NUMERIC},
{"of", OF},
{"off", OFF},
{"offset", OFFSET},
{"oids", OIDS},
{"old", CURRENT},
......
# pg_options file
# Documented for Debian release 7.0-0.beta4-1
# Copyright (c) Oliver Elphick <olly@lfix.co.uk>
# Licence: May be used without any payment or restriction, except that
# the copyright and licence must be preserved.
# pg_options controls certain options and tracing features of the
# PostgreSQL backend. It is read by postmaster and postgres before
# command line arguments are examined, so command line arguments
# will override any settings here.
# This file should be located at $PGDATA/pg_options. In Debian, this is
# a symbolic link to /etc/postgresql/pg_options.
# The capitalised words refer to the internal #defines in the source code
# which use these options. Options can be turned on and off while the
# postmaster is running by editing this file and sending a SIGHUP to
# the postmaster.
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# File format #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# option = integer : set option to the specified value
# option + : set option to 1
# option - : set option to 0
#
# Comments begin with #, whitespace is ignored completely.
# Options are separated by newlines (or by commas -- but why make it
# needlessly difficult to read the file?)
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Tracing options #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# all [TRACE_ALL]
# This governs what tracing occurs. If it is 0, tracing is
# controlled by the more specific options listed below. Set this to 1
# to trace everything, regardless of the settings below; set to -1 to
# turn off all tracing.
#
# Any of these tracing options can be turned on with the command line
# option `-T "option[,...]"'
all = 0
# verbose [TRACE_VERBOSE] -- command line option `-d n' with n >= 1
# Turns on verbose tracing of various events
verbose = 0
# query [TRACE_QUERY] -- command line option `-d n' with n >= 2
# Traces the query string before and after rewriting
query = 0
# plan [TRACE_PLAN] -- command line option `-d n' with n >= 4
# Traces plan trees in raw output format (see also pretty_plan)
plan = 0
# parse [TRACE_PARSE] -- command line option `-d n' with n >= 3
# Traces the parser output in raw form (see also pretty_parse)
parse = 0
# rewritten [TRACE_REWRITTEN]
# Traces the query after rewriting, in raw form (see also pretty_rewritten)
rewritten = 0
# pretty_plan [TRACE_PRETTY_PLAN]
# shows indented multiline versions of plan trees (see also plan)
pretty_plan = 0
# pretty_parse [TRACE_PRETTY_PARSE]
# Traces the parser output in a readable form (see also parse)
pretty_parse = 0
# pretty_rewritten [TRACE_PRETTY_REWRITTEN]
# -- command line option `-d n' with n >= 5
# Traces the query after rewriting, in a readable form (see also rewritten)
pretty_rewritten = 0
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Locks #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# TRACE_SHORTLOCKS
# This value is currently unused but needed as an index placeholder.
# It must be left set to 0, or mayhem may result, including segmentation
# violations, perhaps.
shortlocks = 0
# TRACE_LOCKS
# Enable or disable tracing of ordinary locks
locks = 0
# TRACE_USERLOCKS
# Enable or disable tracing of user (advisory) locks
userlocks = 0
# TRACE_SPINLOCKS
# Enables or disables tracing of spinlocks, but only if LOCKDEBUG was
# defined when PostgreSQL was compiled. (In the Debian release,
# LOCKDEBUG is not defined, so this option is inoperative.)
spinlocks = 0
# TRACE_LOCKOIDMIN
# This option is is used to avoid tracing locks on system relations, which
# would produce a lot of output. You should specify a value greater than
# the maximum oid of system relations, which can be found with the
# following query:
#
# select max(int4in(int4out(oid))) from pg_class where relname ~ '^pg_';
#
# To get a useful lock trace you can set the following pg_options:
#
# verbose+, query+, locks+, userlocks+, lock_debug_oidmin=17500
lock_debug_oidmin = 0
# TRACE_LOCKRELATION
# This option can be used to trace unconditionally a single relation,
# for example pg_listener, if you suspect there are locking problems.
lock_debug_relid = 0
# TRACE_NOTIFY
# Turn on tracing of asynchronous notifications from the backend.
notify = 0
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Memory Allocation #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# These do not appear to be used at 7.0beta4
# TRACE_MALLOC
malloc = 0
# TRACE_PALLOC
palloc = 0
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Statistics #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# The statistics options are not controlled by either TRACE_ALL, or
# by USE_SYSLOG. These options cannot be used togther with the
# command line option `-s'.
# TRACE_PARSERSTATS
# Prints parser statistics to standard error -- command line `-tpa[rser]'
parserstats = 0
# TRACE_PLANNERSTATS
# Prints planner statistics to standard error -- command line `-tpl[anner]'
plannerstats = 0
# TRACE_EXECUTORSTATS
# Prints executor statistics to standard error -- command line `-te[xecutor]'
executorstats = 0
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# options controlling run-time behaviour #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# OPT_LOCKREADPRIORITY
# lock priority, see lock.c -- Does not appear to be used
lock_read_priority = 0
# OPT_DEADLOCKTIMEOUT
# deadlock timeout; set this to a non-zero integer, which is the number
# of seconds that the backend should wait before deciding that it is in
# a deadlock and timing out. The system default is 1 second.
deadlock_timeout = 0
# nofsync [OPT_NOFSYNC] -- command line option `-F'
# If this is non-zero, fsync will be turned off; this means that saving
# to disk will be left to the normal operating system sync. If this
# option is zero, every transaction will trigger a sync to disk; this
# gives increased safety at the expense of performance.
nofsync = 0
# OPT_SYSLOG
# This controls the destination of [many] messages and traces:
# 0 : write to stdout or stderr
# 1 : write to stdout or stderr, and also through syslogd
# 2 : log only through syslogd
# [Not all messages have been converted to use routines controlled by
# this parameter; unconverted ones will print to stdout or stderr
# unconditionally and never to syslogd.]
syslog = 0
# OPT_HOSTLOOKUP
# enable hostname lookup in ps_status. If this is set, a reverse
# lookup will be done on the connecting IP address (for TCP/IP
# connections) for inclusion in the ps_status display.
hostlookup = 0
# OPT_SHOWPORTNUMBER
# show port number in ps_status. If this is set, the TCP port number
# will be included in the ps_status display (for TCP/IP connections).
showportnumber = 0
......@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.143 2000/05/26 01:38:08 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.144 2000/05/31 00:28:25 petere Exp $
*
* NOTES
*
......@@ -90,7 +90,7 @@
#include "storage/proc.h"
#include "access/xlog.h"
#include "tcop/tcopprot.h"
#include "utils/trace.h"
#include "utils/guc.h"
#include "version.h"
/*
......@@ -136,7 +136,7 @@ static Dllist *BackendList;
/* list of ports associated with still open, but incomplete connections */
static Dllist *PortList;
static unsigned short PostPortName = 0;
int PostPortName = DEF_PGPORT;
/*
* This is a boolean indicating that there is at least one backend that
......@@ -167,7 +167,7 @@ static IpcMemoryKey ipc_key;
* adding to this.
*/
static int MaxBackends = DEF_MAXBACKENDS;
int MaxBackends = DEF_MAXBACKENDS;
/*
* MaxBackends is the actual limit on the number of backends we will
......@@ -185,6 +185,9 @@ static int real_argc;
static time_t tnow;
/* flag to indicate that SIGHUP arrived during server loop */
static volatile bool got_SIGHUP = false;
/*
* Default Values
*/
......@@ -217,8 +220,7 @@ static char ExtraOptions[MAXPGPATH];
static bool Reinit = true;
static int SendStop = false;
static bool NetServer = false; /* if not zero, postmaster listen for
* non-local connections */
bool NetServer = false; /* listen on TCP/IP */
#ifdef USE_SSL
static bool SecureNetServer = false; /* if not zero, postmaster listens
......@@ -256,7 +258,8 @@ extern int optind,
static void pmdaemonize(char *extraoptions);
static Port *ConnCreate(int serverFd);
static void ConnFree(Port *port);
static void reset_shared(unsigned short port);
static void reset_shared(int port);
static void SIGHUP_handler(SIGNAL_ARGS);
static void pmdie(SIGNAL_ARGS);
static void reaper(SIGNAL_ARGS);
static void dumpstatus(SIGNAL_ARGS);
......@@ -368,7 +371,6 @@ checkDataDir(const char *DataDir, bool *DataDirOK)
int
PostmasterMain(int argc, char *argv[])
{
extern int NBuffers; /* from buffer/bufmgr.c */
int opt;
char *hostName;
int status;
......@@ -431,6 +433,8 @@ PostmasterMain(int argc, char *argv[])
*/
umask((mode_t) 0077);
ResetAllOptions();
if (!(hostName = getenv("PGHOST")))
{
if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
......@@ -441,9 +445,38 @@ PostmasterMain(int argc, char *argv[])
MyProcPid = getpid();
DataDir = getenv("PGDATA"); /* default value */
opterr = 0;
/*
* First we must scan for a -D argument to get the data dir. Then
* read the config file. Finally, scan all the other arguments.
* (Command line switches override config file.)
*
* Note: The two lists of options must be exactly the same, even
* though perhaps the first one would only have to be "D:" with
* opterr turned off. But some versions of getopt (notably GNU)
* are going to arbitrarily permute some "non-options" (according
* to the local world view) which will result in some switches
* being associated with the wrong argument. Death and destruction
* will occur.
*/
opterr = 1;
while ((opt = getopt(nonblank_argc, argv, "A:a:B:b:D:d:Film:MN:no:p:Ss-:")) != EOF)
{
if (opt == 'D')
DataDir = optarg;
}
optind = 1; /* start over */
checkDataDir(DataDir, &DataDirOK); /* issues error messages */
if (!DataDirOK)
{
fprintf(stderr, "No data directory -- can't proceed.\n");
exit(2);
}
ProcessConfigFile(PGC_POSTMASTER);
IgnoreSystemIndexes(false);
while ((opt = getopt(nonblank_argc, argv, "A:a:B:b:D:d:ilm:MN:no:p:Ss")) != EOF)
while ((opt = getopt(nonblank_argc, argv, "A:a:B:b:D:d:Film:MN:no:p:Ss-:")) != EOF)
{
switch (opt)
{
......@@ -464,15 +497,7 @@ PostmasterMain(int argc, char *argv[])
/* Can no longer set authentication method. */
break;
case 'B':
/*
* The number of buffers to create. Setting this option
* means we have to start each backend with a -B # to make
* sure they know how many buffers were allocated.
*/
NBuffers = atoi(optarg);
strcat(ExtraOptions, " -B ");
strcat(ExtraOptions, optarg);
break;
case 'b':
/* Set the backend executable file to use. */
......@@ -486,8 +511,7 @@ PostmasterMain(int argc, char *argv[])
}
break;
case 'D':
/* Set PGDATA from the command line. */
DataDir = optarg;
/* already done above */
break;
case 'd':
......@@ -496,8 +520,10 @@ PostmasterMain(int argc, char *argv[])
* servers descended from it.
*/
DebugLvl = atoi(optarg);
pg_options[TRACE_VERBOSE] = DebugLvl;
break;
case 'F':
enableFsync = false;
break;
case 'i':
NetServer = true;
break;
......@@ -545,7 +571,7 @@ PostmasterMain(int argc, char *argv[])
break;
case 'p':
/* Set PGPORT by hand. */
PostPortName = (unsigned short) atoi(optarg);
PostPortName = atoi(optarg);
break;
case 'S':
......@@ -567,6 +593,21 @@ PostmasterMain(int argc, char *argv[])
*/
SendStop = true;
break;
case '-':
{
/* A little 'long argument' simulation */
size_t equal_pos = strcspn(optarg, "=");
char *cp;
if (optarg[equal_pos] != '=')
elog(ERROR, "--%s requires argument", optarg);
optarg[equal_pos] = '\0';
for(cp = optarg; *cp; cp++)
if (*cp == '-')
*cp = '_';
SetConfigOption(optarg, optarg + equal_pos + 1, PGC_POSTMASTER);
break;
}
default:
/* usage() never returns */
usage(progname);
......@@ -574,11 +615,8 @@ PostmasterMain(int argc, char *argv[])
}
}
/*
* Select default values for switches where needed
*/
if (PostPortName == 0)
PostPortName = (unsigned short) pq_getport();
PostPortName = pq_getport();
/*
* Check for invalid combinations of switches
......@@ -596,13 +634,6 @@ PostmasterMain(int argc, char *argv[])
exit(1);
}
checkDataDir(DataDir, &DataDirOK); /* issues error messages */
if (!DataDirOK)
{
fprintf(stderr, "No data directory -- can't proceed.\n");
exit(2);
}
if (!Execfile[0] && FindExec(Execfile, argv[0], "postgres") < 0)
{
fprintf(stderr, "%s: could not find backend to execute...\n",
......@@ -622,7 +653,7 @@ PostmasterMain(int argc, char *argv[])
if (NetServer)
{
status = StreamServerPort(hostName, PostPortName, &ServerSock_INET);
status = StreamServerPort(hostName, (unsigned short)PostPortName, &ServerSock_INET);
if (status != STATUS_OK)
{
fprintf(stderr, "%s: cannot create INET stream port\n",
......@@ -632,7 +663,7 @@ PostmasterMain(int argc, char *argv[])
}
#if !defined(__CYGWIN32__) && !defined(__QNX__)
status = StreamServerPort(NULL, PostPortName, &ServerSock_UNIX);
status = StreamServerPort(NULL, (unsigned short)PostPortName, &ServerSock_UNIX);
if (status != STATUS_OK)
{
fprintf(stderr, "%s: cannot create UNIX stream port\n",
......@@ -707,7 +738,7 @@ PostmasterMain(int argc, char *argv[])
PG_INITMASK();
PG_SETMASK(&BlockSig);
pqsignal(SIGHUP, pmdie); /* send SIGHUP, don't die */
pqsignal(SIGHUP, SIGHUP_handler); /* reread config file and have children do same */
pqsignal(SIGINT, pmdie); /* send SIGTERM and ShutdownDataBase */
pqsignal(SIGQUIT, pmdie); /* send SIGUSR1 and die */
pqsignal(SIGTERM, pmdie); /* wait for children and ShutdownDataBase */
......@@ -1066,6 +1097,12 @@ ServerLoop(void)
curr = next;
}
if (got_SIGHUP)
{
got_SIGHUP = false;
ProcessConfigFile(PGC_SIGHUP);
}
}
}
......@@ -1321,7 +1358,7 @@ ConnFree(Port *conn)
* reset_shared -- reset shared memory and semaphores
*/
static void
reset_shared(unsigned short port)
reset_shared(int port)
{
ipc_key = port * 1000 + shmem_seq * 100;
CreateSharedMemoryAndSemaphores(ipc_key, MaxBackends);
......@@ -1330,6 +1367,23 @@ reset_shared(unsigned short port)
shmem_seq -= 10;
}
/*
* set flag is SIGHUP was detected so config file can be reread in
* main loop
*/
static void
SIGHUP_handler(SIGNAL_ARGS)
{
got_SIGHUP = true;
if (Shutdown > SmartShutdown)
return;
got_SIGHUP = true;
SignalChildren(SIGHUP);
}
/*
* pmdie -- signal handler for cleaning up after a kill signal.
*/
......@@ -1338,19 +1392,11 @@ pmdie(SIGNAL_ARGS)
{
PG_SETMASK(&BlockSig);
TPRINTF(TRACE_VERBOSE, "pmdie %d", postgres_signal_arg);
if (DebugLvl >= 1)
elog(DEBUG, "pmdie %d", postgres_signal_arg);
switch (postgres_signal_arg)
{
case SIGHUP:
/*
* Send SIGHUP to all children (update options flags)
*/
if (Shutdown > SmartShutdown)
return;
SignalChildren(SIGHUP);
return;
case SIGUSR2:
/*
......@@ -1679,9 +1725,10 @@ SignalChildren(int signal)
if (bp->pid != mypid)
{
TPRINTF(TRACE_VERBOSE,
"SignalChildren: sending signal %d to process %d",
signal, bp->pid);
if (DebugLvl >= 1)
elog(DEBUG, "SignalChildren: sending signal %d to process %d",
signal, bp->pid);
kill(bp->pid, signal);
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.34 2000/04/12 17:15:33 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.35 2000/05/31 00:28:26 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -48,7 +48,6 @@ long *CurTraceBuf;
#endif /* BMTRACE */
int ShowPinTrace = 0;
int NBuffers = DEF_NBUFFERS; /* default is set in config.h */
int Data_Descriptors;
int Free_List_Descriptor;
int Lookup_List_Descriptor;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.56 2000/04/12 17:15:35 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.57 2000/05/31 00:28:27 petere Exp $
*
* NOTES:
*
......@@ -196,7 +196,10 @@ static long pg_nofile(void);
int
pg_fsync(int fd)
{
return disableFsync ? 0 : fsync(fd);
if (enableFsync)
return fsync(fd);
else
return 0;
}
/*
......@@ -916,7 +919,7 @@ FileSync(File file)
/* Need not sync if file is not dirty. */
returnCode = 0;
}
else if (disableFsync)
else if (!enableFsync)
{
/* Don't force the file open if pg_fsync isn't gonna sync it. */
returnCode = 0;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.47 2000/05/16 20:48:48 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.48 2000/05/31 00:28:29 petere Exp $
*
* NOTES
*
......@@ -36,9 +36,9 @@
/* In Ultrix, sem.h and shm.h must be included AFTER ipc.h */
#include <sys/sem.h>
#include <sys/shm.h>
#include "miscadmin.h"
#include "utils/memutils.h"
#include "libpq/libpq.h"
#include "utils/trace.h"
#if defined(solaris_sparc)
#include <sys/ipc.h>
......@@ -124,7 +124,8 @@ proc_exit(int code)
*/
proc_exit_inprogress = true;
TPRINTF(TRACE_VERBOSE, "proc_exit(%d)", code);
if (DebugLvl > 1)
elog(DEBUG, "proc_exit(%d)", code);
/* do our shared memory exits first */
shmem_exit(code);
......@@ -143,7 +144,8 @@ proc_exit(int code)
(*on_proc_exit_list[on_proc_exit_index].function) (code,
on_proc_exit_list[on_proc_exit_index].arg);
TPRINTF(TRACE_VERBOSE, "exit(%d)", code);
if (DebugLvl > 1)
elog(DEBUG, "exit(%d)", code);
exit(code);
}
......@@ -156,7 +158,8 @@ proc_exit(int code)
void
shmem_exit(int code)
{
TPRINTF(TRACE_VERBOSE, "shmem_exit(%d)", code);
if (DebugLvl > 1)
elog(DEBUG, "shmem_exit(%d)", code);
/* ----------------
* call all the registered callbacks.
......@@ -297,18 +300,16 @@ IpcSemaphoreCreate(IpcSemaphoreKey semKey,
if (semId == -1)
{
#ifdef DEBUG_IPC
EPRINTF("calling semget with %d, %d , %d\n",
semKey,
semNum,
IPC_CREAT | permission);
fprintf(stderr, "calling semget(%d, %d, 0%o)\n",
semKey, semNum, (unsigned)(IPC_CREAT|permission));
#endif
semId = semget(semKey, semNum, IPC_CREAT | permission);
if (semId < 0)
{
EPRINTF("IpcSemaphoreCreate: semget failed (%s) "
"key=%d, num=%d, permission=%o",
strerror(errno), semKey, semNum, permission);
fprintf(stderr, "IpcSemaphoreCreate: semget(%d, %d, 0%o) failed: %s\n",
semKey, semNum, (unsigned)(permission|IPC_CREAT),
strerror(errno));
IpcConfigTip();
return (-1);
}
......@@ -318,8 +319,8 @@ IpcSemaphoreCreate(IpcSemaphoreKey semKey,
errStatus = semctl(semId, 0, SETALL, semun);
if (errStatus == -1)
{
EPRINTF("IpcSemaphoreCreate: semctl failed (%s) id=%d",
strerror(errno), semId);
fprintf(stderr, "IpcSemaphoreCreate: semctl(id=%d) failed: %s\n",
semId, strerror(errno));
semctl(semId, 0, IPC_RMID, semun);
IpcConfigTip();
return (-1);
......@@ -330,10 +331,11 @@ IpcSemaphoreCreate(IpcSemaphoreKey semKey,
}
#ifdef DEBUG_IPC
EPRINTF("\nIpcSemaphoreCreate, returns %d\n", semId);
fprintf(stderr, "IpcSemaphoreCreate returns %d\n", semId);
fflush(stdout);
fflush(stderr);
#endif
return semId;
}
......@@ -357,13 +359,11 @@ IpcSemaphoreSet(int semId, int semno, int value)
IpcSemaphoreSet_return = errStatus;
if (errStatus == -1)
{
EPRINTF("IpcSemaphoreSet: semctl failed (%s) id=%d",
strerror(errno), semId);
}
fprintf(stderr, "IpcSemaphoreSet: semctl(id=%d) failed: %s\n",
semId, strerror(errno));
}
#endif
#endif /* NOT_USED */
/****************************************************************************/
/* IpcSemaphoreKill(key) - removes a semaphore */
......@@ -421,8 +421,8 @@ IpcSemaphoreLock(IpcSemaphoreId semId, int sem, int lock)
if (errStatus == -1)
{
EPRINTF("IpcSemaphoreLock: semop failed (%s) id=%d",
strerror(errno), semId);
fprintf(stderr, "IpcSemaphoreLock: semop(id=%d) failed: %s\n",
semId, strerror(errno));
proc_exit(255);
}
}
......@@ -466,8 +466,8 @@ IpcSemaphoreUnlock(IpcSemaphoreId semId, int sem, int lock)
if (errStatus == -1)
{
EPRINTF("IpcSemaphoreUnlock: semop failed (%s) id=%d",
strerror(errno), semId);
fprintf(stderr, "IpcSemaphoreUnlock: semop(id=%d) failed: %s\n",
semId, strerror(errno));
proc_exit(255);
}
}
......@@ -516,9 +516,8 @@ IpcMemoryCreate(IpcMemoryKey memKey, uint32 size, int permission)
if (shmid < 0)
{
EPRINTF("IpcMemoryCreate: shmget failed (%s) "
"key=%d, size=%d, permission=%o",
strerror(errno), memKey, size, permission);
fprintf(stderr, "IpcMemoryCreate: shmget(%d, %d, 0%o) failed: %s\n",
memKey, size, (unsigned)(IPC_CREAT|permission), strerror(errno));
IpcConfigTip();
return IpcMemCreationFailed;
}
......@@ -542,9 +541,8 @@ IpcMemoryIdGet(IpcMemoryKey memKey, uint32 size)
if (shmid < 0)
{
EPRINTF("IpcMemoryIdGet: shmget failed (%s) "
"key=%d, size=%d, permission=%o",
strerror(errno), memKey, size, 0);
fprintf(stderr, "IpcMemoryIdGet: shmget(%d, %d, 0) failed: %s\n",
memKey, size, strerror(errno));
return IpcMemIdGetFailed;
}
......@@ -583,8 +581,8 @@ IpcMemoryAttach(IpcMemoryId memId)
/* if ( *memAddress == -1) { XXX ??? */
if (memAddress == (char *) -1)
{
EPRINTF("IpcMemoryAttach: shmat failed (%s) id=%d",
strerror(errno), memId);
fprintf(stderr, "IpcMemoryAttach: shmat(id=%d) failed: %s\n",
memId, strerror(errno));
return IpcMemAttachFailed;
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.31 2000/05/30 00:49:52 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.32 2000/05/31 00:28:29 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -268,8 +268,8 @@ SIInsertDataEntry(SISeg *segP, SharedInvalidData *data)
if (numMsgs == (MAXNUMMESSAGES * 70 / 100) &&
IsUnderPostmaster)
{
TPRINTF(TRACE_VERBOSE,
"SIInsertDataEntry: table is 70%% full, signaling postmaster");
if (DebugLvl >= 1)
elog(DEBUG, "SIInsertDataEntry: table is 70%% full, signaling postmaster");
kill(getppid(), SIGUSR2);
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.24 2000/04/12 17:15:37 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.25 2000/05/31 00:28:29 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -35,6 +35,7 @@
#include "storage/proc.h"
#include "storage/s_lock.h"
/* globals used in this file */
IpcSemaphoreId SpinLockId;
......@@ -84,14 +85,23 @@ InitSpinLocks(void)
return;
}
#ifdef LOCKDEBUG
#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
#ifdef LOCK_DEBUG
bool Trace_spinlocks = false;
inline static void
PRINT_SLDEBUG(const char * where, SPINLOCK lockid, const SLock * lock)
{
if (Trace_spinlocks)
elog(DEBUG,
"%s: id=%d (locklock=%d, flag=%d, nshlocks=%d, shlock=%d, exlock=%d)",
where, lockid,
lock->locklock, lock->flag, lock->nshlocks, lock->shlock, lock->exlock);
}
#else /* not LOCK_DEBUG */
#define PRINT_SLDEBUG(a,b,c)
#endif /* not LOCK_DEBUG */
/* from ipc.c */
extern SLock *SLockArray;
......@@ -103,10 +113,7 @@ SpinAcquire(SPINLOCK lockid)
/* This used to be in ipc.c, but move here to reduce function calls */
slckP = &(SLockArray[lockid]);
#ifdef LOCKDEBUG
TPRINTF(TRACE_SPINLOCKS, "SpinAcquire: %d", lockid);
PRINT_LOCK(slckP);
#endif
PRINT_SLDEBUG("SpinAcquire", lockid, slckP);
ex_try_again:
S_LOCK(&(slckP->locklock));
switch (slckP->flag)
......@@ -116,10 +123,7 @@ ex_try_again:
S_LOCK(&(slckP->exlock));
S_LOCK(&(slckP->shlock));
S_UNLOCK(&(slckP->locklock));
#ifdef LOCKDEBUG
TPRINTF(TRACE_SPINLOCKS, "OUT: ");
PRINT_LOCK(slckP);
#endif
PRINT_SLDEBUG("OUT", lockid, slckP);
break;
case SHAREDLOCK:
case EXCLUSIVELOCK:
......@@ -129,9 +133,7 @@ ex_try_again:
goto ex_try_again;
}
PROC_INCR_SLOCK(lockid);
#ifdef LOCKDEBUG
TPRINTF(TRACE_SPINLOCKS, "SpinAcquire: got %d", lockid);
#endif
PRINT_SLDEBUG("SpinAcquire/success", lockid, slckP);
}
void
......@@ -142,23 +144,16 @@ SpinRelease(SPINLOCK 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(!MyProc || MyProc->sLocks[lockid] > 0);
Assert(slckP->flag != NOLOCK);
#endif
PROC_DECR_SLOCK(lockid);
#ifdef LOCKDEBUG
TPRINTF("SpinRelease: %d\n", lockid);
PRINT_LOCK(slckP);
#endif
PROC_DECR_SLOCK(lockid);
PRINT_SLDEBUG("SpinRelease", lockid, slckP);
S_LOCK(&(slckP->locklock));
/* -------------
* give favor to read processes
......@@ -178,13 +173,10 @@ SpinRelease(SPINLOCK lockid)
S_UNLOCK(&(slckP->shlock));
S_UNLOCK(&(slckP->exlock));
S_UNLOCK(&(slckP->locklock));
#ifdef LOCKDEBUG
TPRINTF(TRACE_SPINLOCKS, "SpinRelease: released %d", lockid);
PRINT_LOCK(slckP);
#endif
PRINT_SLDEBUG("SpinRelease/released", lockid, slckP);
}
#else /* HAS_TEST_AND_SET */
#else /* !HAS_TEST_AND_SET */
/* Spinlocks are implemented using SysV semaphores */
static bool AttachSpinLocks(IPCKey key);
......@@ -290,4 +282,4 @@ InitSpinLocks(void)
return;
}
#endif /* HAS_TEST_AND_SET */
#endif /* !HAS_TEST_AND_SET */
......@@ -8,17 +8,10 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.39 2000/04/12 17:15:38 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.40 2000/05/31 00:28:30 petere Exp $
*
*-------------------------------------------------------------------------
*/
/* #define LOCKDEBUGALL 1 */
/* #define LOCKDEBUG 1 */
#ifdef LOCKDEBUGALL
#define LOCKDEBUG 1
#endif /* LOCKDEBUGALL */
#include "postgres.h"
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.73 2000/05/30 00:49:52 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.74 2000/05/31 00:28:30 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -47,7 +47,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.73 2000/05/30 00:49:52 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.74 2000/05/31 00:28:30 petere Exp $
*/
#include <sys/time.h>
#include <unistd.h>
......@@ -66,13 +66,14 @@
/* In Ultrix and QNX, sem.h must be included after ipc.h */
#include <sys/sem.h>
#include "storage/lock.h"
#include "storage/proc.h"
void HandleDeadLock(SIGNAL_ARGS);
static void ProcFreeAllSemaphores(void);
static bool GetOffWaitqueue(PROC *);
#define DeadlockCheckTimer pg_options[OPT_DEADLOCKTIMEOUT]
int DeadlockTimeout = 1000;
/* --------------------
* Spin lock for manipulating the shared process data structure:
......@@ -633,8 +634,8 @@ ins:;
* --------------
*/
MemSet(&timeval, 0, sizeof(struct itimerval));
timeval.it_value.tv_sec = \
(DeadlockCheckTimer ? DeadlockCheckTimer : DEADLOCK_CHECK_TIMER);
timeval.it_value.tv_sec = DeadlockTimeout / 1000;
timeval.it_value.tv_usec = (DeadlockTimeout % 1000) * 1000;
SetWaitingForLock(true);
do
......@@ -663,6 +664,7 @@ ins:;
* ---------------
*/
timeval.it_value.tv_sec = 0;
timeval.it_value.tv_usec = 0;
if (setitimer(ITIMER_REAL, &timeval, &dummy))
elog(FATAL, "ProcSleep: Unable to diable timer for process wakeup");
......@@ -675,7 +677,7 @@ ins:;
rt:;
#ifdef LOCK_MGR_DEBUG
#ifdef LOCK_DEBUG
/* Just to get meaningful debug messages from DumpLocks() */
MyProc->waitLock = (LOCK *) NULL;
#endif
......@@ -723,7 +725,6 @@ ProcLockWakeup(PROC_QUEUE *queue, LOCKMETHOD lockmethod, LOCK *lock)
{
PROC *proc;
int count = 0;
int trace_flag;
int last_locktype = 0;
int queue_size = queue->size;
......@@ -783,14 +784,13 @@ ProcLockWakeup(PROC_QUEUE *queue, LOCKMETHOD lockmethod, LOCK *lock)
else
{
/* Something is still blocking us. May have deadlocked. */
trace_flag = (lock->tag.lockmethod == USER_LOCKMETHOD) ? \
TRACE_USERLOCKS : TRACE_LOCKS;
TPRINTF(trace_flag,
"ProcLockWakeup: lock(%x) can't wake up any process",
MAKE_OFFSET(lock));
#ifdef DEADLOCK_DEBUG
if (pg_options[trace_flag] >= 2)
#ifdef LOCK_DEBUG
if (lock->tag.lockmethod == USER_LOCKMETHOD ? Trace_userlocks : Trace_locks)
{
elog(DEBUG, "ProcLockWakeup: lock(%lx) can't wake up any process", MAKE_OFFSET(lock));
if (Debug_deadlocks)
DumpAllLocks();
}
#endif
return STATUS_NOT_FOUND;
}
......@@ -803,7 +803,7 @@ ProcAddLock(SHM_QUEUE *elem)
}
/* --------------------
* We only get to this routine if we got SIGALRM after DEADLOCK_CHECK_TIMER
* We only get to this routine if we got SIGALRM after DeadlockTimeout
* while waiting for a lock to be released by some other process. If we have
* a real deadlock, we must also indicate that I'm no longer waiting
* on a lock so that other processes don't try to wake me up and screw
......@@ -852,8 +852,9 @@ HandleDeadLock(SIGNAL_ARGS)
return;
}
#ifdef DEADLOCK_DEBUG
DumpAllLocks();
#ifdef LOCK_DEBUG
if (Debug_deadlocks)
DumpAllLocks();
#endif
MyProc->errType = STATUS_NOT_FOUND;
......
This diff is collapsed.
......@@ -8,19 +8,19 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/error/assert.c,v 1.17 2000/01/26 05:57:20 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/error/assert.c,v 1.18 2000/05/31 00:28:31 petere Exp $
*
* NOTE
* This should eventually work with elog(), dlog(), etc.
*
*-------------------------------------------------------------------------
*/
#include <unistd.h>
#include "postgres.h"
#include <stdio.h>
#include <unistd.h>
#include "utils/exc.h"
#include "utils/trace.h"
int
ExceptionalCondition(char *conditionName,
......@@ -39,7 +39,7 @@ ExceptionalCondition(char *conditionName,
|| !PointerIsValid(fileName)
|| !PointerIsValid(exceptionP))
{
EPRINTF("TRAP: ExceptionalCondition: bad arguments\n");
fprintf(stderr, "TRAP: ExceptionalCondition: bad arguments\n");
ExcAbort(exceptionP,
(ExcDetail) detail,
......@@ -48,7 +48,7 @@ ExceptionalCondition(char *conditionName,
}
else
{
EPRINTF("TRAP: %s(\"%s:%s\", File: \"%s\", Line: %d)\n",
fprintf(stderr, "TRAP: %s(\"%s:%s\", File: \"%s\", Line: %d)\n",
exceptionP->message, conditionName,
(detail == NULL ? "" : detail),
fileName, lineNumber);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.58 2000/05/30 00:49:55 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.59 2000/05/31 00:28:32 petere Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -24,8 +24,10 @@
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#ifdef USE_SYSLOG
#include <syslog.h>
#include <sys/time.h>
#include <ctype.h>
#ifdef ENABLE_SYSLOG
# include <syslog.h>
#endif
#include "libpq/libpq.h"
......@@ -40,20 +42,31 @@ extern int sys_nerr;
extern CommandDest whereToSendOutput;
#ifdef USE_SYSLOG
#ifdef ENABLE_SYSLOG
/*
* Global option to control the use of syslog(3) for logging:
*
* 0 stdout/stderr only
* 1 stdout/stderr + syslog
* 2 syslog only
* 0 = only stdout/stderr
* 1 = stdout+stderr and syslog
* 2 = syslog only
* ... in theory anyway
*/
#define UseSyslog pg_options[OPT_SYSLOG]
#define PG_LOG_FACILITY LOG_LOCAL0
int Use_syslog = 0;
static void write_syslog(int level, const char *line);
#else
# define Use_syslog 0
#endif
#ifdef ELOG_TIMESTAMPS
static const char * print_timestamp(void);
# define TIMESTAMP_SIZE 28
#else
#define UseSyslog 0
# define TIMESTAMP_SIZE 0
#endif
static int Debugfile = -1;
static int Err_file = -1;
static int ElogDebugIndentLevel = 0;
......@@ -182,7 +195,7 @@ elog(int lev, const char *fmt,...)
}
}
#ifdef ELOG_TIMESTAMPS
strcpy(fmt_buf, tprintf_timestamp());
strcpy(fmt_buf, print_timestamp());
strcat(fmt_buf, prefix);
#else
strcpy(fmt_buf, prefix);
......@@ -265,7 +278,7 @@ elog(int lev, const char *fmt,...)
msg_buf = msg_fixedbuf;
lev = REALLYFATAL;
#ifdef ELOG_TIMESTAMPS
strcpy(msg_buf, tprintf_timestamp());
strcpy(msg_buf, print_timestamp());
strcat(msg_buf, "FATAL: elog: out of memory");
#else
strcpy(msg_buf, "FATAL: elog: out of memory");
......@@ -278,35 +291,43 @@ elog(int lev, const char *fmt,...)
* Message prepared; send it where it should go
*/
#ifdef USE_SYSLOG
switch (lev)
#ifdef ENABLE_SYSLOG
if (Use_syslog >= 1)
{
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;
int syslog_level;
switch (lev)
{
case NOIND:
syslog_level = LOG_DEBUG;
break;
case DEBUG:
syslog_level = LOG_DEBUG;
break;
case NOTICE:
syslog_level = LOG_NOTICE;
break;
case ERROR:
syslog_level = LOG_WARNING;
break;
case FATAL:
syslog_level = LOG_ERR;
break;
case REALLYFATAL:
default:
syslog_level = LOG_CRIT;
}
write_syslog(syslog_level, msg_buf + TIMESTAMP_SIZE);
}
write_syslog(log_level, msg_buf + TIMESTAMP_SIZE);
#endif
#endif /* ENABLE_SYSLOG */
/* syslog doesn't want a trailing newline, but other destinations do */
strcat(msg_buf, "\n");
len = strlen(msg_buf);
if (Debugfile >= 0 && UseSyslog <= 1)
if (Debugfile >= 0 && Use_syslog <= 1)
write(Debugfile, msg_buf, len);
/*
......@@ -321,7 +342,7 @@ elog(int lev, const char *fmt,...)
* does anyone still use ultrix?)
*/
if (lev > DEBUG && Err_file >= 0 &&
Debugfile != Err_file && UseSyslog <= 1)
Debugfile != Err_file && Use_syslog <= 1)
{
if (write(Err_file, msg_buf, len) < 0)
{
......@@ -502,3 +523,124 @@ DebugFileOpen(void)
}
#endif
#ifdef ELOG_TIMESTAMPS
/*
* Return a timestamp string like "980119.17:25:59.902 [21974] "
*/
static const char *
print_timestamp()
{
struct timeval tv;
struct timezone tz = { 0, 0 };
struct tm *time;
time_t tm;
static char timestamp[32],
pid[8];
gettimeofday(&tv, &tz);
tm = tv.tv_sec;
time = localtime(&tm);
sprintf(pid, "[%d]", MyProcPid);
sprintf(timestamp, "%02d%02d%02d.%02d:%02d:%02d.%03d %7s ",
time->tm_year % 100, time->tm_mon + 1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec,
(int) (tv.tv_usec/1000), pid);
return timestamp;
}
#endif
#ifdef ENABLE_SYSLOG
/*
* Write a message line to syslog if the syslog option is set.
*
* Our problem here is that many syslog implementations don't handle
* long messages in an acceptable manner. While this function doesn't
* help that fact, it does work around by splitting up messages into
* smaller pieces.
*/
static void
write_syslog(int level, const char *line)
{
#ifndef PG_SYSLOG_LIMIT
# define PG_SYSLOG_LIMIT 128
#endif
static bool openlog_done = false;
static unsigned long seq = 0;
int len = strlen(line);
if (Use_syslog == 0)
return;
if (!openlog_done)
{
openlog("postgres", LOG_PID | LOG_NDELAY, LOG_LOCAL0);
openlog_done = true;
}
/*
* We add a sequence number to each log message to suppress "same"
* messages.
*/
seq++;
/* divide into multiple syslog() calls if message is too long */
if (len > PG_SYSLOG_LIMIT)
{
static char buf[PG_SYSLOG_LIMIT+1];
int chunk_nr = 0;
int buflen;
while (len > 0)
{
int l;
int i;
strncpy(buf, line, PG_SYSLOG_LIMIT);
buf[PG_SYSLOG_LIMIT] = '\0';
l = strlen(buf);
#ifdef MULTIBYTE
/* trim to multibyte letter boundary */
buflen = pg_mbcliplen(buf, l, l);
buf[buflen] = '\0';
l = strlen(buf);
#endif
/* already word boundary? */
if (isspace(line[l]) || line[l] == '\0')
buflen = l;
else
{
/* try to divide in word boundary */
i = l - 1;
while(i > 0 && !isspace(buf[i]))
i--;
if (i <= 0) /* couldn't divide word boundary */
buflen = l;
else
{
buflen = i;
buf[i] = '\0';
}
}
chunk_nr++;
syslog(level, "[%lu-%d] %s", seq, chunk_nr, buf);
line += buflen;
len -= buflen;
}
}
/* message short enough */
else
syslog(level, "[%lu] %s", seq, line);
}
#endif /* ENABLE_SYSLOG */
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.44 2000/05/30 00:49:56 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.45 2000/05/31 00:28:32 petere Exp $
*
* NOTES
* Globals used all over the place should be declared here and not
......@@ -77,8 +77,11 @@ char DateFormat[20] = "%d-%m-%Y"; /* mjl: sizes! or better
* malloc? XXX */
char FloatFormat[20] = "%f";
bool enableFsync = true;
bool allowSystemTableMods = false;
int SortMem = 512;
int NBuffers = DEF_NBUFFERS;
char *IndexedCatalogNames[] = {
AttributeRelationName,
......
......@@ -4,27 +4,38 @@
# Makefile for utils/misc
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/utils/misc/Makefile,v 1.13 2000/05/29 05:45:37 tgl Exp $
# $Header: /cvsroot/pgsql/src/backend/utils/misc/Makefile,v 1.14 2000/05/31 00:28:34 petere Exp $
#
#-------------------------------------------------------------------------
SRCDIR = ../../..
include ../../../Makefile.global
OBJS = database.o superuser.o trace.o
OBJS = database.o superuser.o guc.o guc-file.o
all: SUBSYS.o
SUBSYS.o: $(OBJS)
$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
.SECONDARY: guc-file.c
.INTERMEDIATE: lex.yy.c
guc-file.c: lex.yy.c
sed -e 's/lex\.yy\.c/guc-file\.c/g' \
-e 's/^yy/GUC_yy/g' \
-e 's/\([^a-zA-Z0-9_]\)yy/\1GUC_yy/g' < $< > $@
lex.yy.c: guc-file.l
$(LEX) $(LFLAGS) $<
depend dep:
$(CC) -MM $(CFLAGS) *.c >depend
clean:
rm -f SUBSYS.o $(OBJS)
rm -f SUBSYS.o $(OBJS) lex.yy.c
ifeq (depend,$(wildcard depend))
include depend
endif
/* -*-pgsql-c-*- */
/*
* Scanner for the configuration file
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc-file.l,v 1.1 2000/05/31 00:28:34 petere Exp $
*/
%{
#include "postgres.h"
#include <string.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/elog.h"
#include "utils/guc.h"
static unsigned ConfigFileLineno;
enum {
GUC_ID = 1,
GUC_STRING = 2,
GUC_INTEGER = 3,
GUC_REAL = 4,
GUC_EQUALS = 5,
GUC_EOL = 99,
GUC_ERROR = 100,
};
#if defined(yywrap)
#undef yywrap
#endif /* yywrap */
#define YY_USER_INIT (ConfigFileLineno = 1)
#define YY_NO_UNPUT
%}
SIGN ("-"|"+")
DIGIT [0-9]
HEXDIGIT [0-9a-fA-F]
INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+)
EXPONENT [Ee]{SIGN}?{DIGIT}+
REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}?
LETTER [A-Za-z_\200-\377]
LETTER_OR_DIGIT [A-Za-z_0-9\200-\377]
ID {LETTER}{LETTER_OR_DIGIT}*
/*
* FIXME: This string syntax is nice and all but of course the quotes
* need to be stripped before we can make any use of the string value.
* There is a function in parser/scansup.c that does this but it uses
* palloc and there might be a little more magic needed to get it to
* work right. Now there are no string options, and if there were then
* the unquoted (`ID') tokens should still work. Of course this only
* affects the configuration file.
*/
STRING \'([^'\n]|\\.)*'
%%
\n ConfigFileLineno++; return GUC_EOL;
[ \t\r]+ /* eat whitespace */
#.*$ /* eat comment */
{ID} return GUC_ID;
{STRING} return GUC_STRING;
{INTEGER} return GUC_INTEGER;
{REAL} return GUC_REAL;
= return GUC_EQUALS;
. return GUC_ERROR;
%%
struct name_value_pair
{
char *name;
char *value;
struct name_value_pair *next;
};
/*
* Free a list of name/value pairs, including the names and the values
*/
static void
free_name_value_list(struct name_value_pair * list)
{
struct name_value_pair *item;
item = list;
while (item)
{
struct name_value_pair *save;
save = item->next;
free(item->name);
free(item->value);
free(item);
item = save;
}
}
/*
* Official function to read and process the configuration file. The
* parameter indicates in what context the file is being read
* (postmaster startup, backend startup, or SIGHUP). All options
* mentioned in the configuration file are set to new values. This
* function does not return if an error occurs. If an error occurs, no
* values will be changed.
*/
void
ProcessConfigFile(unsigned int context)
{
int token, parse_state;
char *opt_name, *opt_value;
char *filename;
struct stat stat_buf;
struct name_value_pair *item, *head, *tail;
int elevel;
FILE * fp;
Assert(context == PGC_POSTMASTER || context == PGC_BACKEND || context == PGC_SIGHUP);
Assert(DataDir);
elevel = (context == PGC_SIGHUP) ? DEBUG : ERROR;
/*
* Open file
*/
filename = malloc(strlen(DataDir) + 16);
if (filename == NULL)
{
elog(elevel, "out of memory");
return;
}
sprintf(filename, "%s/configuration", DataDir);
fp = AllocateFile(filename, "r");
if (!fp)
{
free(filename);
/* File not found is fine */
if (errno != ENOENT)
elog(elevel, "could not read configuration: %s", strerror(errno));
return;
}
/*
* Check if the file is group or world writeable. If so, reject.
*/
if (fstat(fileno(fp), &stat_buf) == -1)
{
FreeFile(fp);
free(filename);
elog(elevel, "could not stat configuration file: %s", strerror(errno));
return;
}
if (stat_buf.st_mode & (S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH))
{
FreeFile(fp);
free(filename);
elog(elevel, "configuration file has wrong permissions");
return;
}
/*
* Parse
*/
yyin = fp;
parse_state = 0;
head = tail = NULL;
opt_name = opt_value = NULL;
while((token = yylex()))
switch(parse_state)
{
case 0: /* no previous input */
if (token == GUC_EOL) /* empty line */
continue;
if (token != GUC_ID)
goto parse_error;
opt_name = strdup(yytext);
if (opt_name == NULL)
goto out_of_memory;
parse_state = 1;
break;
case 1: /* found name */
/* ignore equals sign */
if (token == GUC_EQUALS)
token = yylex();
if (token != GUC_ID && token != GUC_STRING && token != GUC_INTEGER && token != GUC_REAL)
goto parse_error;
opt_value = strdup(yytext);
if (opt_value == NULL)
goto out_of_memory;
parse_state = 2;
break;
case 2: /* now we'd like an end of line */
if (token != GUC_EOL)
goto parse_error;
/* append to list */
item = malloc(sizeof *item);
if (item == NULL)
goto out_of_memory;
item->name = opt_name;
item->value = opt_value;
item->next = NULL;
if (!head)
tail = head = item;
else
{
tail->next = item;
tail = item;
}
parse_state = 0;
break;
}
FreeFile(fp);
free(filename);
/*
* Check if all options are valid
*/
for(item = head; item; item=item->next)
{
if (!set_config_option(item->name, item->value, context, false))
goto cleanup_exit;
}
/* If we got here all the options parsed okay. */
for(item = head; item; item=item->next)
set_config_option(item->name, item->value, context, true);
cleanup_exit:
free_name_value_list(head);
return;
parse_error:
FreeFile(fp);
free(filename);
free_name_value_list(head);
elog(elevel, "%s:%u: syntax error (ps:%d, t:%d)", filename,
ConfigFileLineno, parse_state, token);
return;
out_of_memory:
FreeFile(fp);
free(filename);
free_name_value_list(head);
elog(elevel, "out of memory");
return;
}
int
yywrap(void)
{
return 1;
}
This diff is collapsed.
This diff is collapsed.
......@@ -26,7 +26,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.91 2000/04/25 08:29:02 petere Exp $
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.92 2000/05/31 00:28:35 petere Exp $
#
#-------------------------------------------------------------------------
......@@ -321,7 +321,6 @@ PG_HBA_SAMPLE="$PGLIB"/pg_hba.conf.sample
TEMPLATE_DESCR="$PGLIB"/local1_template1.description
GLOBAL_DESCR="$PGLIB"/global1.description
PG_GEQO_SAMPLE="$PGLIB"/pg_geqo.sample
PG_POSTMASTER_OPTS_DEFAULT_SAMPLE="$PGLIB"/postmaster.opts.default.sample
if [ "$show_setting" -eq 1 ]
......@@ -342,7 +341,6 @@ then
echo " PG_HBA_SAMPLE: $PG_HBA_SAMPLE"
echo " TEMPLATE_DESCR: $TEMPLATE_DESCR"
echo " GLOBAL_DESCR: $GLOBAL_DESCR"
echo " PG_GEQO_SAMPLE: $PG_GEQO_SAMPLE"
echo " PG_POSTMASTER_OPTS_DEFAULT_SAMPLE: $PG_POSTMASTER_OPTS_DEFAULT_SAMPLE"
echo
exit 0
......@@ -461,7 +459,6 @@ then
"$PGPATH"/pg_version "$PGDATA" || exit_nicely
cp "$PG_HBA_SAMPLE" "$PGDATA"/pg_hba.conf || exit_nicely
cp "$PG_GEQO_SAMPLE" "$PGDATA"/pg_geqo.sample || exit_nicely
cp "$PG_POSTMASTER_OPTS_DEFAULT_SAMPLE" "$PGDATA"/postmaster.opts.default || exit_nicely
echo "Adding template1 database to pg_database"
......@@ -482,7 +479,7 @@ fi
echo
PGSQL_OPT="-o /dev/null -O -F -Q -D$PGDATA"
PGSQL_OPT="-o /dev/null -O -F -D$PGDATA"
# Create a trigger so that direct updates to pg_shadow will be written
# to the flat password file pg_pwd
......
This diff is collapsed.
......@@ -279,9 +279,14 @@ AC_MSG_CHECKING(setting DEF_PGPORT)
AC_ARG_WITH(
pgport,
[ --with-pgport=PORTNUM change default postmaster port ],
AC_DEFINE_UNQUOTED(DEF_PGPORT, "${withval}") AC_MSG_RESULT($with_pgport),
AC_DEFINE_UNQUOTED(DEF_PGPORT, "5432") AC_MSG_RESULT(5432)
[default_port="$withval"],
[default_port=5432]
)
dnl Need to do this twice because backend wants an integer and frontend a string
AC_DEFINE_UNQUOTED(DEF_PGPORT, ${default_port})
AC_DEFINE_UNQUOTED(DEF_PGPORT_STR, "${default_port}")
AC_MSG_RESULT(${default_port})
dnl DEF_MAXBACKENDS can be set by --with-maxbackends. Default value is 32.
AC_MSG_CHECKING(setting DEF_MAXBACKENDS)
......@@ -944,6 +949,13 @@ AC_TRY_LINK([#include <setjmp.h>],
[AC_DEFINE(HAVE_SIGSETJMP) AC_MSG_RESULT(yes)],
AC_MSG_RESULT(no))
AC_ARG_ENABLE(syslog, [ --enable-syslog enable logging to syslog],
[case $enableval in y|ye|yes)
AC_CHECK_FUNC(syslog, [AC_DEFINE(ENABLE_SYSLOG)], [AC_MSG_ERROR([no syslog interface found])])
;;
esac]
)
dnl Check to see if we have a working 64-bit integer type.
dnl This breaks down into two steps:
dnl (1) figure out if the compiler has a 64-bit int type with working
......
......@@ -6,13 +6,15 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: async.h,v 1.13 2000/01/26 05:58:00 momjian Exp $
* $Id: async.h,v 1.14 2000/05/31 00:28:37 petere Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef ASYNC_H
#define ASYNC_H
extern bool Trace_notify;
/* notify-related SQL statements */
extern void Async_Notify(char *relname);
extern void Async_Listen(char *relname, int pid);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment