diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 81183e2ec6b..4f3fb5c90d0 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -838,6 +838,10 @@ XLogInsertRecord(XLogRecData *rdata, * but not force a recomputation. (If doPageWrites was just turned off, * we could recompute the record without full pages, but we choose not to * bother.) + * + * However, if suppress_fpi is true, we skip the recomputation check + * since we're deliberately suppressing full page images for this + * record via the FPI control hook. */ if (RedoRecPtr != Insert->RedoRecPtr) { @@ -848,7 +852,8 @@ XLogInsertRecord(XLogRecData *rdata, if (doPageWrites && (!prevDoPageWrites || - (fpw_lsn != InvalidXLogRecPtr && fpw_lsn <= RedoRecPtr))) + (!suppress_fpi && + fpw_lsn != InvalidXLogRecPtr && fpw_lsn <= RedoRecPtr))) { /* * Oops, some buffer now needs to be backed up that the caller didn't diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c index 1fc2159b193..c77acebefd7 100644 --- a/src/backend/access/transam/xloginsert.c +++ b/src/backend/access/transam/xloginsert.c @@ -94,6 +94,12 @@ int max_replication_apply_lag; int max_replication_flush_lag; int max_replication_write_lag; +/* NEON: Hook to determine if FPI should be suppressed for a WAL record */ +xlog_should_suppress_fpi_hook_type xlog_should_suppress_fpi_hook = NULL; + +/* NEON: Global flag to suppress FPI for current WAL record */ +bool suppress_fpi = false; + static registered_buffer *registered_buffers; static int max_registered_buffers; /* allocated size */ static int max_registered_block_id = 0; /* highest block_id + 1 currently @@ -516,6 +522,16 @@ XLogInsert(RmgrId rmid, uint8 info) */ GetFullPageWriteInfo(&RedoRecPtr, &doPageWrites); + /* + * NEON: Check if we should suppress FPI for this WAL record. + */ + suppress_fpi = false; + if (xlog_should_suppress_fpi_hook != NULL) { + suppress_fpi = xlog_should_suppress_fpi_hook(); + elog(DEBUG1, "FPI suppress hook called: suppress_fpi=%d, doPageWrites=%d", + suppress_fpi, doPageWrites); + } + rdt = XLogRecordAssemble(rmid, info, RedoRecPtr, doPageWrites, &fpw_lsn, &num_fpi, &topxid_included); @@ -605,7 +621,7 @@ XLogRecordAssemble(RmgrId rmid, uint8 info, needs_backup = true; else if (regbuf->flags & REGBUF_NO_IMAGE) needs_backup = false; - else if (!doPageWrites) + else if (!doPageWrites || suppress_fpi) needs_backup = false; else { @@ -617,8 +633,13 @@ XLogRecordAssemble(RmgrId rmid, uint8 info, XLogRecPtr page_lsn = PageGetLSN(regbuf->page); needs_backup = (page_lsn <= RedoRecPtr); + if (!needs_backup) { + /* + * Set fpw_lsn to signal that this record should be + * recomputed if doPageWrites changes. + */ if (*fpw_lsn == InvalidXLogRecPtr || page_lsn < *fpw_lsn) *fpw_lsn = page_lsn; } diff --git a/src/include/access/xloginsert.h b/src/include/access/xloginsert.h index e29c27345ce..92503116b8d 100644 --- a/src/include/access/xloginsert.h +++ b/src/include/access/xloginsert.h @@ -42,6 +42,16 @@ extern int max_replication_apply_lag; extern int max_replication_flush_lag; extern int max_replication_write_lag; +/* NEON: Hook to determine if FPI should be suppressed for a WAL record + * Returns true to suppress FPI, false to allow FPI + * Applies to all resource managers for checkpoint-based FPI triggers. + */ +typedef bool (*xlog_should_suppress_fpi_hook_type)(void); +extern PGDLLIMPORT xlog_should_suppress_fpi_hook_type xlog_should_suppress_fpi_hook; + +/* NEON: Flag set per-record to suppress FPI (set by xlog_should_suppress_fpi_hook) */ +extern bool suppress_fpi; + /* prototypes for public functions in xloginsert.c: */ extern void XLogBeginInsert(void); extern void XLogSetRecordFlags(uint8 flags);