mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-30 18:51:20 +02:00
Fix spccache.c to not suppose that a cache entry will live across database
access, per testing with CLOBBER_CACHE_ALWAYS. Minor other editorialization.
This commit is contained in:
parent
64b9c850e9
commit
9261b19fb5
75
src/backend/utils/cache/spccache.c
vendored
75
src/backend/utils/cache/spccache.c
vendored
@ -12,12 +12,12 @@
|
|||||||
* 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/utils/cache/spccache.c,v 1.2 2010/01/06 22:27:09 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/cache/spccache.c,v 1.3 2010/01/06 23:00:02 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "access/reloptions.h"
|
#include "access/reloptions.h"
|
||||||
#include "catalog/pg_tablespace.h"
|
#include "catalog/pg_tablespace.h"
|
||||||
#include "commands/tablespace.h"
|
#include "commands/tablespace.h"
|
||||||
@ -29,12 +29,16 @@
|
|||||||
#include "utils/spccache.h"
|
#include "utils/spccache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Hash table for information about each tablespace */
|
||||||
static HTAB *TableSpaceCacheHash = NULL;
|
static HTAB *TableSpaceCacheHash = NULL;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
Oid oid;
|
{
|
||||||
TableSpaceOpts *opts;
|
Oid oid; /* lookup key - must be first */
|
||||||
} TableSpace;
|
TableSpaceOpts *opts; /* options, or NULL if none */
|
||||||
|
} TableSpaceCacheEntry;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* InvalidateTableSpaceCacheCallback
|
* InvalidateTableSpaceCacheCallback
|
||||||
@ -49,10 +53,10 @@ static void
|
|||||||
InvalidateTableSpaceCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
|
InvalidateTableSpaceCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
|
||||||
{
|
{
|
||||||
HASH_SEQ_STATUS status;
|
HASH_SEQ_STATUS status;
|
||||||
TableSpace *spc;
|
TableSpaceCacheEntry *spc;
|
||||||
|
|
||||||
hash_seq_init(&status, TableSpaceCacheHash);
|
hash_seq_init(&status, TableSpaceCacheHash);
|
||||||
while ((spc = (TableSpace *) hash_seq_search(&status)) != NULL)
|
while ((spc = (TableSpaceCacheEntry *) hash_seq_search(&status)) != NULL)
|
||||||
{
|
{
|
||||||
if (spc->opts)
|
if (spc->opts)
|
||||||
pfree(spc->opts);
|
pfree(spc->opts);
|
||||||
@ -66,7 +70,7 @@ InvalidateTableSpaceCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* InitializeTableSpaceCache
|
* InitializeTableSpaceCache
|
||||||
* Initiate the tablespace cache.
|
* Initialize the tablespace cache.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
InitializeTableSpaceCache(void)
|
InitializeTableSpaceCache(void)
|
||||||
@ -76,8 +80,8 @@ InitializeTableSpaceCache(void)
|
|||||||
/* Initialize the hash table. */
|
/* Initialize the hash table. */
|
||||||
MemSet(&ctl, 0, sizeof(ctl));
|
MemSet(&ctl, 0, sizeof(ctl));
|
||||||
ctl.keysize = sizeof(Oid);
|
ctl.keysize = sizeof(Oid);
|
||||||
ctl.entrysize = sizeof(TableSpace);
|
ctl.entrysize = sizeof(TableSpaceCacheEntry);
|
||||||
ctl.hash = tag_hash;
|
ctl.hash = oid_hash;
|
||||||
TableSpaceCacheHash =
|
TableSpaceCacheHash =
|
||||||
hash_create("TableSpace cache", 16, &ctl,
|
hash_create("TableSpace cache", 16, &ctl,
|
||||||
HASH_ELEM | HASH_FUNCTION);
|
HASH_ELEM | HASH_FUNCTION);
|
||||||
@ -94,17 +98,17 @@ InitializeTableSpaceCache(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* get_tablespace
|
* get_tablespace
|
||||||
* Fetch TableSpace structure for a specified table OID.
|
* Fetch TableSpaceCacheEntry structure for a specified table OID.
|
||||||
*
|
*
|
||||||
* Pointers returned by this function should not be stored, since a cache
|
* Pointers returned by this function should not be stored, since a cache
|
||||||
* flush will invalidate them.
|
* flush will invalidate them.
|
||||||
*/
|
*/
|
||||||
static TableSpace *
|
static TableSpaceCacheEntry *
|
||||||
get_tablespace(Oid spcid)
|
get_tablespace(Oid spcid)
|
||||||
{
|
{
|
||||||
|
TableSpaceCacheEntry *spc;
|
||||||
HeapTuple tp;
|
HeapTuple tp;
|
||||||
TableSpace *spc;
|
TableSpaceOpts *opts;
|
||||||
bool found;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since spcid is always from a pg_class tuple, InvalidOid implies the
|
* Since spcid is always from a pg_class tuple, InvalidOid implies the
|
||||||
@ -113,12 +117,14 @@ get_tablespace(Oid spcid)
|
|||||||
if (spcid == InvalidOid)
|
if (spcid == InvalidOid)
|
||||||
spcid = MyDatabaseTableSpace;
|
spcid = MyDatabaseTableSpace;
|
||||||
|
|
||||||
/* Find existing cache entry, or create a new one. */
|
/* Find existing cache entry, if any. */
|
||||||
if (!TableSpaceCacheHash)
|
if (!TableSpaceCacheHash)
|
||||||
InitializeTableSpaceCache();
|
InitializeTableSpaceCache();
|
||||||
spc = (TableSpace *) hash_search(TableSpaceCacheHash, (void *) &spcid,
|
spc = (TableSpaceCacheEntry *) hash_search(TableSpaceCacheHash,
|
||||||
HASH_ENTER, &found);
|
(void *) &spcid,
|
||||||
if (found)
|
HASH_FIND,
|
||||||
|
NULL);
|
||||||
|
if (spc)
|
||||||
return spc;
|
return spc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -127,9 +133,11 @@ get_tablespace(Oid spcid)
|
|||||||
* details for a non-existent tablespace. We'll just treat that case as if
|
* details for a non-existent tablespace. We'll just treat that case as if
|
||||||
* no options were specified.
|
* no options were specified.
|
||||||
*/
|
*/
|
||||||
tp = SearchSysCache(TABLESPACEOID, ObjectIdGetDatum(spcid), 0, 0, 0);
|
tp = SearchSysCache(TABLESPACEOID,
|
||||||
|
ObjectIdGetDatum(spcid),
|
||||||
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tp))
|
if (!HeapTupleIsValid(tp))
|
||||||
spc->opts = NULL;
|
opts = NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Datum datum;
|
Datum datum;
|
||||||
@ -141,29 +149,40 @@ get_tablespace(Oid spcid)
|
|||||||
Anum_pg_tablespace_spcoptions,
|
Anum_pg_tablespace_spcoptions,
|
||||||
&isNull);
|
&isNull);
|
||||||
if (isNull)
|
if (isNull)
|
||||||
spc->opts = NULL;
|
opts = NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* XXX should NOT do the parsing work in CacheMemoryContext */
|
||||||
octx = MemoryContextSwitchTo(CacheMemoryContext);
|
octx = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
spc->opts = (TableSpaceOpts *) tablespace_reloptions(datum, false);
|
opts = (TableSpaceOpts *) tablespace_reloptions(datum, false);
|
||||||
MemoryContextSwitchTo(octx);
|
MemoryContextSwitchTo(octx);
|
||||||
}
|
}
|
||||||
ReleaseSysCache(tp);
|
ReleaseSysCache(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update new TableSpace cache entry with results of option parsing. */
|
/*
|
||||||
|
* Now create the cache entry. It's important to do this only after
|
||||||
|
* reading the pg_tablespace entry, since doing so could cause a cache
|
||||||
|
* flush.
|
||||||
|
*/
|
||||||
|
spc = (TableSpaceCacheEntry *) hash_search(TableSpaceCacheHash,
|
||||||
|
(void *) &spcid,
|
||||||
|
HASH_ENTER,
|
||||||
|
NULL);
|
||||||
|
spc->opts = opts;
|
||||||
return spc;
|
return spc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_tablespace_page_costs
|
* get_tablespace_page_costs
|
||||||
* Return random and sequential page costs for a given tablespace.
|
* Return random and/or sequential page costs for a given tablespace.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
get_tablespace_page_costs(Oid spcid, double *spc_random_page_cost,
|
get_tablespace_page_costs(Oid spcid,
|
||||||
double *spc_seq_page_cost)
|
double *spc_random_page_cost,
|
||||||
|
double *spc_seq_page_cost)
|
||||||
{
|
{
|
||||||
TableSpace *spc = get_tablespace(spcid);
|
TableSpaceCacheEntry *spc = get_tablespace(spcid);
|
||||||
|
|
||||||
Assert(spc != NULL);
|
Assert(spc != NULL);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user