From 4aac2c69cbb0001be5e95b6d482fc3b032208f81 Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Tue, 22 Jan 2019 11:46:29 +0800 Subject: [PATCH] Add smgr*_hook() hook points to extend the logic of storage management. Co-authored-by: Haozhou Wang Co-authored-by: Hubert Zhang Co-authored-by: Hao Wu --- src/backend/storage/smgr/smgr.c | 30 ++++++++++++++++++++++++++++++ src/include/storage/smgr.h | 18 ++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index 0c0bba4ab3..b4ba9d9a4d 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -90,6 +90,16 @@ static const f_smgr smgrsw[] = { static const int NSmgr = lengthof(smgrsw); +/* + * Hook for plugins to extend smgr functions. + * for example, collect statistics from smgr functions + * via recording the active relfilenode information. + */ +smgrcreate_hook_type smgrcreate_hook = NULL; +smgrextend_hook_type smgrextend_hook = NULL; +smgrtruncate_hook_type smgrtruncate_hook = NULL; +smgrdounlinkall_hook_type smgrdounlinkall_hook = NULL; + /* * Each backend has a hashtable that stores all extant SMgrRelation objects. @@ -397,6 +407,11 @@ smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo) if (isRedo && reln->md_num_open_segs[forknum] > 0) return; + if (smgrcreate_hook) + { + (*smgrcreate_hook)(reln, forknum, isRedo); + } + /* * We may be using the target table space for the first time in this * database, so create a per-database subdirectory if needed. @@ -492,6 +507,11 @@ smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo) if (nrels == 0) return; + if (smgrdounlinkall_hook) + { + (*smgrdounlinkall_hook)(rels, nrels, isRedo); + } + /* * create an array which contains all relations to be dropped, and close * each relation's forks at the smgr level while at it @@ -615,6 +635,11 @@ void smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync) { + if (smgrextend_hook) + { + (*smgrextend_hook)(reln, forknum, blocknum, buffer, skipFsync); + } + smgrsw[reln->smgr_which].smgr_extend(reln, forknum, blocknum, buffer, skipFsync); } @@ -698,6 +723,11 @@ smgrnblocks(SMgrRelation reln, ForkNumber forknum) void smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks) { + if (smgrtruncate_hook) + { + (*smgrtruncate_hook)(reln, forknum, nblocks); + } + /* * Get rid of any buffers for the about-to-be-deleted blocks. bufmgr will * just drop them without bothering to write the contents. diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index 820d08ed4e..5426543b5c 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.h @@ -144,5 +144,23 @@ extern void RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum, extern void ForgetRelationFsyncRequests(RelFileNode rnode, ForkNumber forknum); extern void ForgetDatabaseFsyncRequests(Oid dbid); extern void DropRelationFiles(RelFileNode *delrels, int ndelrels, bool isRedo); +/* + * Hook for plugins to extend smgr functions. + * for example, collect statistics from smgr functions + * via recording the active relfilenode information. + */ +typedef void (*smgrcreate_hook_type)(SMgrRelation reln, ForkNumber forknum, + bool isRedo); +extern PGDLLIMPORT smgrcreate_hook_type smgrcreate_hook; +typedef void (*smgrextend_hook_type)(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, + char *buffer, bool skipFsync); +extern PGDLLIMPORT smgrextend_hook_type smgrextend_hook; +typedef void (*smgrtruncate_hook_type)(SMgrRelation reln, ForkNumber forknum, + BlockNumber nblocks); +extern PGDLLIMPORT smgrtruncate_hook_type smgrtruncate_hook; +typedef void (*smgrdounlinkall_hook_type)(SMgrRelation *rels, int nrels, + bool isRedo); +extern PGDLLIMPORT smgrdounlinkall_hook_type smgrdounlinkall_hook; #endif /* SMGR_H */ -- 2.11.0 (Apple Git-81)