Move TablespaceCreateDbspace() call into smgrcreate(), which is where it
probably should have been to begin with; this is to cover cases like needing to recreate the per-db directory during WAL replay. Also, fix heap_create to force pg_class.reltablespace to be zero instead of the database's default tablespace; this makes the world safe for CREATE DATABASE to handle all tables in the default tablespace alike, as per previous discussion. And force pg_class.reltablespace to zero when creating a relation without physical storage (eg, a view); this avoids possibly having dangling references in this column after a subsequent DROP TABLESPACE.
This commit is contained in:
parent
94d4d240bb
commit
8801110b20
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.271 2004/06/18 06:13:19 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.272 2004/07/11 19:52:48 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
|
@ -43,7 +43,6 @@
|
||||||
#include "catalog/pg_statistic.h"
|
#include "catalog/pg_statistic.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/tablecmds.h"
|
#include "commands/tablecmds.h"
|
||||||
#include "commands/tablespace.h"
|
|
||||||
#include "commands/trigger.h"
|
#include "commands/trigger.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
|
@ -195,10 +194,6 @@ SystemAttributeByName(const char *attname, bool relhasoids)
|
||||||
* and is mostly zeroes at return.
|
* and is mostly zeroes at return.
|
||||||
*
|
*
|
||||||
* Remove the system relation specific code to elsewhere eventually.
|
* Remove the system relation specific code to elsewhere eventually.
|
||||||
*
|
|
||||||
* If storage_create is TRUE then heap_storage_create is called here,
|
|
||||||
* else caller must call heap_storage_create later (or not at all,
|
|
||||||
* if the relation doesn't need physical storage).
|
|
||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
Relation
|
Relation
|
||||||
|
@ -207,7 +202,7 @@ heap_create(const char *relname,
|
||||||
Oid reltablespace,
|
Oid reltablespace,
|
||||||
TupleDesc tupDesc,
|
TupleDesc tupDesc,
|
||||||
bool shared_relation,
|
bool shared_relation,
|
||||||
bool storage_create,
|
bool create_storage,
|
||||||
bool allow_system_table_mods)
|
bool allow_system_table_mods)
|
||||||
{
|
{
|
||||||
Oid relid;
|
Oid relid;
|
||||||
|
@ -268,6 +263,25 @@ heap_create(const char *relname,
|
||||||
else
|
else
|
||||||
relid = newoid();
|
relid = newoid();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Never allow a pg_class entry to explicitly specify the database's
|
||||||
|
* default tablespace in reltablespace; force it to zero instead.
|
||||||
|
* This ensures that if the database is cloned with a different
|
||||||
|
* default tablespace, the pg_class entry will still match where
|
||||||
|
* CREATE DATABASE will put the physically copied relation.
|
||||||
|
*
|
||||||
|
* Yes, this is a bit of a hack.
|
||||||
|
*/
|
||||||
|
if (reltablespace == MyDatabaseTableSpace)
|
||||||
|
reltablespace = InvalidOid;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Also, force reltablespace to zero if the relation has no physical
|
||||||
|
* storage. This is mainly just for cleanliness' sake.
|
||||||
|
*/
|
||||||
|
if (!create_storage)
|
||||||
|
reltablespace = InvalidOid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* build the relcache entry.
|
* build the relcache entry.
|
||||||
*/
|
*/
|
||||||
|
@ -280,31 +294,16 @@ heap_create(const char *relname,
|
||||||
nailme);
|
nailme);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* have the storage manager create the relation's disk file, if
|
* have the storage manager create the relation's disk file, if needed.
|
||||||
* wanted.
|
|
||||||
*/
|
|
||||||
if (storage_create)
|
|
||||||
heap_storage_create(rel);
|
|
||||||
|
|
||||||
return rel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
heap_storage_create(Relation rel)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We may be using the target table space for the first time in this
|
|
||||||
* database, so create a per-database subdirectory if needed.
|
|
||||||
*
|
|
||||||
* XXX it might be better to do this right in smgrcreate...
|
|
||||||
*/
|
|
||||||
TablespaceCreateDbspace(rel->rd_node.spcNode, rel->rd_node.dbNode);
|
|
||||||
/*
|
|
||||||
* Now we can make the file.
|
|
||||||
*/
|
*/
|
||||||
|
if (create_storage)
|
||||||
|
{
|
||||||
Assert(rel->rd_smgr == NULL);
|
Assert(rel->rd_smgr == NULL);
|
||||||
rel->rd_smgr = smgropen(rel->rd_node);
|
rel->rd_smgr = smgropen(rel->rd_node);
|
||||||
smgrcreate(rel->rd_smgr, rel->rd_istemp, false);
|
smgrcreate(rel->rd_smgr, rel->rd_istemp, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.5 2004/07/02 18:59:22 joe Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.6 2004/07/11 19:52:49 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -85,9 +85,13 @@ static bool directory_is_empty(const char *path);
|
||||||
*
|
*
|
||||||
* If tablespaces are not supported, this is just a no-op; CREATE DATABASE
|
* If tablespaces are not supported, this is just a no-op; CREATE DATABASE
|
||||||
* is expected to create the default subdirectory for the database.
|
* is expected to create the default subdirectory for the database.
|
||||||
|
*
|
||||||
|
* isRedo indicates that we are creating an object during WAL replay;
|
||||||
|
* we can skip doing locking in that case (and should do so to avoid
|
||||||
|
* any possible problems with pg_tablespace not being valid).
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TablespaceCreateDbspace(Oid spcNode, Oid dbNode)
|
TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_SYMLINK
|
#ifdef HAVE_SYMLINK
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -116,7 +120,10 @@ TablespaceCreateDbspace(Oid spcNode, Oid dbNode)
|
||||||
*/
|
*/
|
||||||
Relation rel;
|
Relation rel;
|
||||||
|
|
||||||
|
if (!isRedo)
|
||||||
rel = heap_openr(TableSpaceRelationName, ExclusiveLock);
|
rel = heap_openr(TableSpaceRelationName, ExclusiveLock);
|
||||||
|
else
|
||||||
|
rel = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recheck to see if someone created the directory while
|
* Recheck to see if someone created the directory while
|
||||||
|
@ -137,6 +144,7 @@ TablespaceCreateDbspace(Oid spcNode, Oid dbNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OK to drop the exclusive lock */
|
/* OK to drop the exclusive lock */
|
||||||
|
if (!isRedo)
|
||||||
heap_close(rel, ExclusiveLock);
|
heap_close(rel, ExclusiveLock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -11,12 +11,13 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.75 2004/07/01 00:51:07 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.76 2004/07/11 19:52:51 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "commands/tablespace.h"
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
#include "storage/freespace.h"
|
#include "storage/freespace.h"
|
||||||
#include "storage/ipc.h"
|
#include "storage/ipc.h"
|
||||||
|
@ -309,6 +310,19 @@ smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo)
|
||||||
PendingRelDelete *pending;
|
PendingRelDelete *pending;
|
||||||
MemoryContext old_cxt;
|
MemoryContext old_cxt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may be using the target table space for the first time in this
|
||||||
|
* database, so create a per-database subdirectory if needed.
|
||||||
|
*
|
||||||
|
* XXX this is a fairly ugly violation of module layering, but this seems
|
||||||
|
* to be the best place to put the check. Maybe TablespaceCreateDbspace
|
||||||
|
* should be here and not in commands/tablespace.c? But that would imply
|
||||||
|
* importing a lot of stuff that smgr.c oughtn't know, either.
|
||||||
|
*/
|
||||||
|
TablespaceCreateDbspace(reln->smgr_rnode.spcNode,
|
||||||
|
reln->smgr_rnode.dbNode,
|
||||||
|
isRedo);
|
||||||
|
|
||||||
if (! (*(smgrsw[reln->smgr_which].smgr_create)) (reln, isRedo))
|
if (! (*(smgrsw[reln->smgr_which].smgr_create)) (reln, isRedo))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode_for_file_access(),
|
(errcode_for_file_access(),
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, 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/heap.h,v 1.67 2004/06/18 06:14:05 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.68 2004/07/11 19:52:51 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -40,11 +40,9 @@ extern Relation heap_create(const char *relname,
|
||||||
Oid reltablespace,
|
Oid reltablespace,
|
||||||
TupleDesc tupDesc,
|
TupleDesc tupDesc,
|
||||||
bool shared_relation,
|
bool shared_relation,
|
||||||
bool storage_create,
|
bool create_storage,
|
||||||
bool allow_system_table_mods);
|
bool allow_system_table_mods);
|
||||||
|
|
||||||
extern void heap_storage_create(Relation rel);
|
|
||||||
|
|
||||||
extern Oid heap_create_with_catalog(const char *relname,
|
extern Oid heap_create_with_catalog(const char *relname,
|
||||||
Oid relnamespace,
|
Oid relnamespace,
|
||||||
Oid reltablespace,
|
Oid reltablespace,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2004, 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.2 2004/06/25 21:55:58 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.3 2004/07/11 19:52:52 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -20,7 +20,7 @@ extern void CreateTableSpace(CreateTableSpaceStmt *stmt);
|
||||||
|
|
||||||
extern void DropTableSpace(DropTableSpaceStmt *stmt);
|
extern void DropTableSpace(DropTableSpaceStmt *stmt);
|
||||||
|
|
||||||
extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode);
|
extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
|
||||||
|
|
||||||
extern Oid get_tablespace_oid(const char *tablespacename);
|
extern Oid get_tablespace_oid(const char *tablespacename);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue