Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Move some md.c-specific logic from smgr.c to md.c.
authorThomas Munro <tmunro@postgresql.org>
Wed, 17 Jul 2019 00:14:08 +0000 (12:14 +1200)
committerThomas Munro <tmunro@postgresql.org>
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);