From 46b63c67d1262022280fa862d5759309458333e1 Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Mon, 28 Aug 2017 10:21:53 +0500 Subject: [PATCH] hooks to watch for changed pages --- src/backend/access/transam/xlog.c | 14 ++++++++++++++ src/backend/access/transam/xloginsert.c | 19 +++++++++++++++++++ src/include/access/xloginsert.h | 24 ++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index df4843f409..f18b457cc3 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -926,6 +926,9 @@ static void WALInsertLockAcquireExclusive(void); static void WALInsertLockRelease(void); static void WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt); +/* Hook for plugins to get notified during the end of segment */ +PGDLLIMPORT wal_switch_hook_type wal_switch_hook = NULL; + /* * Insert an XLOG record represented by an already-constructed chain of data * chunks. This is a low-level routine; to construct the WAL record header @@ -7024,6 +7027,7 @@ StartupXLOG(void) do { bool switchedTLI = false; + int nblock; #ifdef WAL_DEBUG if (XLOG_DEBUG || @@ -7186,6 +7190,16 @@ StartupXLOG(void) /* Pop the error context stack */ error_context_stack = errcallback.previous; + if (xlog_insert_buffer_hook) + for(nblock = 0; nblock < xlogreader->max_block_id; nblock++) + { + if(xlogreader->blocks[nblock].forknum == MAIN_FORKNUM) + { + xlog_insert_buffer_hook(xlogreader->blocks[nblock].blkno, + xlogreader->blocks[nblock].rnode, true); + } + } + /* * Update lastReplayedEndRecPtr after this record has been * successfully replayed. diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c index 3af03ecdb1..2f6d52dc49 100644 --- a/src/backend/access/transam/xloginsert.c +++ b/src/backend/access/transam/xloginsert.c @@ -112,6 +112,9 @@ static XLogRecData *XLogRecordAssemble(RmgrId rmid, uint8 info, static bool XLogCompressBackupBlock(char *page, uint16 hole_offset, uint16 hole_length, char *dest, uint16 *dlen); +/* Hook for plugins to get control at the beginning of insertion xlog */ +PGDLLIMPORT xlog_begin_insert_hook_type xlog_begin_insert_hook = NULL; + /* * Begin constructing a WAL record. This must be called before the * XLogRegister* functions and XLogInsert(). @@ -131,6 +134,8 @@ XLogBeginInsert(void) elog(ERROR, "XLogBeginInsert was already called"); begininsert_called = true; + if(xlog_begin_insert_hook) + xlog_begin_insert_hook(); } /* @@ -205,6 +210,9 @@ XLogResetInsertion(void) begininsert_called = false; } +/* Hook for plugins to get control in during page insertion into xlog */ +PGDLLIMPORT xlog_insert_buffer_hook_type xlog_insert_buffer_hook = NULL; + /* * Register a reference to a buffer with the WAL record being constructed. * This must be called for every page that the WAL-logged operation modifies. @@ -256,6 +264,10 @@ XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags) #endif regbuf->in_use = true; + if (xlog_insert_buffer_hook && regbuf->forkno == MAIN_FORKNUM) + { + xlog_insert_buffer_hook(regbuf->block, regbuf->rnode, false); + } } /* @@ -400,6 +412,9 @@ XLogSetRecordFlags(uint8 flags) curinsert_flags = flags; } +/* Hook for plugins to get control at the end of insertion of xlog record */ +PGDLLIMPORT xlog_end_insert_hook_type xlog_end_insert_hook = NULL; + /* * Insert an XLOG record having the specified RMID and info bytes, with the * body of the record being the data and buffer references registered earlier @@ -438,6 +453,8 @@ XLogInsert(RmgrId rmid, uint8 info) if (IsBootstrapProcessingMode() && rmid != RM_XLOG_ID) { XLogResetInsertion(); + if (xlog_end_insert_hook) + xlog_end_insert_hook(false); EndPos = SizeOfXLogLongPHD; /* start of 1st chkpt record */ return EndPos; } @@ -463,6 +480,8 @@ XLogInsert(RmgrId rmid, uint8 info) } while (EndPos == InvalidXLogRecPtr); XLogResetInsertion(); + if (xlog_end_insert_hook) + xlog_end_insert_hook(true); return EndPos; } diff --git a/src/include/access/xloginsert.h b/src/include/access/xloginsert.h index 174c88677f..72f7e2e722 100644 --- a/src/include/access/xloginsert.h +++ b/src/include/access/xloginsert.h @@ -58,4 +58,28 @@ extern XLogRecPtr XLogSaveBufferForHint(Buffer buffer, bool buffer_std); extern void InitXLogInsert(void); +/* Hook for plugins to get control in during page insertion into xlog */ +typedef void (*xlog_insert_buffer_hook_type) (BlockNumber block_number, RelFileNode rel, bool recovery); + +/* in xloginsert.c */ +extern PGDLLIMPORT xlog_insert_buffer_hook_type xlog_insert_buffer_hook; + +/* Hook for plugins to get control at the beginning of insertion xlog */ +typedef void (*xlog_begin_insert_hook_type) (); + +/* in xloginsert.c */ +extern PGDLLIMPORT xlog_begin_insert_hook_type xlog_begin_insert_hook; + +/* Hook for plugins to get control at the end of insertion of xlog record */ +typedef void (*xlog_end_insert_hook_type) (bool inserted); + +/* in xloginsert.c */ +extern PGDLLIMPORT xlog_end_insert_hook_type xlog_end_insert_hook; + +/* Hook for plugins to get notified during the end of segment */ +typedef void (*wal_switch_hook_type) (XLogRecPtr EndPos); + +/* in xlog.c */ +extern PGDLLIMPORT wal_switch_hook_type wal_switch_hook; + #endif /* XLOGINSERT_H */ -- 2.11.0 (Apple Git-81)