mirror of
https://github.com/postgres/postgres.git
synced 2025-06-25 01:02:05 +03:00
Previously, md.c and checkpointer.c were tightly integrated so that fsync calls could be handed off and processed in the background. Introduce a system of callbacks and file tags, so that other modules can hand off fsync work in the same way. For now only md.c uses the new interface, but other users are being proposed. Since there may be use cases that are not strictly SMGR implementations, use a new function table for sync handlers rather than extending the traditional SMGR one. Instead of using a bitmapset of segment numbers for each RelFileNode in the checkpointer's hash table, make the segment number part of the key. This requires sending explicit "forget" requests for every segment individually when relations are dropped, but suits the file layout schemes of proposed future users better (ie sparse or high segment numbers). Author: Shawn Debnath and Thomas Munro Reviewed-by: Thomas Munro, Andres Freund Discussion: https://postgr.es/m/CAEepm=2gTANm=e3ARnJT=n0h8hf88wqmaZxk0JYkxw+b21fNrw@mail.gmail.com
111 lines
4.4 KiB
C
111 lines
4.4 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* smgr.h
|
|
* storage manager switch public interface declarations.
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/storage/smgr.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef SMGR_H
|
|
#define SMGR_H
|
|
|
|
#include "lib/ilist.h"
|
|
#include "storage/block.h"
|
|
#include "storage/relfilenode.h"
|
|
|
|
/*
|
|
* smgr.c maintains a table of SMgrRelation objects, which are essentially
|
|
* cached file handles. An SMgrRelation is created (if not already present)
|
|
* by smgropen(), and destroyed by smgrclose(). Note that neither of these
|
|
* operations imply I/O, they just create or destroy a hashtable entry.
|
|
* (But smgrclose() may release associated resources, such as OS-level file
|
|
* descriptors.)
|
|
*
|
|
* An SMgrRelation may have an "owner", which is just a pointer to it from
|
|
* somewhere else; smgr.c will clear this pointer if the SMgrRelation is
|
|
* closed. We use this to avoid dangling pointers from relcache to smgr
|
|
* without having to make the smgr explicitly aware of relcache. There
|
|
* can't be more than one "owner" pointer per SMgrRelation, but that's
|
|
* all we need.
|
|
*
|
|
* SMgrRelations that do not have an "owner" are considered to be transient,
|
|
* and are deleted at end of transaction.
|
|
*/
|
|
typedef struct SMgrRelationData
|
|
{
|
|
/* rnode is the hashtable lookup key, so it must be first! */
|
|
RelFileNodeBackend smgr_rnode; /* relation physical identifier */
|
|
|
|
/* pointer to owning pointer, or NULL if none */
|
|
struct SMgrRelationData **smgr_owner;
|
|
|
|
/*
|
|
* These next three fields are not actually used or manipulated by smgr,
|
|
* except that they are reset to InvalidBlockNumber upon a cache flush
|
|
* event (in particular, upon truncation of the relation). Higher levels
|
|
* store cached state here so that it will be reset when truncation
|
|
* happens. In all three cases, InvalidBlockNumber means "unknown".
|
|
*/
|
|
BlockNumber smgr_targblock; /* current insertion target block */
|
|
BlockNumber smgr_fsm_nblocks; /* last known size of fsm fork */
|
|
BlockNumber smgr_vm_nblocks; /* last known size of vm fork */
|
|
|
|
/* additional public fields may someday exist here */
|
|
|
|
/*
|
|
* Fields below here are intended to be private to smgr.c and its
|
|
* submodules. Do not touch them from elsewhere.
|
|
*/
|
|
int smgr_which; /* storage manager selector */
|
|
|
|
/*
|
|
* for md.c; per-fork arrays of the number of open segments
|
|
* (md_num_open_segs) and the segments themselves (md_seg_fds).
|
|
*/
|
|
int md_num_open_segs[MAX_FORKNUM + 1];
|
|
struct _MdfdVec *md_seg_fds[MAX_FORKNUM + 1];
|
|
|
|
/* if unowned, list link in list of all unowned SMgrRelations */
|
|
dlist_node node;
|
|
} SMgrRelationData;
|
|
|
|
typedef SMgrRelationData *SMgrRelation;
|
|
|
|
#define SmgrIsTemp(smgr) \
|
|
RelFileNodeBackendIsTemp((smgr)->smgr_rnode)
|
|
|
|
extern void smgrinit(void);
|
|
extern SMgrRelation smgropen(RelFileNode rnode, BackendId backend);
|
|
extern bool smgrexists(SMgrRelation reln, ForkNumber forknum);
|
|
extern void smgrsetowner(SMgrRelation *owner, SMgrRelation reln);
|
|
extern void smgrclearowner(SMgrRelation *owner, SMgrRelation reln);
|
|
extern void smgrclose(SMgrRelation reln);
|
|
extern void smgrcloseall(void);
|
|
extern void smgrclosenode(RelFileNodeBackend rnode);
|
|
extern void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo);
|
|
extern void smgrdounlink(SMgrRelation reln, bool isRedo);
|
|
extern void smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo);
|
|
extern void smgrdounlinkfork(SMgrRelation reln, ForkNumber forknum, bool isRedo);
|
|
extern void smgrextend(SMgrRelation reln, ForkNumber forknum,
|
|
BlockNumber blocknum, char *buffer, bool skipFsync);
|
|
extern void smgrprefetch(SMgrRelation reln, ForkNumber forknum,
|
|
BlockNumber blocknum);
|
|
extern void smgrread(SMgrRelation reln, ForkNumber forknum,
|
|
BlockNumber blocknum, char *buffer);
|
|
extern void smgrwrite(SMgrRelation reln, ForkNumber forknum,
|
|
BlockNumber blocknum, char *buffer, bool skipFsync);
|
|
extern void smgrwriteback(SMgrRelation reln, ForkNumber forknum,
|
|
BlockNumber blocknum, BlockNumber nblocks);
|
|
extern BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum);
|
|
extern void smgrtruncate(SMgrRelation reln, ForkNumber forknum,
|
|
BlockNumber nblocks);
|
|
extern void smgrimmedsync(SMgrRelation reln, ForkNumber forknum);
|
|
extern void AtEOXact_SMgr(void);
|
|
|
|
#endif /* SMGR_H */
|