Skip to content

Commit 8801110

Browse files
committed
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.
1 parent 94d4d24 commit 8801110

File tree

5 files changed

+59
-40
lines changed

5 files changed

+59
-40
lines changed

src/backend/catalog/heap.c

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.271 2004/06/18 06:13:19 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.272 2004/07/11 19:52:48 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -43,7 +43,6 @@
4343
#include "catalog/pg_statistic.h"
4444
#include "catalog/pg_type.h"
4545
#include "commands/tablecmds.h"
46-
#include "commands/tablespace.h"
4746
#include "commands/trigger.h"
4847
#include "miscadmin.h"
4948
#include "nodes/makefuncs.h"
@@ -195,10 +194,6 @@ SystemAttributeByName(const char *attname, bool relhasoids)
195194
* and is mostly zeroes at return.
196195
*
197196
* Remove the system relation specific code to elsewhere eventually.
198-
*
199-
* If storage_create is TRUE then heap_storage_create is called here,
200-
* else caller must call heap_storage_create later (or not at all,
201-
* if the relation doesn't need physical storage).
202197
* ----------------------------------------------------------------
203198
*/
204199
Relation
@@ -207,7 +202,7 @@ heap_create(const char *relname,
207202
Oid reltablespace,
208203
TupleDesc tupDesc,
209204
bool shared_relation,
210-
bool storage_create,
205+
bool create_storage,
211206
bool allow_system_table_mods)
212207
{
213208
Oid relid;
@@ -268,6 +263,25 @@ heap_create(const char *relname,
268263
else
269264
relid = newoid();
270265

266+
/*
267+
* Never allow a pg_class entry to explicitly specify the database's
268+
* default tablespace in reltablespace; force it to zero instead.
269+
* This ensures that if the database is cloned with a different
270+
* default tablespace, the pg_class entry will still match where
271+
* CREATE DATABASE will put the physically copied relation.
272+
*
273+
* Yes, this is a bit of a hack.
274+
*/
275+
if (reltablespace == MyDatabaseTableSpace)
276+
reltablespace = InvalidOid;
277+
278+
/*
279+
* Also, force reltablespace to zero if the relation has no physical
280+
* storage. This is mainly just for cleanliness' sake.
281+
*/
282+
if (!create_storage)
283+
reltablespace = InvalidOid;
284+
271285
/*
272286
* build the relcache entry.
273287
*/
@@ -280,33 +294,18 @@ heap_create(const char *relname,
280294
nailme);
281295

282296
/*
283-
* have the storage manager create the relation's disk file, if
284-
* wanted.
297+
* have the storage manager create the relation's disk file, if needed.
285298
*/
286-
if (storage_create)
287-
heap_storage_create(rel);
299+
if (create_storage)
300+
{
301+
Assert(rel->rd_smgr == NULL);
302+
rel->rd_smgr = smgropen(rel->rd_node);
303+
smgrcreate(rel->rd_smgr, rel->rd_istemp, false);
304+
}
288305

289306
return rel;
290307
}
291308

292-
void
293-
heap_storage_create(Relation rel)
294-
{
295-
/*
296-
* We may be using the target table space for the first time in this
297-
* database, so create a per-database subdirectory if needed.
298-
*
299-
* XXX it might be better to do this right in smgrcreate...
300-
*/
301-
TablespaceCreateDbspace(rel->rd_node.spcNode, rel->rd_node.dbNode);
302-
/*
303-
* Now we can make the file.
304-
*/
305-
Assert(rel->rd_smgr == NULL);
306-
rel->rd_smgr = smgropen(rel->rd_node);
307-
smgrcreate(rel->rd_smgr, rel->rd_istemp, false);
308-
}
309-
310309
/* ----------------------------------------------------------------
311310
* heap_create_with_catalog - Create a cataloged relation
312311
*

src/backend/commands/tablespace.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
*
4646
*
4747
* IDENTIFICATION
48-
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.5 2004/07/02 18:59:22 joe Exp $
48+
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.6 2004/07/11 19:52:49 tgl Exp $
4949
*
5050
*-------------------------------------------------------------------------
5151
*/
@@ -85,9 +85,13 @@ static bool directory_is_empty(const char *path);
8585
*
8686
* If tablespaces are not supported, this is just a no-op; CREATE DATABASE
8787
* is expected to create the default subdirectory for the database.
88+
*
89+
* isRedo indicates that we are creating an object during WAL replay;
90+
* we can skip doing locking in that case (and should do so to avoid
91+
* any possible problems with pg_tablespace not being valid).
8892
*/
8993
void
90-
TablespaceCreateDbspace(Oid spcNode, Oid dbNode)
94+
TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo)
9195
{
9296
#ifdef HAVE_SYMLINK
9397
struct stat st;
@@ -116,7 +120,10 @@ TablespaceCreateDbspace(Oid spcNode, Oid dbNode)
116120
*/
117121
Relation rel;
118122

119-
rel = heap_openr(TableSpaceRelationName, ExclusiveLock);
123+
if (!isRedo)
124+
rel = heap_openr(TableSpaceRelationName, ExclusiveLock);
125+
else
126+
rel = NULL;
120127

121128
/*
122129
* Recheck to see if someone created the directory while
@@ -137,7 +144,8 @@ TablespaceCreateDbspace(Oid spcNode, Oid dbNode)
137144
}
138145

139146
/* OK to drop the exclusive lock */
140-
heap_close(rel, ExclusiveLock);
147+
if (!isRedo)
148+
heap_close(rel, ExclusiveLock);
141149
}
142150
else
143151
{

src/backend/storage/smgr/smgr.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.75 2004/07/01 00:51:07 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.76 2004/07/11 19:52:51 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
1818
#include "postgres.h"
1919

20+
#include "commands/tablespace.h"
2021
#include "storage/bufmgr.h"
2122
#include "storage/freespace.h"
2223
#include "storage/ipc.h"
@@ -309,6 +310,19 @@ smgrcreate(SMgrRelation reln, bool isTemp, bool isRedo)
309310
PendingRelDelete *pending;
310311
MemoryContext old_cxt;
311312

313+
/*
314+
* We may be using the target table space for the first time in this
315+
* database, so create a per-database subdirectory if needed.
316+
*
317+
* XXX this is a fairly ugly violation of module layering, but this seems
318+
* to be the best place to put the check. Maybe TablespaceCreateDbspace
319+
* should be here and not in commands/tablespace.c? But that would imply
320+
* importing a lot of stuff that smgr.c oughtn't know, either.
321+
*/
322+
TablespaceCreateDbspace(reln->smgr_rnode.spcNode,
323+
reln->smgr_rnode.dbNode,
324+
isRedo);
325+
312326
if (! (*(smgrsw[reln->smgr_which].smgr_create)) (reln, isRedo))
313327
ereport(ERROR,
314328
(errcode_for_file_access(),

src/include/catalog/heap.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.67 2004/06/18 06:14:05 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.68 2004/07/11 19:52:51 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -40,11 +40,9 @@ extern Relation heap_create(const char *relname,
4040
Oid reltablespace,
4141
TupleDesc tupDesc,
4242
bool shared_relation,
43-
bool storage_create,
43+
bool create_storage,
4444
bool allow_system_table_mods);
4545

46-
extern void heap_storage_create(Relation rel);
47-
4846
extern Oid heap_create_with_catalog(const char *relname,
4947
Oid relnamespace,
5048
Oid reltablespace,

src/include/commands/tablespace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.2 2004/06/25 21:55:58 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.3 2004/07/11 19:52:52 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -20,7 +20,7 @@ extern void CreateTableSpace(CreateTableSpaceStmt *stmt);
2020

2121
extern void DropTableSpace(DropTableSpaceStmt *stmt);
2222

23-
extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode);
23+
extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
2424

2525
extern Oid get_tablespace_oid(const char *tablespacename);
2626

0 commit comments

Comments
 (0)