Move some md.c-specific logic from smgr.c to md.c.
authorThomas Munro <[email protected]>
Wed, 17 Jul 2019 00:14:08 +0000 (12:14 +1200)
committerThomas Munro <[email protected]>
Wed, 17 Jul 2019 03:00:22 +0000 (15:00 +1200)
Potential future SMGR implementations may not want to create
tablespace directories when creating an SMGR relation.  Move that
logic to mdcreate().  Move the initialization of md-specific
data structures from smgropen() to a new callback mdopen().

Author: Thomas Munro
Reviewed-by: Shawn Debnath (as part of an earlier patch set)
Discussion: https://postgr.es/m/CA%2BhUKG%2BOZqOiOuDm5tC5DyQZtJ3FH4%2BFSVMqtdC4P1atpJ%2Bqhg%40mail.gmail.com

src/backend/storage/smgr/md.c
src/backend/storage/smgr/smgr.c
src/include/storage/md.h

index 58c94e9257a506a8aafa806e32012d7b22c4b39d..52136ad55800e1c51d945ac44c7fe378441cde80 100644 (file)
@@ -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;
@@ -474,6 +488,17 @@ mdopen(SMgrRelation reln, ForkNumber forknum, int behavior)
        return mdfd;
 }
 
+/*
+ *  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.
  */
@@ -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 */
        }
index dba8c397feb85fff4e994a06bae968681866e187..b0d9f21e6880e69ad9eac2baebb30c77a5654c8c 100644 (file)
@@ -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);
 }
 
index df24b931613179185f8d37202eb818f2a5188780..c0f05e23ff9b3d771d5a394e7e90dfc51337832e 100644 (file)
@@ -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);