mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Move some md.c-specific logic from smgr.c to md.c.
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
This commit is contained in:
@ -28,6 +28,7 @@
|
|||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "access/xlogutils.h"
|
#include "access/xlogutils.h"
|
||||||
#include "access/xlog.h"
|
#include "access/xlog.h"
|
||||||
|
#include "commands/tablespace.h"
|
||||||
#include "pgstat.h"
|
#include "pgstat.h"
|
||||||
#include "postmaster/bgwriter.h"
|
#include "postmaster/bgwriter.h"
|
||||||
#include "storage/fd.h"
|
#include "storage/fd.h"
|
||||||
@ -120,7 +121,7 @@ static MemoryContext MdCxt; /* context for all MdfdVec objects */
|
|||||||
/* local routines */
|
/* local routines */
|
||||||
static void mdunlinkfork(RelFileNodeBackend rnode, ForkNumber forkNum,
|
static void mdunlinkfork(RelFileNodeBackend rnode, ForkNumber forkNum,
|
||||||
bool isRedo);
|
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,
|
static void register_dirty_segment(SMgrRelation reln, ForkNumber forknum,
|
||||||
MdfdVec *seg);
|
MdfdVec *seg);
|
||||||
static void register_unlink_segment(RelFileNodeBackend rnode, ForkNumber forknum,
|
static void register_unlink_segment(RelFileNodeBackend rnode, ForkNumber forknum,
|
||||||
@ -165,7 +166,7 @@ mdexists(SMgrRelation reln, ForkNumber forkNum)
|
|||||||
*/
|
*/
|
||||||
mdclose(reln, 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);
|
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);
|
path = relpath(reln->smgr_rnode, forkNum);
|
||||||
|
|
||||||
fd = PathNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY);
|
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.
|
* 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.
|
* invent one out of whole cloth.
|
||||||
*/
|
*/
|
||||||
static MdfdVec *
|
static MdfdVec *
|
||||||
mdopen(SMgrRelation reln, ForkNumber forknum, int behavior)
|
mdopenfork(SMgrRelation reln, ForkNumber forknum, int behavior)
|
||||||
{
|
{
|
||||||
MdfdVec *mdfd;
|
MdfdVec *mdfd;
|
||||||
char *path;
|
char *path;
|
||||||
@ -474,6 +488,17 @@ mdopen(SMgrRelation reln, ForkNumber forknum, int behavior)
|
|||||||
return mdfd;
|
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.
|
* mdclose() -- Close the specified relation, if it isn't closed already.
|
||||||
*/
|
*/
|
||||||
@ -713,7 +738,7 @@ mdwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
|
|||||||
BlockNumber
|
BlockNumber
|
||||||
mdnblocks(SMgrRelation reln, ForkNumber forknum)
|
mdnblocks(SMgrRelation reln, ForkNumber forknum)
|
||||||
{
|
{
|
||||||
MdfdVec *v = mdopen(reln, forknum, EXTENSION_FAIL);
|
MdfdVec *v = mdopenfork(reln, forknum, EXTENSION_FAIL);
|
||||||
BlockNumber nblocks;
|
BlockNumber nblocks;
|
||||||
BlockNumber segno = 0;
|
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];
|
v = &reln->md_seg_fds[forknum][reln->md_num_open_segs[forknum] - 1];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
v = mdopen(reln, forknum, behavior);
|
v = mdopenfork(reln, forknum, behavior);
|
||||||
if (!v)
|
if (!v)
|
||||||
return NULL; /* if behavior & EXTENSION_RETURN_NULL */
|
return NULL; /* if behavior & EXTENSION_RETURN_NULL */
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "commands/tablespace.h"
|
|
||||||
#include "lib/ilist.h"
|
#include "lib/ilist.h"
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
#include "storage/ipc.h"
|
#include "storage/ipc.h"
|
||||||
@ -41,6 +40,7 @@ typedef struct f_smgr
|
|||||||
{
|
{
|
||||||
void (*smgr_init) (void); /* may be NULL */
|
void (*smgr_init) (void); /* may be NULL */
|
||||||
void (*smgr_shutdown) (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_close) (SMgrRelation reln, ForkNumber forknum);
|
||||||
void (*smgr_create) (SMgrRelation reln, ForkNumber forknum,
|
void (*smgr_create) (SMgrRelation reln, ForkNumber forknum,
|
||||||
bool isRedo);
|
bool isRedo);
|
||||||
@ -68,6 +68,7 @@ static const f_smgr smgrsw[] = {
|
|||||||
{
|
{
|
||||||
.smgr_init = mdinit,
|
.smgr_init = mdinit,
|
||||||
.smgr_shutdown = NULL,
|
.smgr_shutdown = NULL,
|
||||||
|
.smgr_open = mdopen,
|
||||||
.smgr_close = mdclose,
|
.smgr_close = mdclose,
|
||||||
.smgr_create = mdcreate,
|
.smgr_create = mdcreate,
|
||||||
.smgr_exists = mdexists,
|
.smgr_exists = mdexists,
|
||||||
@ -170,8 +171,6 @@ smgropen(RelFileNode rnode, BackendId backend)
|
|||||||
/* Initialize it if not present before */
|
/* Initialize it if not present before */
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
int forknum;
|
|
||||||
|
|
||||||
/* hash_search already filled in the lookup key */
|
/* hash_search already filled in the lookup key */
|
||||||
reln->smgr_owner = NULL;
|
reln->smgr_owner = NULL;
|
||||||
reln->smgr_targblock = InvalidBlockNumber;
|
reln->smgr_targblock = InvalidBlockNumber;
|
||||||
@ -179,9 +178,8 @@ smgropen(RelFileNode rnode, BackendId backend)
|
|||||||
reln->smgr_vm_nblocks = InvalidBlockNumber;
|
reln->smgr_vm_nblocks = InvalidBlockNumber;
|
||||||
reln->smgr_which = 0; /* we only have md.c at present */
|
reln->smgr_which = 0; /* we only have md.c at present */
|
||||||
|
|
||||||
/* mark it not open */
|
/* implementation-specific initialization */
|
||||||
for (forknum = 0; forknum <= MAX_FORKNUM; forknum++)
|
smgrsw[reln->smgr_which].smgr_open(reln);
|
||||||
reln->md_num_open_segs[forknum] = 0;
|
|
||||||
|
|
||||||
/* it has no owner yet */
|
/* it has no owner yet */
|
||||||
dlist_push_tail(&unowned_relns, &reln->node);
|
dlist_push_tail(&unowned_relns, &reln->node);
|
||||||
@ -330,33 +328,10 @@ smgrclosenode(RelFileNodeBackend rnode)
|
|||||||
* Given an already-created (but presumably unused) SMgrRelation,
|
* Given an already-created (but presumably unused) SMgrRelation,
|
||||||
* cause the underlying disk file or other storage for the fork
|
* cause the underlying disk file or other storage for the fork
|
||||||
* to be created.
|
* 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
|
void
|
||||||
smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
|
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);
|
smgrsw[reln->smgr_which].smgr_create(reln, forknum, isRedo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
/* md storage manager functionality */
|
/* md storage manager functionality */
|
||||||
extern void mdinit(void);
|
extern void mdinit(void);
|
||||||
|
extern void mdopen(SMgrRelation reln);
|
||||||
extern void mdclose(SMgrRelation reln, ForkNumber forknum);
|
extern void mdclose(SMgrRelation reln, ForkNumber forknum);
|
||||||
extern void mdcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo);
|
extern void mdcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo);
|
||||||
extern bool mdexists(SMgrRelation reln, ForkNumber forknum);
|
extern bool mdexists(SMgrRelation reln, ForkNumber forknum);
|
||||||
|
Reference in New Issue
Block a user