28
28
#include "miscadmin.h"
29
29
#include "access/xlogutils.h"
30
30
#include "access/xlog.h"
31
+ #include "commands/tablespace.h"
31
32
#include "pgstat.h"
32
33
#include "postmaster/bgwriter.h"
33
34
#include "storage/fd.h"
@@ -120,7 +121,7 @@ static MemoryContext MdCxt; /* context for all MdfdVec objects */
120
121
/* local routines */
121
122
static void mdunlinkfork (RelFileNodeBackend rnode , ForkNumber forkNum ,
122
123
bool isRedo );
123
- static MdfdVec * mdopen (SMgrRelation reln , ForkNumber forknum , int behavior );
124
+ static MdfdVec * mdopenfork (SMgrRelation reln , ForkNumber forknum , int behavior );
124
125
static void register_dirty_segment (SMgrRelation reln , ForkNumber forknum ,
125
126
MdfdVec * seg );
126
127
static void register_unlink_segment (RelFileNodeBackend rnode , ForkNumber forknum ,
@@ -165,7 +166,7 @@ mdexists(SMgrRelation reln, ForkNumber forkNum)
165
166
*/
166
167
mdclose (reln , forkNum );
167
168
168
- return (mdopen (reln , forkNum , EXTENSION_RETURN_NULL ) != NULL );
169
+ return (mdopenfork (reln , forkNum , EXTENSION_RETURN_NULL ) != NULL );
169
170
}
170
171
171
172
/*
@@ -185,6 +186,19 @@ mdcreate(SMgrRelation reln, ForkNumber forkNum, bool isRedo)
185
186
186
187
Assert (reln -> md_num_open_segs [forkNum ] == 0 );
187
188
189
+ /*
190
+ * We may be using the target table space for the first time in this
191
+ * database, so create a per-database subdirectory if needed.
192
+ *
193
+ * XXX this is a fairly ugly violation of module layering, but this seems
194
+ * to be the best place to put the check. Maybe TablespaceCreateDbspace
195
+ * should be here and not in commands/tablespace.c? But that would imply
196
+ * importing a lot of stuff that smgr.c oughtn't know, either.
197
+ */
198
+ TablespaceCreateDbspace (reln -> smgr_rnode .node .spcNode ,
199
+ reln -> smgr_rnode .node .dbNode ,
200
+ isRedo );
201
+
188
202
path = relpath (reln -> smgr_rnode , forkNum );
189
203
190
204
fd = PathNameOpenFile (path , O_RDWR | O_CREAT | O_EXCL | PG_BINARY );
@@ -425,7 +439,7 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
425
439
}
426
440
427
441
/*
428
- * mdopen () -- Open the specified relation.
442
+ * mdopenfork () -- Open one fork of the specified relation.
429
443
*
430
444
* Note we only open the first segment, when there are multiple segments.
431
445
*
@@ -435,7 +449,7 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
435
449
* invent one out of whole cloth.
436
450
*/
437
451
static MdfdVec *
438
- mdopen (SMgrRelation reln , ForkNumber forknum , int behavior )
452
+ mdopenfork (SMgrRelation reln , ForkNumber forknum , int behavior )
439
453
{
440
454
MdfdVec * mdfd ;
441
455
char * path ;
@@ -474,6 +488,17 @@ mdopen(SMgrRelation reln, ForkNumber forknum, int behavior)
474
488
return mdfd ;
475
489
}
476
490
491
+ /*
492
+ * mdopen() -- Initialize newly-opened relation.
493
+ */
494
+ void
495
+ mdopen (SMgrRelation reln )
496
+ {
497
+ /* mark it not open */
498
+ for (int forknum = 0 ; forknum <= MAX_FORKNUM ; forknum ++ )
499
+ reln -> md_num_open_segs [forknum ] = 0 ;
500
+ }
501
+
477
502
/*
478
503
* mdclose() -- Close the specified relation, if it isn't closed already.
479
504
*/
@@ -713,7 +738,7 @@ mdwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
713
738
BlockNumber
714
739
mdnblocks (SMgrRelation reln , ForkNumber forknum )
715
740
{
716
- MdfdVec * v = mdopen (reln , forknum , EXTENSION_FAIL );
741
+ MdfdVec * v = mdopenfork (reln , forknum , EXTENSION_FAIL );
717
742
BlockNumber nblocks ;
718
743
BlockNumber segno = 0 ;
719
744
@@ -1137,7 +1162,7 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno,
1137
1162
v = & reln -> md_seg_fds [forknum ][reln -> md_num_open_segs [forknum ] - 1 ];
1138
1163
else
1139
1164
{
1140
- v = mdopen (reln , forknum , behavior );
1165
+ v = mdopenfork (reln , forknum , behavior );
1141
1166
if (!v )
1142
1167
return NULL ; /* if behavior & EXTENSION_RETURN_NULL */
1143
1168
}
0 commit comments