diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/heap.c | 57 | ||||
-rw-r--r-- | src/backend/commands/tablespace.c | 16 | ||||
-rw-r--r-- | src/backend/storage/smgr/smgr.c | 16 |
3 files changed, 55 insertions, 34 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 68ea6f45f69..1dbe77a8f53 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; @@ -269,6 +264,25 @@ heap_create(const char *relname, 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. */ rel = RelationBuildLocalRelation(relname, @@ -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 875fb1cae8a..a08c12305a7 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 5c53d48f838..5ad43955e46 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(), |