diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 68ea6f45f6..1dbe77a8f5 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -8,7 +8,7 @@ * * * 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 @@ -43,7 +43,6 @@ #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" #include "commands/tablecmds.h" -#include "commands/tablespace.h" #include "commands/trigger.h" #include "miscadmin.h" #include "nodes/makefuncs.h" @@ -195,10 +194,6 @@ SystemAttributeByName(const char *attname, bool relhasoids) * and is mostly zeroes at return. * * 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 @@ -207,7 +202,7 @@ heap_create(const char *relname, Oid reltablespace, TupleDesc tupDesc, bool shared_relation, - bool storage_create, + bool create_storage, bool allow_system_table_mods) { Oid relid; @@ -268,6 +263,25 @@ heap_create(const char *relname, else 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. */ @@ -280,33 +294,18 @@ heap_create(const char *relname, nailme); /* - * have the storage manager create the relation's disk file, if - * wanted. + * have the storage manager create the relation's disk file, if needed. */ - if (storage_create) - heap_storage_create(rel); + if (create_storage) + { + Assert(rel->rd_smgr == NULL); + rel->rd_smgr = smgropen(rel->rd_node); + smgrcreate(rel->rd_smgr, rel->rd_istemp, false); + } 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. - */ - Assert(rel->rd_smgr == NULL); - rel->rd_smgr = smgropen(rel->rd_node); - smgrcreate(rel->rd_smgr, rel->rd_istemp, false); -} - /* ---------------------------------------------------------------- * heap_create_with_catalog - Create a cataloged relation * diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 875fb1cae8..a08c12305a 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -45,7 +45,7 @@ * * * 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 * 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 -TablespaceCreateDbspace(Oid spcNode, Oid dbNode) +TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo) { #ifdef HAVE_SYMLINK struct stat st; @@ -116,7 +120,10 @@ TablespaceCreateDbspace(Oid spcNode, Oid dbNode) */ Relation rel; - rel = heap_openr(TableSpaceRelationName, ExclusiveLock); + if (!isRedo) + rel = heap_openr(TableSpaceRelationName, ExclusiveLock); + else + rel = NULL; /* * Recheck to see if someone created the directory while @@ -137,7 +144,8 @@ TablespaceCreateDbspace(Oid spcNode, Oid dbNode) } /* OK to drop the exclusive lock */ - heap_close(rel, ExclusiveLock); + if (!isRedo) + heap_close(rel, ExclusiveLock); } else { diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index 5c53d48f83..5ad43955e4 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -11,12 +11,13 @@ * * * 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 "commands/tablespace.h" #include "storage/bufmgr.h" #include "storage/freespace.h" #include "storage/ipc.h" @@ -309,6 +310,19 @@ smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo) PendingRelDelete *pending; 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)) ereport(ERROR, (errcode_for_file_access(), diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 4ead9728df..06f0f4da3a 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * 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, TupleDesc tupDesc, bool shared_relation, - bool storage_create, + bool create_storage, bool allow_system_table_mods); -extern void heap_storage_create(Relation rel); - extern Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltablespace, diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h index 17821493f4..42093c5150 100644 --- a/src/include/commands/tablespace.h +++ b/src/include/commands/tablespace.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group * 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 TablespaceCreateDbspace(Oid spcNode, Oid dbNode); +extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo); extern Oid get_tablespace_oid(const char *tablespacename);