mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Support ALTER TABLESPACE name SET/RESET ( tablespace_options ).
This patch only supports seq_page_cost and random_page_cost as parameters, but it provides the infrastructure to scalably support many more. In particular, we may want to add support for effective_io_concurrency, but I'm leaving that as future work for now. Thanks to Tom Lane for design help and Alvaro Herrera for the review.
This commit is contained in:
parent
72559b49c0
commit
d86d51a958
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.241 2009/12/25 01:09:31 rhaas Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.242 2010/01/05 21:53:58 rhaas Exp $ -->
|
||||||
|
|
||||||
<chapter Id="runtime-config">
|
<chapter Id="runtime-config">
|
||||||
<title>Server Configuration</title>
|
<title>Server Configuration</title>
|
||||||
@ -2000,6 +2000,9 @@ archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"' # Windows
|
|||||||
<para>
|
<para>
|
||||||
Sets the planner's estimate of the cost of a disk page fetch
|
Sets the planner's estimate of the cost of a disk page fetch
|
||||||
that is part of a series of sequential fetches. The default is 1.0.
|
that is part of a series of sequential fetches. The default is 1.0.
|
||||||
|
This value can be overriden for a particular tablespace by setting
|
||||||
|
the tablespace parameter of the same name
|
||||||
|
(see <xref linkend="sql-altertablespace">).
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -2013,6 +2016,12 @@ archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"' # Windows
|
|||||||
<para>
|
<para>
|
||||||
Sets the planner's estimate of the cost of a
|
Sets the planner's estimate of the cost of a
|
||||||
non-sequentially-fetched disk page. The default is 4.0.
|
non-sequentially-fetched disk page. The default is 4.0.
|
||||||
|
This value can be overriden for a particular tablespace by setting
|
||||||
|
the tablespace parameter of the same name
|
||||||
|
(see <xref linkend="sql-altertablespace">).
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
Reducing this value relative to <varname>seq_page_cost</>
|
Reducing this value relative to <varname>seq_page_cost</>
|
||||||
will cause the system to prefer index scans; raising it will
|
will cause the system to prefer index scans; raising it will
|
||||||
make index scans look relatively more expensive. You can raise
|
make index scans look relatively more expensive. You can raise
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_tablespace.sgml,v 1.5 2009/09/19 10:23:26 petere Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_tablespace.sgml,v 1.6 2010/01/05 21:53:58 rhaas Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -23,6 +23,8 @@ PostgreSQL documentation
|
|||||||
<synopsis>
|
<synopsis>
|
||||||
ALTER TABLESPACE <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
|
ALTER TABLESPACE <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
|
||||||
ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
|
ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
|
||||||
|
ALTER TABLESPACE <replaceable>name</replaceable> SET ( <replaceable class="PARAMETER">tablespace_option</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] )
|
||||||
|
ALTER TABLESPACE <replaceable>name</replaceable> RESET ( <replaceable class="PARAMETER">tablespace_option</replaceable> [, ... ] )
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
@ -74,6 +76,24 @@ ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">tablespace_parameter</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A tablespace parameter to be set or reset. Currently, the only
|
||||||
|
available parameters are <varname>seq_page_cost</> and
|
||||||
|
<varname>random_page_cost</>. Setting either value for a particular
|
||||||
|
tablespace will override the planner's usual estimate of the cost of
|
||||||
|
reading pages from tables in that tablespace, as established by
|
||||||
|
the configuration parameters of the same name (see
|
||||||
|
<xref linkend="guc-seq-page-cost">,
|
||||||
|
<xref linkend="guc-random-page-cost">). This may be useful if one
|
||||||
|
tablespace is located on a disk which is faster or slower than the
|
||||||
|
remainder of the I/O subsystem.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.30 2010/01/02 16:57:33 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.31 2010/01/05 21:53:58 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -21,6 +21,7 @@
|
|||||||
#include "access/reloptions.h"
|
#include "access/reloptions.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
|
#include "commands/tablespace.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "utils/array.h"
|
#include "utils/array.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
@ -179,6 +180,22 @@ static relopt_real realRelOpts[] =
|
|||||||
},
|
},
|
||||||
-1, 0.0, 100.0
|
-1, 0.0, 100.0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"seq_page_cost",
|
||||||
|
"Sets the planner's estimate of the cost of a sequentially fetched disk page.",
|
||||||
|
RELOPT_KIND_TABLESPACE
|
||||||
|
},
|
||||||
|
-1, 0.0, DBL_MAX
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"random_page_cost",
|
||||||
|
"Sets the planner's estimate of the cost of a nonsequentially fetched disk page.",
|
||||||
|
RELOPT_KIND_TABLESPACE
|
||||||
|
},
|
||||||
|
-1, 0.0, DBL_MAX
|
||||||
|
},
|
||||||
/* list terminator */
|
/* list terminator */
|
||||||
{{NULL}}
|
{{NULL}}
|
||||||
};
|
};
|
||||||
@ -1168,3 +1185,34 @@ index_reloptions(RegProcedure amoptions, Datum reloptions, bool validate)
|
|||||||
|
|
||||||
return DatumGetByteaP(result);
|
return DatumGetByteaP(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Option parser for tablespace reloptions
|
||||||
|
*/
|
||||||
|
bytea *
|
||||||
|
tablespace_reloptions(Datum reloptions, bool validate)
|
||||||
|
{
|
||||||
|
relopt_value *options;
|
||||||
|
TableSpaceOpts *tsopts;
|
||||||
|
int numoptions;
|
||||||
|
static const relopt_parse_elt tab[] = {
|
||||||
|
{"random_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, random_page_cost)},
|
||||||
|
{"seq_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, seq_page_cost)}
|
||||||
|
};
|
||||||
|
|
||||||
|
options = parseRelOptions(reloptions, validate, RELOPT_KIND_TABLESPACE,
|
||||||
|
&numoptions);
|
||||||
|
|
||||||
|
/* if none set, we're done */
|
||||||
|
if (numoptions == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
tsopts = allocateReloptStruct(sizeof(TableSpaceOpts), options, numoptions);
|
||||||
|
|
||||||
|
fillRelOptions((void *) tsopts, sizeof(TableSpaceOpts), options, numoptions,
|
||||||
|
validate, tab, lengthof(tab));
|
||||||
|
|
||||||
|
pfree(options);
|
||||||
|
|
||||||
|
return (bytea *) tsopts;
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.159 2010/01/02 16:57:36 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.160 2010/01/05 21:53:58 rhaas Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* See acl.h.
|
* See acl.h.
|
||||||
@ -2783,18 +2783,11 @@ ExecGrant_Tablespace(InternalGrant *istmt)
|
|||||||
int nnewmembers;
|
int nnewmembers;
|
||||||
Oid *oldmembers;
|
Oid *oldmembers;
|
||||||
Oid *newmembers;
|
Oid *newmembers;
|
||||||
ScanKeyData entry[1];
|
|
||||||
SysScanDesc scan;
|
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
/* There's no syscache for pg_tablespace, so must look the hard way */
|
/* Search syscache for pg_tablespace */
|
||||||
ScanKeyInit(&entry[0],
|
tuple = SearchSysCache(TABLESPACEOID, ObjectIdGetDatum(tblId),
|
||||||
ObjectIdAttributeNumber,
|
0, 0, 0);
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(tblId));
|
|
||||||
scan = systable_beginscan(relation, TablespaceOidIndexId, true,
|
|
||||||
SnapshotNow, 1, entry);
|
|
||||||
tuple = systable_getnext(scan);
|
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
elog(ERROR, "cache lookup failed for tablespace %u", tblId);
|
elog(ERROR, "cache lookup failed for tablespace %u", tblId);
|
||||||
|
|
||||||
@ -2865,8 +2858,7 @@ ExecGrant_Tablespace(InternalGrant *istmt)
|
|||||||
noldmembers, oldmembers,
|
noldmembers, oldmembers,
|
||||||
nnewmembers, newmembers);
|
nnewmembers, newmembers);
|
||||||
|
|
||||||
systable_endscan(scan);
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
pfree(new_acl);
|
pfree(new_acl);
|
||||||
|
|
||||||
/* prevent error when processing duplicate objects */
|
/* prevent error when processing duplicate objects */
|
||||||
@ -3696,9 +3688,6 @@ pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
|
|||||||
AclMode mask, AclMaskHow how)
|
AclMode mask, AclMaskHow how)
|
||||||
{
|
{
|
||||||
AclMode result;
|
AclMode result;
|
||||||
Relation pg_tablespace;
|
|
||||||
ScanKeyData entry[1];
|
|
||||||
SysScanDesc scan;
|
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Datum aclDatum;
|
Datum aclDatum;
|
||||||
bool isNull;
|
bool isNull;
|
||||||
@ -3711,17 +3700,9 @@ pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the tablespace's ACL from pg_tablespace
|
* Get the tablespace's ACL from pg_tablespace
|
||||||
*
|
|
||||||
* There's no syscache for pg_tablespace, so must look the hard way
|
|
||||||
*/
|
*/
|
||||||
pg_tablespace = heap_open(TableSpaceRelationId, AccessShareLock);
|
tuple = SearchSysCache(TABLESPACEOID, ObjectIdGetDatum(spc_oid),
|
||||||
ScanKeyInit(&entry[0],
|
0, 0, 0);
|
||||||
ObjectIdAttributeNumber,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(spc_oid));
|
|
||||||
scan = systable_beginscan(pg_tablespace, TablespaceOidIndexId, true,
|
|
||||||
SnapshotNow, 1, entry);
|
|
||||||
tuple = systable_getnext(scan);
|
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
@ -3729,8 +3710,9 @@ pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
|
|||||||
|
|
||||||
ownerId = ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner;
|
ownerId = ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner;
|
||||||
|
|
||||||
aclDatum = heap_getattr(tuple, Anum_pg_tablespace_spcacl,
|
aclDatum = SysCacheGetAttr(TABLESPACEOID, tuple,
|
||||||
RelationGetDescr(pg_tablespace), &isNull);
|
Anum_pg_tablespace_spcacl,
|
||||||
|
&isNull);
|
||||||
|
|
||||||
if (isNull)
|
if (isNull)
|
||||||
{
|
{
|
||||||
@ -3750,8 +3732,7 @@ pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
|
|||||||
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
|
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
|
||||||
pfree(acl);
|
pfree(acl);
|
||||||
|
|
||||||
systable_endscan(scan);
|
ReleaseSysCache(tuple);
|
||||||
heap_close(pg_tablespace, AccessShareLock);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -4338,9 +4319,6 @@ pg_namespace_ownercheck(Oid nsp_oid, Oid roleid)
|
|||||||
bool
|
bool
|
||||||
pg_tablespace_ownercheck(Oid spc_oid, Oid roleid)
|
pg_tablespace_ownercheck(Oid spc_oid, Oid roleid)
|
||||||
{
|
{
|
||||||
Relation pg_tablespace;
|
|
||||||
ScanKeyData entry[1];
|
|
||||||
SysScanDesc scan;
|
|
||||||
HeapTuple spctuple;
|
HeapTuple spctuple;
|
||||||
Oid spcowner;
|
Oid spcowner;
|
||||||
|
|
||||||
@ -4348,17 +4326,9 @@ pg_tablespace_ownercheck(Oid spc_oid, Oid roleid)
|
|||||||
if (superuser_arg(roleid))
|
if (superuser_arg(roleid))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* There's no syscache for pg_tablespace, so must look the hard way */
|
/* Search syscache for pg_tablespace */
|
||||||
pg_tablespace = heap_open(TableSpaceRelationId, AccessShareLock);
|
spctuple = SearchSysCache(TABLESPACEOID, ObjectIdGetDatum(spc_oid),
|
||||||
ScanKeyInit(&entry[0],
|
0, 0, 0);
|
||||||
ObjectIdAttributeNumber,
|
|
||||||
BTEqualStrategyNumber, F_OIDEQ,
|
|
||||||
ObjectIdGetDatum(spc_oid));
|
|
||||||
scan = systable_beginscan(pg_tablespace, TablespaceOidIndexId, true,
|
|
||||||
SnapshotNow, 1, entry);
|
|
||||||
|
|
||||||
spctuple = systable_getnext(scan);
|
|
||||||
|
|
||||||
if (!HeapTupleIsValid(spctuple))
|
if (!HeapTupleIsValid(spctuple))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
@ -4366,8 +4336,7 @@ pg_tablespace_ownercheck(Oid spc_oid, Oid roleid)
|
|||||||
|
|
||||||
spcowner = ((Form_pg_tablespace) GETSTRUCT(spctuple))->spcowner;
|
spcowner = ((Form_pg_tablespace) GETSTRUCT(spctuple))->spcowner;
|
||||||
|
|
||||||
systable_endscan(scan);
|
ReleaseSysCache(spctuple);
|
||||||
heap_close(pg_tablespace, AccessShareLock);
|
|
||||||
|
|
||||||
return has_privs_of_role(roleid, spcowner);
|
return has_privs_of_role(roleid, spcowner);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.65 2010/01/02 16:57:37 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.66 2010/01/05 21:53:58 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -49,6 +49,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
|
#include "access/reloptions.h"
|
||||||
#include "access/sysattr.h"
|
#include "access/sysattr.h"
|
||||||
#include "access/transam.h"
|
#include "access/transam.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
@ -57,6 +58,7 @@
|
|||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/pg_tablespace.h"
|
#include "catalog/pg_tablespace.h"
|
||||||
#include "commands/comment.h"
|
#include "commands/comment.h"
|
||||||
|
#include "commands/defrem.h"
|
||||||
#include "commands/tablespace.h"
|
#include "commands/tablespace.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "postmaster/bgwriter.h"
|
#include "postmaster/bgwriter.h"
|
||||||
@ -70,6 +72,7 @@
|
|||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
#include "utils/tqual.h"
|
#include "utils/tqual.h"
|
||||||
|
|
||||||
|
|
||||||
@ -290,6 +293,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
|
|||||||
values[Anum_pg_tablespace_spclocation - 1] =
|
values[Anum_pg_tablespace_spclocation - 1] =
|
||||||
CStringGetTextDatum(location);
|
CStringGetTextDatum(location);
|
||||||
nulls[Anum_pg_tablespace_spcacl - 1] = true;
|
nulls[Anum_pg_tablespace_spcacl - 1] = true;
|
||||||
|
nulls[Anum_pg_tablespace_spcoptions - 1] = true;
|
||||||
|
|
||||||
tuple = heap_form_tuple(rel->rd_att, values, nulls);
|
tuple = heap_form_tuple(rel->rd_att, values, nulls);
|
||||||
|
|
||||||
@ -912,6 +916,73 @@ AlterTableSpaceOwner(const char *name, Oid newOwnerId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Alter table space options
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt)
|
||||||
|
{
|
||||||
|
Relation rel;
|
||||||
|
ScanKeyData entry[1];
|
||||||
|
HeapScanDesc scandesc;
|
||||||
|
HeapTuple tup;
|
||||||
|
Datum datum;
|
||||||
|
Datum newOptions;
|
||||||
|
Datum repl_val[Natts_pg_tablespace];
|
||||||
|
bool isnull;
|
||||||
|
bool repl_null[Natts_pg_tablespace];
|
||||||
|
bool repl_repl[Natts_pg_tablespace];
|
||||||
|
HeapTuple newtuple;
|
||||||
|
|
||||||
|
/* Search pg_tablespace */
|
||||||
|
rel = heap_open(TableSpaceRelationId, RowExclusiveLock);
|
||||||
|
|
||||||
|
ScanKeyInit(&entry[0],
|
||||||
|
Anum_pg_tablespace_spcname,
|
||||||
|
BTEqualStrategyNumber, F_NAMEEQ,
|
||||||
|
CStringGetDatum(stmt->tablespacename));
|
||||||
|
scandesc = heap_beginscan(rel, SnapshotNow, 1, entry);
|
||||||
|
tup = heap_getnext(scandesc, ForwardScanDirection);
|
||||||
|
if (!HeapTupleIsValid(tup))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("tablespace \"%s\" does not exist",
|
||||||
|
stmt->tablespacename)));
|
||||||
|
|
||||||
|
/* Must be owner of the existing object */
|
||||||
|
if (!pg_tablespace_ownercheck(HeapTupleGetOid(tup), GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE,
|
||||||
|
stmt->tablespacename);
|
||||||
|
|
||||||
|
/* Generate new proposed spcoptions (text array) */
|
||||||
|
datum = heap_getattr(tup, Anum_pg_tablespace_spcoptions,
|
||||||
|
RelationGetDescr(rel), &isnull);
|
||||||
|
newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
|
||||||
|
stmt->options, NULL, NULL, false,
|
||||||
|
stmt->isReset);
|
||||||
|
(void) tablespace_reloptions(newOptions, true);
|
||||||
|
|
||||||
|
/* Build new tuple. */
|
||||||
|
memset(repl_null, false, sizeof(repl_null));
|
||||||
|
memset(repl_repl, false, sizeof(repl_repl));
|
||||||
|
if (newOptions != (Datum) 0)
|
||||||
|
repl_val[Anum_pg_tablespace_spcoptions - 1] = newOptions;
|
||||||
|
else
|
||||||
|
repl_null[Anum_pg_tablespace_spcoptions - 1] = true;
|
||||||
|
repl_repl[Anum_pg_tablespace_spcoptions - 1] = true;
|
||||||
|
newtuple = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val,
|
||||||
|
repl_null, repl_repl);
|
||||||
|
|
||||||
|
/* Update system catalog. */
|
||||||
|
simple_heap_update(rel, &newtuple->t_self, newtuple);
|
||||||
|
CatalogUpdateIndexes(rel, newtuple);
|
||||||
|
heap_freetuple(newtuple);
|
||||||
|
|
||||||
|
/* Conclude heap scan. */
|
||||||
|
heap_endscan(scandesc);
|
||||||
|
heap_close(rel, NoLock);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routines for handling the GUC variable 'default_tablespace'.
|
* Routines for handling the GUC variable 'default_tablespace'.
|
||||||
*/
|
*/
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.458 2010/01/02 16:57:45 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.459 2010/01/05 21:53:58 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -3064,6 +3064,18 @@ _copyDropTableSpaceStmt(DropTableSpaceStmt *from)
|
|||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static AlterTableSpaceOptionsStmt *
|
||||||
|
_copyAlterTableSpaceOptionsStmt(AlterTableSpaceOptionsStmt *from)
|
||||||
|
{
|
||||||
|
AlterTableSpaceOptionsStmt *newnode = makeNode(AlterTableSpaceOptionsStmt);
|
||||||
|
|
||||||
|
COPY_STRING_FIELD(tablespacename);
|
||||||
|
COPY_NODE_FIELD(options);
|
||||||
|
COPY_SCALAR_FIELD(isReset);
|
||||||
|
|
||||||
|
return newnode;
|
||||||
|
}
|
||||||
|
|
||||||
static CreateFdwStmt *
|
static CreateFdwStmt *
|
||||||
_copyCreateFdwStmt(CreateFdwStmt *from)
|
_copyCreateFdwStmt(CreateFdwStmt *from)
|
||||||
{
|
{
|
||||||
@ -4028,6 +4040,9 @@ copyObject(void *from)
|
|||||||
case T_DropTableSpaceStmt:
|
case T_DropTableSpaceStmt:
|
||||||
retval = _copyDropTableSpaceStmt(from);
|
retval = _copyDropTableSpaceStmt(from);
|
||||||
break;
|
break;
|
||||||
|
case T_AlterTableSpaceOptionsStmt:
|
||||||
|
retval = _copyAlterTableSpaceOptionsStmt(from);
|
||||||
|
break;
|
||||||
case T_CreateFdwStmt:
|
case T_CreateFdwStmt:
|
||||||
retval = _copyCreateFdwStmt(from);
|
retval = _copyCreateFdwStmt(from);
|
||||||
break;
|
break;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.379 2010/01/02 16:57:46 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.380 2010/01/05 21:53:58 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1568,6 +1568,17 @@ _equalDropTableSpaceStmt(DropTableSpaceStmt *a, DropTableSpaceStmt *b)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_equalAlterTableSpaceOptionsStmt(AlterTableSpaceOptionsStmt *a,
|
||||||
|
AlterTableSpaceOptionsStmt *b)
|
||||||
|
{
|
||||||
|
COMPARE_STRING_FIELD(tablespacename);
|
||||||
|
COMPARE_NODE_FIELD(options);
|
||||||
|
COMPARE_SCALAR_FIELD(isReset);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_equalCreateFdwStmt(CreateFdwStmt *a, CreateFdwStmt *b)
|
_equalCreateFdwStmt(CreateFdwStmt *a, CreateFdwStmt *b)
|
||||||
{
|
{
|
||||||
@ -2720,6 +2731,9 @@ equal(void *a, void *b)
|
|||||||
case T_DropTableSpaceStmt:
|
case T_DropTableSpaceStmt:
|
||||||
retval = _equalDropTableSpaceStmt(a, b);
|
retval = _equalDropTableSpaceStmt(a, b);
|
||||||
break;
|
break;
|
||||||
|
case T_AlterTableSpaceOptionsStmt:
|
||||||
|
retval = _equalAlterTableSpaceOptionsStmt(a, b);
|
||||||
|
break;
|
||||||
case T_CreateFdwStmt:
|
case T_CreateFdwStmt:
|
||||||
retval = _equalCreateFdwStmt(a, b);
|
retval = _equalCreateFdwStmt(a, b);
|
||||||
break;
|
break;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.379 2010/01/02 16:57:46 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.380 2010/01/05 21:53:58 rhaas Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Every node type that can appear in stored rules' parsetrees *must*
|
* Every node type that can appear in stored rules' parsetrees *must*
|
||||||
@ -1590,6 +1590,7 @@ _outRelOptInfo(StringInfo str, RelOptInfo *node)
|
|||||||
WRITE_NODE_FIELD(cheapest_total_path);
|
WRITE_NODE_FIELD(cheapest_total_path);
|
||||||
WRITE_NODE_FIELD(cheapest_unique_path);
|
WRITE_NODE_FIELD(cheapest_unique_path);
|
||||||
WRITE_UINT_FIELD(relid);
|
WRITE_UINT_FIELD(relid);
|
||||||
|
WRITE_UINT_FIELD(reltablespace);
|
||||||
WRITE_ENUM_FIELD(rtekind, RTEKind);
|
WRITE_ENUM_FIELD(rtekind, RTEKind);
|
||||||
WRITE_INT_FIELD(min_attr);
|
WRITE_INT_FIELD(min_attr);
|
||||||
WRITE_INT_FIELD(max_attr);
|
WRITE_INT_FIELD(max_attr);
|
||||||
|
@ -27,6 +27,11 @@
|
|||||||
* detail. Note that all of these parameters are user-settable, in case
|
* detail. Note that all of these parameters are user-settable, in case
|
||||||
* the default values are drastically off for a particular platform.
|
* the default values are drastically off for a particular platform.
|
||||||
*
|
*
|
||||||
|
* seq_page_cost and random_page_cost can also be overridden for an individual
|
||||||
|
* tablespace, in case some data is on a fast disk and other data is on a slow
|
||||||
|
* disk. Per-tablespace overrides never apply to temporary work files such as
|
||||||
|
* an external sort or a materialize node that overflows work_mem.
|
||||||
|
*
|
||||||
* We compute two separate costs for each path:
|
* We compute two separate costs for each path:
|
||||||
* total_cost: total estimated cost to fetch all tuples
|
* total_cost: total estimated cost to fetch all tuples
|
||||||
* startup_cost: cost that is expended before first tuple is fetched
|
* startup_cost: cost that is expended before first tuple is fetched
|
||||||
@ -54,7 +59,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.213 2010/01/02 16:57:46 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.214 2010/01/05 21:53:58 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -76,6 +81,7 @@
|
|||||||
#include "parser/parsetree.h"
|
#include "parser/parsetree.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/selfuncs.h"
|
#include "utils/selfuncs.h"
|
||||||
|
#include "utils/spccache.h"
|
||||||
#include "utils/tuplesort.h"
|
#include "utils/tuplesort.h"
|
||||||
|
|
||||||
|
|
||||||
@ -164,6 +170,7 @@ void
|
|||||||
cost_seqscan(Path *path, PlannerInfo *root,
|
cost_seqscan(Path *path, PlannerInfo *root,
|
||||||
RelOptInfo *baserel)
|
RelOptInfo *baserel)
|
||||||
{
|
{
|
||||||
|
double spc_seq_page_cost;
|
||||||
Cost startup_cost = 0;
|
Cost startup_cost = 0;
|
||||||
Cost run_cost = 0;
|
Cost run_cost = 0;
|
||||||
Cost cpu_per_tuple;
|
Cost cpu_per_tuple;
|
||||||
@ -175,10 +182,15 @@ cost_seqscan(Path *path, PlannerInfo *root,
|
|||||||
if (!enable_seqscan)
|
if (!enable_seqscan)
|
||||||
startup_cost += disable_cost;
|
startup_cost += disable_cost;
|
||||||
|
|
||||||
|
/* fetch estimated page cost for tablespace containing table */
|
||||||
|
get_tablespace_page_costs(baserel->reltablespace,
|
||||||
|
NULL,
|
||||||
|
&spc_seq_page_cost);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* disk costs
|
* disk costs
|
||||||
*/
|
*/
|
||||||
run_cost += seq_page_cost * baserel->pages;
|
run_cost += spc_seq_page_cost * baserel->pages;
|
||||||
|
|
||||||
/* CPU costs */
|
/* CPU costs */
|
||||||
startup_cost += baserel->baserestrictcost.startup;
|
startup_cost += baserel->baserestrictcost.startup;
|
||||||
@ -226,6 +238,8 @@ cost_index(IndexPath *path, PlannerInfo *root,
|
|||||||
Selectivity indexSelectivity;
|
Selectivity indexSelectivity;
|
||||||
double indexCorrelation,
|
double indexCorrelation,
|
||||||
csquared;
|
csquared;
|
||||||
|
double spc_seq_page_cost,
|
||||||
|
spc_random_page_cost;
|
||||||
Cost min_IO_cost,
|
Cost min_IO_cost,
|
||||||
max_IO_cost;
|
max_IO_cost;
|
||||||
Cost cpu_per_tuple;
|
Cost cpu_per_tuple;
|
||||||
@ -272,13 +286,18 @@ cost_index(IndexPath *path, PlannerInfo *root,
|
|||||||
/* estimate number of main-table tuples fetched */
|
/* estimate number of main-table tuples fetched */
|
||||||
tuples_fetched = clamp_row_est(indexSelectivity * baserel->tuples);
|
tuples_fetched = clamp_row_est(indexSelectivity * baserel->tuples);
|
||||||
|
|
||||||
|
/* fetch estimated page costs for tablespace containing table */
|
||||||
|
get_tablespace_page_costs(baserel->reltablespace,
|
||||||
|
&spc_random_page_cost,
|
||||||
|
&spc_seq_page_cost);
|
||||||
|
|
||||||
/*----------
|
/*----------
|
||||||
* Estimate number of main-table pages fetched, and compute I/O cost.
|
* Estimate number of main-table pages fetched, and compute I/O cost.
|
||||||
*
|
*
|
||||||
* When the index ordering is uncorrelated with the table ordering,
|
* When the index ordering is uncorrelated with the table ordering,
|
||||||
* we use an approximation proposed by Mackert and Lohman (see
|
* we use an approximation proposed by Mackert and Lohman (see
|
||||||
* index_pages_fetched() for details) to compute the number of pages
|
* index_pages_fetched() for details) to compute the number of pages
|
||||||
* fetched, and then charge random_page_cost per page fetched.
|
* fetched, and then charge spc_random_page_cost per page fetched.
|
||||||
*
|
*
|
||||||
* When the index ordering is exactly correlated with the table ordering
|
* When the index ordering is exactly correlated with the table ordering
|
||||||
* (just after a CLUSTER, for example), the number of pages fetched should
|
* (just after a CLUSTER, for example), the number of pages fetched should
|
||||||
@ -286,7 +305,7 @@ cost_index(IndexPath *path, PlannerInfo *root,
|
|||||||
* will be sequential fetches, not the random fetches that occur in the
|
* will be sequential fetches, not the random fetches that occur in the
|
||||||
* uncorrelated case. So if the number of pages is more than 1, we
|
* uncorrelated case. So if the number of pages is more than 1, we
|
||||||
* ought to charge
|
* ought to charge
|
||||||
* random_page_cost + (pages_fetched - 1) * seq_page_cost
|
* spc_random_page_cost + (pages_fetched - 1) * spc_seq_page_cost
|
||||||
* For partially-correlated indexes, we ought to charge somewhere between
|
* For partially-correlated indexes, we ought to charge somewhere between
|
||||||
* these two estimates. We currently interpolate linearly between the
|
* these two estimates. We currently interpolate linearly between the
|
||||||
* estimates based on the correlation squared (XXX is that appropriate?).
|
* estimates based on the correlation squared (XXX is that appropriate?).
|
||||||
@ -309,7 +328,7 @@ cost_index(IndexPath *path, PlannerInfo *root,
|
|||||||
(double) index->pages,
|
(double) index->pages,
|
||||||
root);
|
root);
|
||||||
|
|
||||||
max_IO_cost = (pages_fetched * random_page_cost) / num_scans;
|
max_IO_cost = (pages_fetched * spc_random_page_cost) / num_scans;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In the perfectly correlated case, the number of pages touched by
|
* In the perfectly correlated case, the number of pages touched by
|
||||||
@ -328,7 +347,7 @@ cost_index(IndexPath *path, PlannerInfo *root,
|
|||||||
(double) index->pages,
|
(double) index->pages,
|
||||||
root);
|
root);
|
||||||
|
|
||||||
min_IO_cost = (pages_fetched * random_page_cost) / num_scans;
|
min_IO_cost = (pages_fetched * spc_random_page_cost) / num_scans;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -342,13 +361,13 @@ cost_index(IndexPath *path, PlannerInfo *root,
|
|||||||
root);
|
root);
|
||||||
|
|
||||||
/* max_IO_cost is for the perfectly uncorrelated case (csquared=0) */
|
/* max_IO_cost is for the perfectly uncorrelated case (csquared=0) */
|
||||||
max_IO_cost = pages_fetched * random_page_cost;
|
max_IO_cost = pages_fetched * spc_random_page_cost;
|
||||||
|
|
||||||
/* min_IO_cost is for the perfectly correlated case (csquared=1) */
|
/* min_IO_cost is for the perfectly correlated case (csquared=1) */
|
||||||
pages_fetched = ceil(indexSelectivity * (double) baserel->pages);
|
pages_fetched = ceil(indexSelectivity * (double) baserel->pages);
|
||||||
min_IO_cost = random_page_cost;
|
min_IO_cost = spc_random_page_cost;
|
||||||
if (pages_fetched > 1)
|
if (pages_fetched > 1)
|
||||||
min_IO_cost += (pages_fetched - 1) * seq_page_cost;
|
min_IO_cost += (pages_fetched - 1) * spc_seq_page_cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -553,6 +572,8 @@ cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel,
|
|||||||
Cost cost_per_page;
|
Cost cost_per_page;
|
||||||
double tuples_fetched;
|
double tuples_fetched;
|
||||||
double pages_fetched;
|
double pages_fetched;
|
||||||
|
double spc_seq_page_cost,
|
||||||
|
spc_random_page_cost;
|
||||||
double T;
|
double T;
|
||||||
|
|
||||||
/* Should only be applied to base relations */
|
/* Should only be applied to base relations */
|
||||||
@ -571,6 +592,11 @@ cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel,
|
|||||||
|
|
||||||
startup_cost += indexTotalCost;
|
startup_cost += indexTotalCost;
|
||||||
|
|
||||||
|
/* Fetch estimated page costs for tablespace containing table. */
|
||||||
|
get_tablespace_page_costs(baserel->reltablespace,
|
||||||
|
&spc_random_page_cost,
|
||||||
|
&spc_seq_page_cost);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Estimate number of main-table pages fetched.
|
* Estimate number of main-table pages fetched.
|
||||||
*/
|
*/
|
||||||
@ -609,17 +635,18 @@ cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel,
|
|||||||
pages_fetched = ceil(pages_fetched);
|
pages_fetched = ceil(pages_fetched);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For small numbers of pages we should charge random_page_cost apiece,
|
* For small numbers of pages we should charge spc_random_page_cost apiece,
|
||||||
* while if nearly all the table's pages are being read, it's more
|
* while if nearly all the table's pages are being read, it's more
|
||||||
* appropriate to charge seq_page_cost apiece. The effect is nonlinear,
|
* appropriate to charge spc_seq_page_cost apiece. The effect is nonlinear,
|
||||||
* too. For lack of a better idea, interpolate like this to determine the
|
* too. For lack of a better idea, interpolate like this to determine the
|
||||||
* cost per page.
|
* cost per page.
|
||||||
*/
|
*/
|
||||||
if (pages_fetched >= 2.0)
|
if (pages_fetched >= 2.0)
|
||||||
cost_per_page = random_page_cost -
|
cost_per_page = spc_random_page_cost -
|
||||||
(random_page_cost - seq_page_cost) * sqrt(pages_fetched / T);
|
(spc_random_page_cost - spc_seq_page_cost)
|
||||||
|
* sqrt(pages_fetched / T);
|
||||||
else
|
else
|
||||||
cost_per_page = random_page_cost;
|
cost_per_page = spc_random_page_cost;
|
||||||
|
|
||||||
run_cost += pages_fetched * cost_per_page;
|
run_cost += pages_fetched * cost_per_page;
|
||||||
|
|
||||||
@ -783,6 +810,7 @@ cost_tidscan(Path *path, PlannerInfo *root,
|
|||||||
QualCost tid_qual_cost;
|
QualCost tid_qual_cost;
|
||||||
int ntuples;
|
int ntuples;
|
||||||
ListCell *l;
|
ListCell *l;
|
||||||
|
double spc_random_page_cost;
|
||||||
|
|
||||||
/* Should only be applied to base relations */
|
/* Should only be applied to base relations */
|
||||||
Assert(baserel->relid > 0);
|
Assert(baserel->relid > 0);
|
||||||
@ -835,8 +863,13 @@ cost_tidscan(Path *path, PlannerInfo *root,
|
|||||||
*/
|
*/
|
||||||
cost_qual_eval(&tid_qual_cost, tidquals, root);
|
cost_qual_eval(&tid_qual_cost, tidquals, root);
|
||||||
|
|
||||||
|
/* fetch estimated page cost for tablespace containing table */
|
||||||
|
get_tablespace_page_costs(baserel->reltablespace,
|
||||||
|
&spc_random_page_cost,
|
||||||
|
NULL);
|
||||||
|
|
||||||
/* disk costs --- assume each tuple on a different page */
|
/* disk costs --- assume each tuple on a different page */
|
||||||
run_cost += random_page_cost * ntuples;
|
run_cost += spc_random_page_cost * ntuples;
|
||||||
|
|
||||||
/* CPU costs */
|
/* CPU costs */
|
||||||
startup_cost += baserel->baserestrictcost.startup +
|
startup_cost += baserel->baserestrictcost.startup +
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.161 2010/01/02 16:57:48 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.162 2010/01/05 21:53:58 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -91,6 +91,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
|
|||||||
|
|
||||||
rel->min_attr = FirstLowInvalidHeapAttributeNumber + 1;
|
rel->min_attr = FirstLowInvalidHeapAttributeNumber + 1;
|
||||||
rel->max_attr = RelationGetNumberOfAttributes(relation);
|
rel->max_attr = RelationGetNumberOfAttributes(relation);
|
||||||
|
rel->reltablespace = RelationGetForm(relation)->reltablespace;
|
||||||
|
|
||||||
Assert(rel->max_attr >= rel->min_attr);
|
Assert(rel->max_attr >= rel->min_attr);
|
||||||
rel->attr_needed = (Relids *)
|
rel->attr_needed = (Relids *)
|
||||||
@ -183,6 +184,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
|
|||||||
info = makeNode(IndexOptInfo);
|
info = makeNode(IndexOptInfo);
|
||||||
|
|
||||||
info->indexoid = index->indexrelid;
|
info->indexoid = index->indexrelid;
|
||||||
|
info->reltablespace =
|
||||||
|
RelationGetForm(indexRelation)->reltablespace;
|
||||||
info->rel = rel;
|
info->rel = rel;
|
||||||
info->ncolumns = ncolumns = index->indnatts;
|
info->ncolumns = ncolumns = index->indnatts;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.701 2010/01/02 16:57:48 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.702 2010/01/05 21:53:58 rhaas Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -5687,6 +5687,24 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
|
|||||||
n->newname = $6;
|
n->newname = $6;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
|
| ALTER TABLESPACE name SET reloptions
|
||||||
|
{
|
||||||
|
AlterTableSpaceOptionsStmt *n =
|
||||||
|
makeNode(AlterTableSpaceOptionsStmt);
|
||||||
|
n->tablespacename = $3;
|
||||||
|
n->options = $5;
|
||||||
|
n->isReset = FALSE;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
| ALTER TABLESPACE name RESET reloptions
|
||||||
|
{
|
||||||
|
AlterTableSpaceOptionsStmt *n =
|
||||||
|
makeNode(AlterTableSpaceOptionsStmt);
|
||||||
|
n->tablespacename = $3;
|
||||||
|
n->options = $5;
|
||||||
|
n->isReset = TRUE;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
| ALTER TEXT_P SEARCH PARSER any_name RENAME TO name
|
| ALTER TEXT_P SEARCH PARSER any_name RENAME TO name
|
||||||
{
|
{
|
||||||
RenameStmt *n = makeNode(RenameStmt);
|
RenameStmt *n = makeNode(RenameStmt);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.326 2010/01/02 16:57:53 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.327 2010/01/05 21:53:58 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -218,6 +218,7 @@ check_xact_readonly(Node *parsetree)
|
|||||||
case T_CreateUserMappingStmt:
|
case T_CreateUserMappingStmt:
|
||||||
case T_AlterUserMappingStmt:
|
case T_AlterUserMappingStmt:
|
||||||
case T_DropUserMappingStmt:
|
case T_DropUserMappingStmt:
|
||||||
|
case T_AlterTableSpaceOptionsStmt:
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
|
(errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
|
||||||
errmsg("transaction is read-only")));
|
errmsg("transaction is read-only")));
|
||||||
@ -528,6 +529,10 @@ standard_ProcessUtility(Node *parsetree,
|
|||||||
DropTableSpace((DropTableSpaceStmt *) parsetree);
|
DropTableSpace((DropTableSpaceStmt *) parsetree);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_AlterTableSpaceOptionsStmt:
|
||||||
|
AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
|
||||||
|
break;
|
||||||
|
|
||||||
case T_CreateFdwStmt:
|
case T_CreateFdwStmt:
|
||||||
CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
|
CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
|
||||||
break;
|
break;
|
||||||
@ -1456,6 +1461,10 @@ CreateCommandTag(Node *parsetree)
|
|||||||
tag = "DROP TABLESPACE";
|
tag = "DROP TABLESPACE";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_AlterTableSpaceOptionsStmt:
|
||||||
|
tag = "ALTER TABLESPACE";
|
||||||
|
break;
|
||||||
|
|
||||||
case T_CreateFdwStmt:
|
case T_CreateFdwStmt:
|
||||||
tag = "CREATE FOREIGN DATA WRAPPER";
|
tag = "CREATE FOREIGN DATA WRAPPER";
|
||||||
break;
|
break;
|
||||||
@ -2238,6 +2247,10 @@ GetCommandLogLevel(Node *parsetree)
|
|||||||
lev = LOGSTMT_DDL;
|
lev = LOGSTMT_DDL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_AlterTableSpaceOptionsStmt:
|
||||||
|
lev = LOGSTMT_DDL;
|
||||||
|
break;
|
||||||
|
|
||||||
case T_CreateFdwStmt:
|
case T_CreateFdwStmt:
|
||||||
case T_AlterFdwStmt:
|
case T_AlterFdwStmt:
|
||||||
case T_DropFdwStmt:
|
case T_DropFdwStmt:
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.267 2010/01/04 02:44:39 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.268 2010/01/05 21:53:59 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -119,6 +119,7 @@
|
|||||||
#include "utils/nabstime.h"
|
#include "utils/nabstime.h"
|
||||||
#include "utils/pg_locale.h"
|
#include "utils/pg_locale.h"
|
||||||
#include "utils/selfuncs.h"
|
#include "utils/selfuncs.h"
|
||||||
|
#include "utils/spccache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
#include "utils/tqual.h"
|
#include "utils/tqual.h"
|
||||||
|
|
||||||
@ -5648,6 +5649,7 @@ genericcostestimate(PlannerInfo *root,
|
|||||||
QualCost index_qual_cost;
|
QualCost index_qual_cost;
|
||||||
double qual_op_cost;
|
double qual_op_cost;
|
||||||
double qual_arg_cost;
|
double qual_arg_cost;
|
||||||
|
double spc_random_page_cost;
|
||||||
List *selectivityQuals;
|
List *selectivityQuals;
|
||||||
ListCell *l;
|
ListCell *l;
|
||||||
|
|
||||||
@ -5756,6 +5758,11 @@ genericcostestimate(PlannerInfo *root,
|
|||||||
else
|
else
|
||||||
numIndexPages = 1.0;
|
numIndexPages = 1.0;
|
||||||
|
|
||||||
|
/* fetch estimated page cost for schema containing index */
|
||||||
|
get_tablespace_page_costs(index->reltablespace,
|
||||||
|
&spc_random_page_cost,
|
||||||
|
NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now compute the disk access costs.
|
* Now compute the disk access costs.
|
||||||
*
|
*
|
||||||
@ -5802,15 +5809,16 @@ genericcostestimate(PlannerInfo *root,
|
|||||||
* share for each outer scan. (Don't pro-rate for ScalarArrayOpExpr,
|
* share for each outer scan. (Don't pro-rate for ScalarArrayOpExpr,
|
||||||
* since that's internal to the indexscan.)
|
* since that's internal to the indexscan.)
|
||||||
*/
|
*/
|
||||||
*indexTotalCost = (pages_fetched * random_page_cost) / num_outer_scans;
|
*indexTotalCost = (pages_fetched * spc_random_page_cost)
|
||||||
|
/ num_outer_scans;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* For a single index scan, we just charge random_page_cost per page
|
* For a single index scan, we just charge spc_random_page_cost per
|
||||||
* touched.
|
* page touched.
|
||||||
*/
|
*/
|
||||||
*indexTotalCost = numIndexPages * random_page_cost;
|
*indexTotalCost = numIndexPages * spc_random_page_cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5825,11 +5833,11 @@ genericcostestimate(PlannerInfo *root,
|
|||||||
*
|
*
|
||||||
* We can deal with this by adding a very small "fudge factor" that
|
* We can deal with this by adding a very small "fudge factor" that
|
||||||
* depends on the index size. The fudge factor used here is one
|
* depends on the index size. The fudge factor used here is one
|
||||||
* random_page_cost per 100000 index pages, which should be small enough
|
* spc_random_page_cost per 100000 index pages, which should be small
|
||||||
* to not alter index-vs-seqscan decisions, but will prevent indexes of
|
* enough to not alter index-vs-seqscan decisions, but will prevent
|
||||||
* different sizes from looking exactly equally attractive.
|
* indexes of different sizes from looking exactly equally attractive.
|
||||||
*/
|
*/
|
||||||
*indexTotalCost += index->pages * random_page_cost / 100000.0;
|
*indexTotalCost += index->pages * spc_random_page_cost / 100000.0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CPU cost: any complex expressions in the indexquals will need to be
|
* CPU cost: any complex expressions in the indexquals will need to be
|
||||||
|
4
src/backend/utils/cache/Makefile
vendored
4
src/backend/utils/cache/Makefile
vendored
@ -4,7 +4,7 @@
|
|||||||
# Makefile for utils/cache
|
# Makefile for utils/cache
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $PostgreSQL: pgsql/src/backend/utils/cache/Makefile,v 1.23 2008/02/19 10:30:08 petere Exp $
|
# $PostgreSQL: pgsql/src/backend/utils/cache/Makefile,v 1.24 2010/01/05 21:53:59 rhaas Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -13,6 +13,6 @@ top_builddir = ../../../..
|
|||||||
include $(top_builddir)/src/Makefile.global
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
|
||||||
OBJS = catcache.o inval.o plancache.o relcache.o \
|
OBJS = catcache.o inval.o plancache.o relcache.o \
|
||||||
syscache.o lsyscache.o typcache.o ts_cache.o
|
spccache.o syscache.o lsyscache.o typcache.o ts_cache.o
|
||||||
|
|
||||||
include $(top_srcdir)/src/backend/common.mk
|
include $(top_srcdir)/src/backend/common.mk
|
||||||
|
183
src/backend/utils/cache/spccache.c
vendored
Normal file
183
src/backend/utils/cache/spccache.c
vendored
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* spccache.c
|
||||||
|
* Tablespace cache management.
|
||||||
|
*
|
||||||
|
* We cache the parsed version of spcoptions for each tablespace to avoid
|
||||||
|
* needing to reparse on every lookup. Right now, there doesn't appear to
|
||||||
|
* be a measurable performance gain from doing this, but that might change
|
||||||
|
* in the future as we add more options.
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* $PostgreSQL: pgsql/src/backend/utils/cache/spccache.c,v 1.1 2010/01/05 21:53:59 rhaas Exp $
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
#include "access/reloptions.h"
|
||||||
|
#include "catalog/pg_tablespace.h"
|
||||||
|
#include "commands/tablespace.h"
|
||||||
|
#include "miscadmin.h"
|
||||||
|
#include "optimizer/cost.h"
|
||||||
|
#include "utils/catcache.h"
|
||||||
|
#include "utils/hsearch.h"
|
||||||
|
#include "utils/inval.h"
|
||||||
|
#include "utils/spccache.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
static HTAB *TableSpaceCacheHash = NULL;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Oid oid;
|
||||||
|
TableSpaceOpts *opts;
|
||||||
|
} TableSpace;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* InvalidateTableSpaceCacheCallback
|
||||||
|
* Flush all cache entries when pg_tablespace is updated.
|
||||||
|
*
|
||||||
|
* When pg_tablespace is updated, we must flush the cache entry at least
|
||||||
|
* for that tablespace. Currently, we just flush them all. This is quick
|
||||||
|
* and easy and doesn't cost much, since there shouldn't be terribly many
|
||||||
|
* tablespaces, nor do we expect them to be frequently modified.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
InvalidateTableSpaceCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
|
||||||
|
{
|
||||||
|
HASH_SEQ_STATUS status;
|
||||||
|
TableSpace *spc;
|
||||||
|
|
||||||
|
hash_seq_init(&status, TableSpaceCacheHash);
|
||||||
|
while ((spc = (TableSpace *) hash_seq_search(&status)) != NULL)
|
||||||
|
{
|
||||||
|
if (hash_search(TableSpaceCacheHash, (void *) &spc->oid, HASH_REMOVE,
|
||||||
|
NULL) == NULL)
|
||||||
|
elog(ERROR, "hash table corrupted");
|
||||||
|
if (spc->opts)
|
||||||
|
pfree(spc->opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* InitializeTableSpaceCache
|
||||||
|
* Initiate the tablespace cache.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
InitializeTableSpaceCache(void)
|
||||||
|
{
|
||||||
|
HASHCTL ctl;
|
||||||
|
|
||||||
|
/* Initialize the hash table. */
|
||||||
|
MemSet(&ctl, 0, sizeof(ctl));
|
||||||
|
ctl.keysize = sizeof(Oid);
|
||||||
|
ctl.entrysize = sizeof(TableSpace);
|
||||||
|
ctl.hash = tag_hash;
|
||||||
|
TableSpaceCacheHash =
|
||||||
|
hash_create("TableSpace cache", 16, &ctl,
|
||||||
|
HASH_ELEM | HASH_FUNCTION);
|
||||||
|
|
||||||
|
/* Make sure we've initialized CacheMemoryContext. */
|
||||||
|
if (!CacheMemoryContext)
|
||||||
|
CreateCacheMemoryContext();
|
||||||
|
|
||||||
|
/* Watch for invalidation events. */
|
||||||
|
CacheRegisterSyscacheCallback(TABLESPACEOID,
|
||||||
|
InvalidateTableSpaceCacheCallback,
|
||||||
|
(Datum) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_tablespace
|
||||||
|
* Fetch TableSpace structure for a specified table OID.
|
||||||
|
*
|
||||||
|
* Pointers returned by this function should not be stored, since a cache
|
||||||
|
* flush will invalidate them.
|
||||||
|
*/
|
||||||
|
static TableSpace *
|
||||||
|
get_tablespace(Oid spcid)
|
||||||
|
{
|
||||||
|
HeapTuple tp;
|
||||||
|
TableSpace *spc;
|
||||||
|
bool found;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since spcid is always from a pg_class tuple, InvalidOid implies the
|
||||||
|
* default.
|
||||||
|
*/
|
||||||
|
if (spcid == InvalidOid)
|
||||||
|
spcid = MyDatabaseTableSpace;
|
||||||
|
|
||||||
|
/* Find existing cache entry, or create a new one. */
|
||||||
|
if (!TableSpaceCacheHash)
|
||||||
|
InitializeTableSpaceCache();
|
||||||
|
spc = (TableSpace *) hash_search(TableSpaceCacheHash, (void *) &spcid,
|
||||||
|
HASH_ENTER, &found);
|
||||||
|
if (found)
|
||||||
|
return spc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Not found in TableSpace cache. Check catcache. If we don't find a
|
||||||
|
* valid HeapTuple, it must mean someone has managed to request tablespace
|
||||||
|
* details for a non-existent tablespace. We'll just treat that case as if
|
||||||
|
* no options were specified.
|
||||||
|
*/
|
||||||
|
tp = SearchSysCache(TABLESPACEOID, ObjectIdGetDatum(spcid), 0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tp))
|
||||||
|
spc->opts = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Datum datum;
|
||||||
|
bool isNull;
|
||||||
|
MemoryContext octx;
|
||||||
|
|
||||||
|
datum = SysCacheGetAttr(TABLESPACEOID,
|
||||||
|
tp,
|
||||||
|
Anum_pg_tablespace_spcoptions,
|
||||||
|
&isNull);
|
||||||
|
if (isNull)
|
||||||
|
spc->opts = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
octx = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
|
spc->opts = (TableSpaceOpts *) tablespace_reloptions(datum, false);
|
||||||
|
MemoryContextSwitchTo(octx);
|
||||||
|
}
|
||||||
|
ReleaseSysCache(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update new TableSpace cache entry with results of option parsing. */
|
||||||
|
return spc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_tablespace_page_costs
|
||||||
|
* Return random and sequential page costs for a given tablespace.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
get_tablespace_page_costs(Oid spcid, double *spc_random_page_cost,
|
||||||
|
double *spc_seq_page_cost)
|
||||||
|
{
|
||||||
|
TableSpace *spc = get_tablespace(spcid);
|
||||||
|
|
||||||
|
Assert(spc != NULL);
|
||||||
|
|
||||||
|
if (spc_random_page_cost)
|
||||||
|
{
|
||||||
|
if (!spc->opts || spc->opts->random_page_cost < 0)
|
||||||
|
*spc_random_page_cost = random_page_cost;
|
||||||
|
else
|
||||||
|
*spc_random_page_cost = spc->opts->random_page_cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spc_seq_page_cost)
|
||||||
|
{
|
||||||
|
if (!spc->opts || spc->opts->seq_page_cost < 0)
|
||||||
|
*spc_seq_page_cost = seq_page_cost;
|
||||||
|
else
|
||||||
|
*spc_seq_page_cost = spc->opts->seq_page_cost;
|
||||||
|
}
|
||||||
|
}
|
15
src/backend/utils/cache/syscache.c
vendored
15
src/backend/utils/cache/syscache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.123 2010/01/02 16:57:56 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.124 2010/01/05 21:53:59 rhaas Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* These routines allow the parser/planner/executor to perform
|
* These routines allow the parser/planner/executor to perform
|
||||||
@ -43,6 +43,7 @@
|
|||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_rewrite.h"
|
#include "catalog/pg_rewrite.h"
|
||||||
#include "catalog/pg_statistic.h"
|
#include "catalog/pg_statistic.h"
|
||||||
|
#include "catalog/pg_tablespace.h"
|
||||||
#include "catalog/pg_ts_config.h"
|
#include "catalog/pg_ts_config.h"
|
||||||
#include "catalog/pg_ts_config_map.h"
|
#include "catalog/pg_ts_config_map.h"
|
||||||
#include "catalog/pg_ts_dict.h"
|
#include "catalog/pg_ts_dict.h"
|
||||||
@ -609,6 +610,18 @@ static const struct cachedesc cacheinfo[] = {
|
|||||||
},
|
},
|
||||||
1024
|
1024
|
||||||
},
|
},
|
||||||
|
{TableSpaceRelationId, /* TABLESPACEOID */
|
||||||
|
TablespaceOidIndexId,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
{
|
||||||
|
ObjectIdAttributeNumber,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
16
|
||||||
|
},
|
||||||
{TSConfigMapRelationId, /* TSCONFIGMAP */
|
{TSConfigMapRelationId, /* TSCONFIGMAP */
|
||||||
TSConfigMapIndexId,
|
TSConfigMapIndexId,
|
||||||
0,
|
0,
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.129 2010/01/02 16:57:59 momjian Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.130 2010/01/05 21:53:59 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -956,19 +956,28 @@ dumpTablespaces(PGconn *conn)
|
|||||||
* Get all tablespaces except built-in ones (which we assume are named
|
* Get all tablespaces except built-in ones (which we assume are named
|
||||||
* pg_xxx)
|
* pg_xxx)
|
||||||
*/
|
*/
|
||||||
if (server_version >= 80200)
|
if (server_version >= 80500)
|
||||||
res = executeQuery(conn, "SELECT spcname, "
|
res = executeQuery(conn, "SELECT spcname, "
|
||||||
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
|
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
|
||||||
"spclocation, spcacl, "
|
"spclocation, spcacl, "
|
||||||
|
"array_to_string(spcoptions, ', '),"
|
||||||
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
|
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
|
||||||
"FROM pg_catalog.pg_tablespace "
|
"FROM pg_catalog.pg_tablespace "
|
||||||
"WHERE spcname !~ '^pg_' "
|
"WHERE spcname !~ '^pg_' "
|
||||||
"ORDER BY 1");
|
"ORDER BY 1");
|
||||||
|
else if (server_version >= 80200)
|
||||||
|
res = executeQuery(conn, "SELECT spcname, "
|
||||||
|
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
|
||||||
|
"spclocation, spcacl, null, "
|
||||||
|
"pg_catalog.shobj_description(oid, 'pg_tablespace'), "
|
||||||
|
"FROM pg_catalog.pg_tablespace "
|
||||||
|
"WHERE spcname !~ '^pg_' "
|
||||||
|
"ORDER BY 1");
|
||||||
else
|
else
|
||||||
res = executeQuery(conn, "SELECT spcname, "
|
res = executeQuery(conn, "SELECT spcname, "
|
||||||
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
|
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
|
||||||
"spclocation, spcacl, "
|
"spclocation, spcacl, "
|
||||||
"null "
|
"null, null "
|
||||||
"FROM pg_catalog.pg_tablespace "
|
"FROM pg_catalog.pg_tablespace "
|
||||||
"WHERE spcname !~ '^pg_' "
|
"WHERE spcname !~ '^pg_' "
|
||||||
"ORDER BY 1");
|
"ORDER BY 1");
|
||||||
@ -983,7 +992,8 @@ dumpTablespaces(PGconn *conn)
|
|||||||
char *spcowner = PQgetvalue(res, i, 1);
|
char *spcowner = PQgetvalue(res, i, 1);
|
||||||
char *spclocation = PQgetvalue(res, i, 2);
|
char *spclocation = PQgetvalue(res, i, 2);
|
||||||
char *spcacl = PQgetvalue(res, i, 3);
|
char *spcacl = PQgetvalue(res, i, 3);
|
||||||
char *spccomment = PQgetvalue(res, i, 4);
|
char *spcoptions = PQgetvalue(res, i, 4);
|
||||||
|
char *spccomment = PQgetvalue(res, i, 5);
|
||||||
char *fspcname;
|
char *fspcname;
|
||||||
|
|
||||||
/* needed for buildACLCommands() */
|
/* needed for buildACLCommands() */
|
||||||
@ -996,6 +1006,10 @@ dumpTablespaces(PGconn *conn)
|
|||||||
appendStringLiteralConn(buf, spclocation, conn);
|
appendStringLiteralConn(buf, spclocation, conn);
|
||||||
appendPQExpBuffer(buf, ";\n");
|
appendPQExpBuffer(buf, ";\n");
|
||||||
|
|
||||||
|
if (spcoptions && spcoptions[0] != '\0')
|
||||||
|
appendPQExpBuffer(buf, "ALTER TABLESPACE %s SET (%s);\n",
|
||||||
|
fspcname, spcoptions);
|
||||||
|
|
||||||
if (!skip_acls &&
|
if (!skip_acls &&
|
||||||
!buildACLCommands(fspcname, NULL, "TABLESPACE", spcacl, spcowner,
|
!buildACLCommands(fspcname, NULL, "TABLESPACE", spcacl, spcowner,
|
||||||
"", server_version, buf))
|
"", server_version, buf))
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* reloptions.h
|
* reloptions.h
|
||||||
* Core support for relation options (pg_class.reloptions)
|
* Core support for relation and tablespace options (pg_class.reloptions
|
||||||
|
* and pg_tablespace.spcoptions)
|
||||||
*
|
*
|
||||||
* Note: the functions dealing with text-array reloptions values declare
|
* Note: the functions dealing with text-array reloptions values declare
|
||||||
* them as Datum, not ArrayType *, to avoid needing to include array.h
|
* them as Datum, not ArrayType *, to avoid needing to include array.h
|
||||||
@ -11,7 +12,7 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.17 2010/01/02 16:58:00 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.18 2010/01/05 21:53:59 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -39,8 +40,9 @@ typedef enum relopt_kind
|
|||||||
RELOPT_KIND_HASH = (1 << 3),
|
RELOPT_KIND_HASH = (1 << 3),
|
||||||
RELOPT_KIND_GIN = (1 << 4),
|
RELOPT_KIND_GIN = (1 << 4),
|
||||||
RELOPT_KIND_GIST = (1 << 5),
|
RELOPT_KIND_GIST = (1 << 5),
|
||||||
|
RELOPT_KIND_TABLESPACE = (1 << 6),
|
||||||
/* if you add a new kind, make sure you update "last_default" too */
|
/* if you add a new kind, make sure you update "last_default" too */
|
||||||
RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_GIST,
|
RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_TABLESPACE,
|
||||||
/* some compilers treat enums as signed ints, so we can't use 1 << 31 */
|
/* some compilers treat enums as signed ints, so we can't use 1 << 31 */
|
||||||
RELOPT_KIND_MAX = (1 << 30)
|
RELOPT_KIND_MAX = (1 << 30)
|
||||||
} relopt_kind;
|
} relopt_kind;
|
||||||
@ -264,5 +266,6 @@ extern bytea *default_reloptions(Datum reloptions, bool validate,
|
|||||||
extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate);
|
extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate);
|
||||||
extern bytea *index_reloptions(RegProcedure amoptions, Datum reloptions,
|
extern bytea *index_reloptions(RegProcedure amoptions, Datum reloptions,
|
||||||
bool validate);
|
bool validate);
|
||||||
|
extern bytea *tablespace_reloptions(Datum reloptions, bool validate);
|
||||||
|
|
||||||
#endif /* RELOPTIONS_H */
|
#endif /* RELOPTIONS_H */
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.566 2010/01/04 12:50:49 heikki Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.567 2010/01/05 21:53:59 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 201001041
|
#define CATALOG_VERSION_NO 201001051
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_tablespace.h,v 1.14 2010/01/05 01:06:57 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_tablespace.h,v 1.15 2010/01/05 21:53:59 rhaas Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.pl script reads this file and generates .bki
|
* the genbki.pl script reads this file and generates .bki
|
||||||
@ -34,6 +34,7 @@ CATALOG(pg_tablespace,1213) BKI_SHARED_RELATION
|
|||||||
Oid spcowner; /* owner of tablespace */
|
Oid spcowner; /* owner of tablespace */
|
||||||
text spclocation; /* physical location (VAR LENGTH) */
|
text spclocation; /* physical location (VAR LENGTH) */
|
||||||
aclitem spcacl[1]; /* access permissions (VAR LENGTH) */
|
aclitem spcacl[1]; /* access permissions (VAR LENGTH) */
|
||||||
|
text spcoptions[1]; /* per-tablespace options */
|
||||||
} FormData_pg_tablespace;
|
} FormData_pg_tablespace;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
@ -48,14 +49,15 @@ typedef FormData_pg_tablespace *Form_pg_tablespace;
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define Natts_pg_tablespace 4
|
#define Natts_pg_tablespace 5
|
||||||
#define Anum_pg_tablespace_spcname 1
|
#define Anum_pg_tablespace_spcname 1
|
||||||
#define Anum_pg_tablespace_spcowner 2
|
#define Anum_pg_tablespace_spcowner 2
|
||||||
#define Anum_pg_tablespace_spclocation 3
|
#define Anum_pg_tablespace_spclocation 3
|
||||||
#define Anum_pg_tablespace_spcacl 4
|
#define Anum_pg_tablespace_spcacl 4
|
||||||
|
#define Anum_pg_tablespace_spcoptions 5
|
||||||
|
|
||||||
DATA(insert OID = 1663 ( pg_default PGUID "" _null_ ));
|
DATA(insert OID = 1663 ( pg_default PGUID "" _null_ _null_ ));
|
||||||
DATA(insert OID = 1664 ( pg_global PGUID "" _null_ ));
|
DATA(insert OID = 1664 ( pg_global PGUID "" _null_ _null_ ));
|
||||||
|
|
||||||
#define DEFAULTTABLESPACE_OID 1663
|
#define DEFAULTTABLESPACE_OID 1663
|
||||||
#define GLOBALTABLESPACE_OID 1664
|
#define GLOBALTABLESPACE_OID 1664
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.21 2010/01/02 16:58:03 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.22 2010/01/05 21:53:59 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -32,11 +32,17 @@ typedef struct xl_tblspc_drop_rec
|
|||||||
Oid ts_id;
|
Oid ts_id;
|
||||||
} xl_tblspc_drop_rec;
|
} xl_tblspc_drop_rec;
|
||||||
|
|
||||||
|
typedef struct TableSpaceOpts
|
||||||
|
{
|
||||||
|
float8 random_page_cost;
|
||||||
|
float8 seq_page_cost;
|
||||||
|
} TableSpaceOpts;
|
||||||
|
|
||||||
extern void CreateTableSpace(CreateTableSpaceStmt *stmt);
|
extern void CreateTableSpace(CreateTableSpaceStmt *stmt);
|
||||||
extern void DropTableSpace(DropTableSpaceStmt *stmt);
|
extern void DropTableSpace(DropTableSpaceStmt *stmt);
|
||||||
extern void RenameTableSpace(const char *oldname, const char *newname);
|
extern void RenameTableSpace(const char *oldname, const char *newname);
|
||||||
extern void AlterTableSpaceOwner(const char *name, Oid newOwnerId);
|
extern void AlterTableSpaceOwner(const char *name, Oid newOwnerId);
|
||||||
|
extern void AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt);
|
||||||
|
|
||||||
extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
|
extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.232 2010/01/02 16:58:04 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.233 2010/01/05 21:53:59 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -346,6 +346,7 @@ typedef enum NodeTag
|
|||||||
T_CreateUserMappingStmt,
|
T_CreateUserMappingStmt,
|
||||||
T_AlterUserMappingStmt,
|
T_AlterUserMappingStmt,
|
||||||
T_DropUserMappingStmt,
|
T_DropUserMappingStmt,
|
||||||
|
T_AlterTableSpaceOptionsStmt,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TAGS FOR PARSE TREE NODES (parsenodes.h)
|
* TAGS FOR PARSE TREE NODES (parsenodes.h)
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.421 2010/01/02 16:58:04 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.422 2010/01/05 21:53:59 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1477,6 +1477,14 @@ typedef struct DropTableSpaceStmt
|
|||||||
bool missing_ok; /* skip error if missing? */
|
bool missing_ok; /* skip error if missing? */
|
||||||
} DropTableSpaceStmt;
|
} DropTableSpaceStmt;
|
||||||
|
|
||||||
|
typedef struct AlterTableSpaceOptionsStmt
|
||||||
|
{
|
||||||
|
NodeTag type;
|
||||||
|
char *tablespacename;
|
||||||
|
List *options;
|
||||||
|
bool isReset;
|
||||||
|
} AlterTableSpaceOptionsStmt;
|
||||||
|
|
||||||
/* ----------------------
|
/* ----------------------
|
||||||
* Create/Drop FOREIGN DATA WRAPPER Statements
|
* Create/Drop FOREIGN DATA WRAPPER Statements
|
||||||
* ----------------------
|
* ----------------------
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.182 2010/01/02 16:58:07 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.183 2010/01/05 21:54:00 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -371,6 +371,7 @@ typedef struct RelOptInfo
|
|||||||
|
|
||||||
/* information about a base rel (not set for join rels!) */
|
/* information about a base rel (not set for join rels!) */
|
||||||
Index relid;
|
Index relid;
|
||||||
|
Oid reltablespace; /* containing tablespace */
|
||||||
RTEKind rtekind; /* RELATION, SUBQUERY, or FUNCTION */
|
RTEKind rtekind; /* RELATION, SUBQUERY, or FUNCTION */
|
||||||
AttrNumber min_attr; /* smallest attrno of rel (often <0) */
|
AttrNumber min_attr; /* smallest attrno of rel (often <0) */
|
||||||
AttrNumber max_attr; /* largest attrno of rel */
|
AttrNumber max_attr; /* largest attrno of rel */
|
||||||
@ -435,6 +436,7 @@ typedef struct IndexOptInfo
|
|||||||
NodeTag type;
|
NodeTag type;
|
||||||
|
|
||||||
Oid indexoid; /* OID of the index relation */
|
Oid indexoid; /* OID of the index relation */
|
||||||
|
Oid reltablespace; /* tablespace of index (not table) */
|
||||||
RelOptInfo *rel; /* back-link to index's table */
|
RelOptInfo *rel; /* back-link to index's table */
|
||||||
|
|
||||||
/* statistics from pg_class */
|
/* statistics from pg_class */
|
||||||
|
19
src/include/utils/spccache.h
Normal file
19
src/include/utils/spccache.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* spccache.h
|
||||||
|
* Tablespace cache.
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
* $PostgreSQL: pgsql/src/include/utils/spccache.h,v 1.1 2010/01/05 21:54:00 rhaas Exp $
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef SPCCACHE_H
|
||||||
|
#define SPCCACHE_H
|
||||||
|
|
||||||
|
void get_tablespace_page_costs(Oid spcid, float8 *spc_random_page_cost,
|
||||||
|
float8 *spc_seq_page_cost);
|
||||||
|
|
||||||
|
#endif /* SPCCACHE_H */
|
@ -9,7 +9,7 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.77 2010/01/02 16:58:10 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.78 2010/01/05 21:54:00 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -71,6 +71,7 @@ enum SysCacheIdentifier
|
|||||||
RELOID,
|
RELOID,
|
||||||
RULERELNAME,
|
RULERELNAME,
|
||||||
STATRELATTINH,
|
STATRELATTINH,
|
||||||
|
TABLESPACEOID,
|
||||||
TSCONFIGMAP,
|
TSCONFIGMAP,
|
||||||
TSCONFIGNAMENSP,
|
TSCONFIGNAMENSP,
|
||||||
TSCONFIGOID,
|
TSCONFIGOID,
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
-- create a tablespace we can use
|
-- create a tablespace we can use
|
||||||
CREATE TABLESPACE testspace LOCATION '@testtablespace@';
|
CREATE TABLESPACE testspace LOCATION '@testtablespace@';
|
||||||
|
|
||||||
|
-- try setting and resetting some properties for the new tablespace
|
||||||
|
ALTER TABLESPACE testspace SET (random_page_cost = 1.0);
|
||||||
|
ALTER TABLESPACE testspace SET (some_nonexistent_parameter = true); -- fail
|
||||||
|
ALTER TABLESPACE testspace RESET (random_page_cost = 2.0); -- fail
|
||||||
|
ALTER TABLESPACE testspace RESET (random_page_cost, seq_page_cost); -- ok
|
||||||
|
|
||||||
-- create a schema we can use
|
-- create a schema we can use
|
||||||
CREATE SCHEMA testschema;
|
CREATE SCHEMA testschema;
|
||||||
|
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
-- create a tablespace we can use
|
-- create a tablespace we can use
|
||||||
CREATE TABLESPACE testspace LOCATION '@testtablespace@';
|
CREATE TABLESPACE testspace LOCATION '@testtablespace@';
|
||||||
|
-- try setting and resetting some properties for the new tablespace
|
||||||
|
ALTER TABLESPACE testspace SET (random_page_cost = 1.0);
|
||||||
|
ALTER TABLESPACE testspace SET (some_nonexistent_parameter = true); -- fail
|
||||||
|
ERROR: unrecognized parameter "some_nonexistent_parameter"
|
||||||
|
ALTER TABLESPACE testspace RESET (random_page_cost = 2.0); -- fail
|
||||||
|
ERROR: RESET must not include values for parameters
|
||||||
|
ALTER TABLESPACE testspace RESET (random_page_cost, seq_page_cost); -- ok
|
||||||
-- create a schema we can use
|
-- create a schema we can use
|
||||||
CREATE SCHEMA testschema;
|
CREATE SCHEMA testschema;
|
||||||
-- try a table
|
-- try a table
|
||||||
|
Loading…
x
Reference in New Issue
Block a user