From 18e2f13ecd9af7594dee78f981873c5a18998b2c Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Mon, 15 Jul 2019 11:34:24 +0800 Subject: [PATCH] Add smgr hooks to extend the logic of storage management One example is that these hooks could be used by diskquota extension to detect heap table change(create/extend/truncate/unlink). Co-authored-by: Haozhou Wang Co-authored-by: Hubert Zhang Co-authored-by: Hao Wu --- src/backend/storage/smgr/smgr.c | 22 ++++++++++++++++++++++ src/include/storage/smgr.h | 19 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index b50c69b438..f1c759ce11 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -97,6 +97,16 @@ static dlist_head unowned_relns; /* local function prototypes */ static void smgrshutdown(int code, Datum arg); +/* + * 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; + /* * smgrinit(), smgrshutdown() -- Initialize or shut down storage @@ -332,6 +342,9 @@ smgrclosenode(RelFileNodeBackend rnode) void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo) { + if (smgrcreate_hook) + (*smgrcreate_hook)(reln, forknum, isRedo); + smgrsw[reln->smgr_which].smgr_create(reln, forknum, isRedo); } @@ -411,6 +424,9 @@ 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 @@ -483,6 +499,9 @@ 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); } @@ -572,6 +591,9 @@ smgrtruncate(SMgrRelation reln, ForkNumber *forknum, int nforks, BlockNumber *nb { int i; + 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 1543d8d870..e94c8b0644 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.h @@ -106,4 +106,23 @@ extern void smgrtruncate(SMgrRelation reln, ForkNumber *forknum, extern void smgrimmedsync(SMgrRelation reln, ForkNumber forknum); extern void AtEOXact_SMgr(void); +/* + * 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.20.1 (Apple Git-117)