diff options
-rw-r--r-- | src/backend/storage/smgr/md.c | 37 | ||||
-rw-r--r-- | src/backend/storage/smgr/smgr.c | 33 | ||||
-rw-r--r-- | src/include/storage/md.h | 1 |
3 files changed, 36 insertions, 35 deletions
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 58c94e9257a..52136ad5580 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -28,6 +28,7 @@ #include "miscadmin.h" #include "access/xlogutils.h" #include "access/xlog.h" +#include "commands/tablespace.h" #include "pgstat.h" #include "postmaster/bgwriter.h" #include "storage/fd.h" @@ -120,7 +121,7 @@ static MemoryContext MdCxt; /* context for all MdfdVec objects */ /* local routines */ static void mdunlinkfork(RelFileNodeBackend rnode, ForkNumber forkNum, bool isRedo); -static MdfdVec *mdopen(SMgrRelation reln, ForkNumber forknum, int behavior); +static MdfdVec *mdopenfork(SMgrRelation reln, ForkNumber forknum, int behavior); static void register_dirty_segment(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg); static void register_unlink_segment(RelFileNodeBackend rnode, ForkNumber forknum, @@ -165,7 +166,7 @@ mdexists(SMgrRelation reln, ForkNumber forkNum) */ mdclose(reln, forkNum); - return (mdopen(reln, forkNum, EXTENSION_RETURN_NULL) != NULL); + return (mdopenfork(reln, forkNum, EXTENSION_RETURN_NULL) != NULL); } /* @@ -185,6 +186,19 @@ mdcreate(SMgrRelation reln, ForkNumber forkNum, bool isRedo) Assert(reln->md_num_open_segs[forkNum] == 0); + /* + * 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.node.spcNode, + reln->smgr_rnode.node.dbNode, + isRedo); + path = relpath(reln->smgr_rnode, forkNum); fd = PathNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY); @@ -425,7 +439,7 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, } /* - * mdopen() -- Open the specified relation. + * mdopenfork() -- Open one fork of the specified relation. * * Note we only open the first segment, when there are multiple segments. * @@ -435,7 +449,7 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, * invent one out of whole cloth. */ static MdfdVec * -mdopen(SMgrRelation reln, ForkNumber forknum, int behavior) +mdopenfork(SMgrRelation reln, ForkNumber forknum, int behavior) { MdfdVec *mdfd; char *path; @@ -475,6 +489,17 @@ mdopen(SMgrRelation reln, ForkNumber forknum, int behavior) } /* + * mdopen() -- Initialize newly-opened relation. + */ +void +mdopen(SMgrRelation reln) +{ + /* mark it not open */ + for (int forknum = 0; forknum <= MAX_FORKNUM; forknum++) + reln->md_num_open_segs[forknum] = 0; +} + +/* * mdclose() -- Close the specified relation, if it isn't closed already. */ void @@ -713,7 +738,7 @@ mdwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber mdnblocks(SMgrRelation reln, ForkNumber forknum) { - MdfdVec *v = mdopen(reln, forknum, EXTENSION_FAIL); + MdfdVec *v = mdopenfork(reln, forknum, EXTENSION_FAIL); BlockNumber nblocks; BlockNumber segno = 0; @@ -1137,7 +1162,7 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno, v = &reln->md_seg_fds[forknum][reln->md_num_open_segs[forknum] - 1]; else { - v = mdopen(reln, forknum, behavior); + v = mdopenfork(reln, forknum, behavior); if (!v) return NULL; /* if behavior & EXTENSION_RETURN_NULL */ } diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index dba8c397feb..b0d9f21e688 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -17,7 +17,6 @@ */ #include "postgres.h" -#include "commands/tablespace.h" #include "lib/ilist.h" #include "storage/bufmgr.h" #include "storage/ipc.h" @@ -41,6 +40,7 @@ typedef struct f_smgr { void (*smgr_init) (void); /* may be NULL */ void (*smgr_shutdown) (void); /* may be NULL */ + void (*smgr_open) (SMgrRelation reln); void (*smgr_close) (SMgrRelation reln, ForkNumber forknum); void (*smgr_create) (SMgrRelation reln, ForkNumber forknum, bool isRedo); @@ -68,6 +68,7 @@ static const f_smgr smgrsw[] = { { .smgr_init = mdinit, .smgr_shutdown = NULL, + .smgr_open = mdopen, .smgr_close = mdclose, .smgr_create = mdcreate, .smgr_exists = mdexists, @@ -170,8 +171,6 @@ smgropen(RelFileNode rnode, BackendId backend) /* Initialize it if not present before */ if (!found) { - int forknum; - /* hash_search already filled in the lookup key */ reln->smgr_owner = NULL; reln->smgr_targblock = InvalidBlockNumber; @@ -179,9 +178,8 @@ smgropen(RelFileNode rnode, BackendId backend) reln->smgr_vm_nblocks = InvalidBlockNumber; reln->smgr_which = 0; /* we only have md.c at present */ - /* mark it not open */ - for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) - reln->md_num_open_segs[forknum] = 0; + /* implementation-specific initialization */ + smgrsw[reln->smgr_which].smgr_open(reln); /* it has no owner yet */ dlist_push_tail(&unowned_relns, &reln->node); @@ -330,33 +328,10 @@ smgrclosenode(RelFileNodeBackend rnode) * Given an already-created (but presumably unused) SMgrRelation, * cause the underlying disk file or other storage for the fork * to be created. - * - * If isRedo is true, it is okay for the underlying file to exist - * already because we are in a WAL replay sequence. */ void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo) { - /* - * Exit quickly in WAL replay mode if we've already opened the file. If - * it's open, it surely must exist. - */ - if (isRedo && reln->md_num_open_segs[forknum] > 0) - return; - - /* - * 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.node.spcNode, - reln->smgr_rnode.node.dbNode, - isRedo); - smgrsw[reln->smgr_which].smgr_create(reln, forknum, isRedo); } diff --git a/src/include/storage/md.h b/src/include/storage/md.h index df24b931613..c0f05e23ff9 100644 --- a/src/include/storage/md.h +++ b/src/include/storage/md.h @@ -21,6 +21,7 @@ /* md storage manager functionality */ extern void mdinit(void); +extern void mdopen(SMgrRelation reln); extern void mdclose(SMgrRelation reln, ForkNumber forknum); extern void mdcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo); extern bool mdexists(SMgrRelation reln, ForkNumber forknum); |