1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-15 19:21:59 +03:00

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)
This commit is contained in:
Peter Eisentraut
2000-05-31 00:28:42 +00:00
parent 5e4d554bae
commit 6a68f42648
54 changed files with 2584 additions and 3290 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -1,350 +0,0 @@
/*------------------------------------------------------------------------
*
* 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));
}

View File

@ -1,72 +0,0 @@
#*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
# 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

View File

@ -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);

View File

@ -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;