Add GUC temp_tablespaces to provide a default location for temporary

objects.

Jaime Casanova
This commit is contained in:
Bruce Momjian 2007-01-25 04:35:11 +00:00
parent 5af6b2abe9
commit 148ea5cbea
10 changed files with 272 additions and 16 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.104 2007/01/20 21:30:26 momjian Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.105 2007/01/25 04:35:10 momjian Exp $ -->
<chapter Id="runtime-config">
<title>Server Configuration</title>
@ -3398,6 +3398,35 @@ SELECT * FROM parent WHERE key = 2400;
</listitem>
</varlistentry>
<varlistentry id="guc-temp-tablespaces" xreflabel="temp_tablespaces">
<term><varname>temp_tablespaces</varname> (<type>string</type>)</term>
<indexterm>
<primary><varname>temp_tablespaces</> configuration parameter</primary>
</indexterm>
<indexterm><primary>tablespace</><secondary>temp</></>
<listitem>
<para>
This variable specifies tablespaces in which to create temp
objects (temp tables and indexes on temp tables) when a
<command>CREATE</> command does not explicitly specify a tablespace
and temp files when necessary (eg. for sorting operations).
</para>
<para>
The value is either a list of names of tablespaces, or an empty
string to specify using the default tablespace of the current database.
If the value does not match the name of any existing tablespace,
<productname>PostgreSQL</> will automatically use the default
tablespace of the current database.
</para>
<para>
For more information on tablespaces,
see <xref linkend="manage-ag-tablespaces">.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-check-function-bodies" xreflabel="check_function_bodies">
<term><varname>check_function_bodies</varname> (<type>boolean</type>)</term>
<indexterm>

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.153 2007/01/20 23:13:01 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.154 2007/01/25 04:35:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -209,7 +209,13 @@ DefineIndex(RangeVar *heapRelation,
}
else
{
tablespaceId = GetDefaultTablespace();
/*
* if the target table is temporary then use a temp_tablespace
*/
if (!rel->rd_istemp)
tablespaceId = GetDefaultTablespace();
else
tablespaceId = GetTempTablespace();
/* note InvalidOid is OK in this case */
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.211 2007/01/25 04:17:45 momjian Exp $
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.212 2007/01/25 04:35:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -334,6 +334,10 @@ DefineRelation(CreateStmt *stmt, char relkind)
errmsg("tablespace \"%s\" does not exist",
stmt->tablespacename)));
}
else if (stmt->relation->istemp)
{
tablespaceId = GetTempTablespace();
}
else
{
tablespaceId = GetDefaultTablespace();

View File

@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.40 2007/01/05 22:19:26 momjian Exp $
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.41 2007/01/25 04:35:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -65,9 +65,12 @@
#include "utils/lsyscache.h"
/* GUC variable */
/* GUC variables */
char *default_tablespace = NULL;
char *temp_tablespaces = NULL;
int next_temp_tablespace;
int num_temp_tablespaces;
static bool remove_tablespace_directories(Oid tablespaceoid, bool redo);
static void set_short_version(const char *path);
@ -930,6 +933,142 @@ GetDefaultTablespace(void)
return result;
}
/*
* Routines for handling the GUC variable 'temp_tablespaces'.
*/
/* assign_hook: validate new temp_tablespaces, do extra actions as needed */
const char *
assign_temp_tablespaces(const char *newval, bool doit, GucSource source)
{
char *rawname;
List *namelist;
ListCell *l;
/* Need a modifiable copy of string */
rawname = pstrdup(newval);
/* Parse string into list of identifiers */
if (!SplitIdentifierString(rawname, ',', &namelist))
{
/* syntax error in name list */
pfree(rawname);
list_free(namelist);
return NULL;
}
num_temp_tablespaces = 0;
foreach(l, namelist)
{
char *curname = (char *) lfirst(l);
/*
* If we aren't inside a transaction, we cannot do database access so
* cannot verify the individual names. Must accept the list on faith.
*/
if (source >= PGC_S_INTERACTIVE && IsTransactionState())
{
/*
* Verify that all the names are valid tablspace names
* We do not check for USAGE rights should we?
*/
if (get_tablespace_oid(curname) == InvalidOid)
ereport((source == PGC_S_TEST) ? NOTICE : ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("tablespace \"%s\" does not exist", curname)));
}
num_temp_tablespaces++;
}
/*
* Select the first tablespace to use
*/
next_temp_tablespace = MyProcPid % num_temp_tablespaces;
pfree(rawname);
list_free(namelist);
return newval;
}
/*
* GetTempTablespace -- get the OID of the tablespace for temporary objects
*
* May return InvalidOid to indicate "use the database's default tablespace"
*
* This exists to hide the temp_tablespace GUC variable.
*/
Oid
GetTempTablespace(void)
{
Oid result;
char *curname = NULL;
char *rawname;
List *namelist;
ListCell *l;
int i = 0;
if ( temp_tablespaces == NULL )
return InvalidOid;
/* Need a modifiable version of temp_tablespaces */
rawname = pstrdup(temp_tablespaces);
/* Parse string into list of identifiers */
if (!SplitIdentifierString(rawname, ',', &namelist))
{
/* syntax error in name list */
pfree(rawname);
list_free(namelist);
return InvalidOid;
}
/*
* Iterate through the list of namespaces until the one we need
* (next_temp_tablespace)
*/
foreach(l, namelist)
{
curname = (char *) lfirst(l);
if ( i == next_temp_tablespace )
break;
i++;
}
/* Prepare for the next time the function is called */
next_temp_tablespace++;
if (next_temp_tablespace == num_temp_tablespaces)
next_temp_tablespace = 0;
/* Fast path for temp_tablespaces == "" */
if ( curname == NULL || curname[0] == '\0') {
list_free(namelist);
pfree(rawname);
return InvalidOid;
}
/*
* It is tempting to cache this lookup for more speed, but then we would
* fail to detect the case where the tablespace was dropped since the GUC
* variable was set. Note also that we don't complain if the value fails
* to refer to an existing tablespace; we just silently return InvalidOid,
* causing the new object to be created in the database's tablespace.
*/
result = get_tablespace_oid(curname);
/* We don't free rawname before because curname points to a part of it */
pfree(rawname);
/*
* Allow explicit specification of database's default tablespace in
* default_tablespace without triggering permissions checks.
*/
if (result == MyDatabaseTableSpace)
result = InvalidOid;
list_free(namelist);
return result;
}
/*
* get_tablespace_oid - given a tablespace name, look up the OID

View File

@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.284 2007/01/25 02:17:26 momjian Exp $
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.285 2007/01/25 04:35:10 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -2409,6 +2409,10 @@ OpenIntoRel(QueryDesc *queryDesc)
errmsg("tablespace \"%s\" does not exist",
parseTree->intoTableSpaceName)));
}
else if (parseTree->into->istemp)
{
tablespaceId = GetTempTablespace();
}
else
{
tablespaceId = GetDefaultTablespace();

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.134 2007/01/09 22:03:51 momjian Exp $
* $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.135 2007/01/25 04:35:10 momjian Exp $
*
* NOTES:
*
@ -46,6 +46,8 @@
#include <unistd.h>
#include <fcntl.h>
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "access/xact.h"
#include "storage/fd.h"
@ -76,6 +78,7 @@
*/
#define FD_MINFREE 10
#define OIDCHARS 10 /* max chars printed by %u */
/*
* A number of platforms allow individual processes to open many more files
@ -880,13 +883,51 @@ OpenTemporaryFile(bool interXact)
{
char tempfilepath[MAXPGPATH];
File file;
Oid oid;
char *path;
int pathlen;
/*
* Generate a tempfile name that should be unique within the current
* database instance.
* Take a look what should be the path of the temporary file
*/
snprintf(tempfilepath, sizeof(tempfilepath),
"%s/%s%d.%ld", PG_TEMP_FILES_DIR, PG_TEMP_FILE_PREFIX,
oid = GetTempTablespace();
if (oid != InvalidOid)
{
/*
* As we got a valid tablespace, try to create the
* file there
*/
pathlen = strlen("pg_tblspc/") + OIDCHARS + 1;
path = (char *) palloc(pathlen);
snprintf(path, pathlen, "pg_tblspc/%u", oid );
/*
* Generate a tempfile name that should be unique within the current
* database instance.
*/
snprintf(tempfilepath, sizeof(tempfilepath),
"%s/%s%d.%ld", path, PG_TEMP_FILE_PREFIX,
MyProcPid, tempFileCounter++);
pfree(path);
file = PathNameOpenFile(tempfilepath,
O_RDWR | O_CREAT | O_TRUNC | PG_BINARY,
0600);
}
/*
* Create a normal temporary file if no tablespace returned or
* couldn't create the file in the tablespace "oid"
*/
if (oid == InvalidOid || file <= 0)
{
path = PG_TEMP_FILES_DIR;
/*
* Generate a tempfile name that should be unique within the current
* database instance.
*/
snprintf(tempfilepath, sizeof(tempfilepath),
"%s/%s%d.%ld", path, PG_TEMP_FILE_PREFIX,
MyProcPid, tempFileCounter++);
/*
@ -918,7 +959,8 @@ OpenTemporaryFile(bool interXact)
if (file <= 0)
elog(ERROR, "could not create temporary file \"%s\": %m",
tempfilepath);
}
}
}
/* Mark it for deletion at close */
VfdCache[file].fdstate |= FD_TEMPORARY;
@ -1292,6 +1334,20 @@ TryAgain:
errno = save_errno;
}
/*
* TEMPORARY hack to log the Windows error code on fopen failures, in
* hopes of diagnosing some hard-to-reproduce problems.
*/
#ifdef WIN32
{
int save_errno = errno;
elog(LOG, "Windows fopen(\"%s\",\"%s\") failed: code %lu, errno %d",
name, mode, GetLastError(), save_errno);
errno = save_errno;
}
#endif
return NULL;
}

View File

@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.369 2007/01/19 16:58:46 petere Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.370 2007/01/25 04:35:11 momjian Exp $
*
*--------------------------------------------------------------------
*/
@ -99,6 +99,7 @@ extern bool Log_disconnections;
extern int CommitDelay;
extern int CommitSiblings;
extern char *default_tablespace;
extern char *temp_tablespaces;
extern bool fullPageWrites;
#ifdef TRACE_SORT
@ -2291,6 +2292,16 @@ static struct config_string ConfigureNamesString[] =
"base64", assign_xmlbinary, NULL
},
{
{"temp_tablespaces", PGC_USERSET, PGC_S_FILE,
gettext_noop("Sets the tablespaces suitable for creating new objects and sort files."),
NULL,
GUC_LIST_INPUT | GUC_LIST_QUOTE
},
&temp_tablespaces,
NULL, assign_temp_tablespaces, NULL
},
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL

View File

@ -399,6 +399,8 @@
#search_path = '"$user",public' # schema names
#default_tablespace = '' # a tablespace name, '' uses
# the default
#temp_tablespaces = '' # a list of tablespace names,
# '' uses default_tablespace
#check_function_bodies = on
#default_transaction_isolation = 'read committed'
#default_transaction_read_only = off

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.14 2007/01/05 22:19:54 momjian Exp $
* $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.15 2007/01/25 04:35:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -41,6 +41,7 @@ extern void AlterTableSpaceOwner(const char *name, Oid newOwnerId);
extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
extern Oid GetDefaultTablespace(void);
extern Oid GetTempTablespace(void);
extern Oid get_tablespace_oid(const char *tablespacename);
extern char *get_tablespace_name(Oid spc_oid);

View File

@ -7,7 +7,7 @@
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.78 2007/01/09 21:31:17 momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.79 2007/01/25 04:35:11 momjian Exp $
*--------------------------------------------------------------------
*/
#ifndef GUC_H
@ -238,4 +238,8 @@ extern const char *assign_search_path(const char *newval,
extern const char *assign_xlog_sync_method(const char *method,
bool doit, GucSource source);
/* in commands/tablespace.c */
extern const char *assign_temp_tablespaces(const char *newval,
bool doit, GucSource source);
#endif /* GUC_H */