mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +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:
4
src/backend/utils/cache/Makefile
vendored
4
src/backend/utils/cache/Makefile
vendored
@ -4,7 +4,7 @@
|
||||
# Makefile for utils/cache
|
||||
#
|
||||
# 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
|
||||
|
||||
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
|
||||
|
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
|
||||
* $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
|
||||
* These routines allow the parser/planner/executor to perform
|
||||
@ -43,6 +43,7 @@
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "catalog/pg_rewrite.h"
|
||||
#include "catalog/pg_statistic.h"
|
||||
#include "catalog/pg_tablespace.h"
|
||||
#include "catalog/pg_ts_config.h"
|
||||
#include "catalog/pg_ts_config_map.h"
|
||||
#include "catalog/pg_ts_dict.h"
|
||||
@ -609,6 +610,18 @@ static const struct cachedesc cacheinfo[] = {
|
||||
},
|
||||
1024
|
||||
},
|
||||
{TableSpaceRelationId, /* TABLESPACEOID */
|
||||
TablespaceOidIndexId,
|
||||
0,
|
||||
1,
|
||||
{
|
||||
ObjectIdAttributeNumber,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
16
|
||||
},
|
||||
{TSConfigMapRelationId, /* TSCONFIGMAP */
|
||||
TSConfigMapIndexId,
|
||||
0,
|
||||
|
Reference in New Issue
Block a user