summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/storage/smgr.h36
-rw-r--r--src/include/utils/rel.h18
-rw-r--r--src/include/utils/relcache.h2
3 files changed, 24 insertions, 32 deletions
diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h
index 527cd2a0568..8d90d1f8e22 100644
--- a/src/include/storage/smgr.h
+++ b/src/include/storage/smgr.h
@@ -21,29 +21,21 @@
/*
* 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
+ * by smgropen(), and destroyed by smgrdestroy(). Note that neither of these
+ * operations imply I/O, they just create or destroy a hashtable entry. (But
+ * smgrdestroy() 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.
+ * An SMgrRelation may be "pinned", to prevent it from being destroyed while
+ * it's in use. We use this to prevent pointers relcache to smgr from being
+ * invalidated. SMgrRelations that are not pinned are deleted at end of
+ * transaction.
*/
typedef struct SMgrRelationData
{
/* rlocator is the hashtable lookup key, so it must be first! */
RelFileLocatorBackend smgr_rlocator; /* relation physical identifier */
- /* pointer to owning pointer, or NULL if none */
- struct SMgrRelationData **smgr_owner;
-
/*
* The following fields are reset to InvalidBlockNumber upon a cache flush
* event, and hold the last known size for each fork. This information is
@@ -68,7 +60,11 @@ typedef struct SMgrRelationData
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 */
+ /*
+ * Pinning support. If unpinned (ie. pincount == 0), 'node' is a list
+ * link in list of all unpinned SMgrRelations.
+ */
+ int pincount;
dlist_node node;
} SMgrRelationData;
@@ -80,13 +76,13 @@ typedef SMgrRelationData *SMgrRelation;
extern void smgrinit(void);
extern SMgrRelation smgropen(RelFileLocator rlocator, 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 smgrpin(SMgrRelation reln);
+extern void smgrunpin(SMgrRelation reln);
extern void smgrclose(SMgrRelation reln);
-extern void smgrcloseall(void);
-extern void smgrcloserellocator(RelFileLocatorBackend rlocator);
+extern void smgrdestroyall(void);
extern void smgrrelease(SMgrRelation reln);
extern void smgrreleaseall(void);
+extern void smgrreleaserellocator(RelFileLocatorBackend rlocator);
extern void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo);
extern void smgrdosyncall(SMgrRelation *rels, int nrels);
extern void smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index a584b1ddff3..ab9fa4faf9f 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -561,18 +561,15 @@ typedef struct ViewOptions
*
* Very little code is authorized to touch rel->rd_smgr directly. Instead
* use this function to fetch its value.
- *
- * Note: since a relcache flush can cause the file handle to be closed again,
- * it's unwise to hold onto the pointer returned by this function for any
- * long period. Recommended practice is to just re-execute RelationGetSmgr
- * each time you need to access the SMgrRelation. It's quite cheap in
- * comparison to whatever an smgr function is going to do.
*/
static inline SMgrRelation
RelationGetSmgr(Relation rel)
{
if (unlikely(rel->rd_smgr == NULL))
- smgrsetowner(&(rel->rd_smgr), smgropen(rel->rd_locator, rel->rd_backend));
+ {
+ rel->rd_smgr = smgropen(rel->rd_locator, rel->rd_backend);
+ smgrpin(rel->rd_smgr);
+ }
return rel->rd_smgr;
}
@@ -584,10 +581,11 @@ static inline void
RelationCloseSmgr(Relation relation)
{
if (relation->rd_smgr != NULL)
+ {
+ smgrunpin(relation->rd_smgr);
smgrclose(relation->rd_smgr);
-
- /* smgrclose should unhook from owner pointer */
- Assert(relation->rd_smgr == NULL);
+ relation->rd_smgr = NULL;
+ }
}
#endif /* !FRONTEND */
diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h
index 058da62a726..18c32ea7008 100644
--- a/src/include/utils/relcache.h
+++ b/src/include/utils/relcache.h
@@ -129,8 +129,6 @@ extern void RelationCacheInvalidateEntry(Oid relationId);
extern void RelationCacheInvalidate(bool debug_discard);
-extern void RelationCloseSmgrByOid(Oid relationId);
-
#ifdef USE_ASSERT_CHECKING
extern void AssertPendingSyncs_RelationCache(void);
#else