From d045dcb01a7610981f303fe081a04c0ee7a75539 Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Thu, 27 Feb 2025 16:58:22 -0500 Subject: [PATCH 01/19] removed lwlsn code and added hooks for the removed functions --- src/backend/access/transam/xlog.c | 394 +----------------------------- src/include/access/xlog.h | 21 +- 2 files changed, 17 insertions(+), 398 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 6356b23df33..dee2ad13169 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -138,7 +138,7 @@ int max_slot_wal_keep_size_mb = -1; int wal_decode_buffer_size = 512 * 1024; bool track_wal_io_timing = false; uint64 predefined_sysidentifier; -int lastWrittenLsnCacheSize; + #ifdef WAL_DEBUG bool XLOG_DEBUG = false; @@ -207,24 +207,10 @@ const struct config_enum_entry archive_mode_options[] = { {NULL, 0, false} }; -typedef struct LastWrittenLsnCacheEntry -{ - BufferTag key; - XLogRecPtr lsn; - /* double linked list for LRU replacement algorithm */ - dlist_node lru_node; -} LastWrittenLsnCacheEntry; -/* - * Cache of last written LSN for each relation page. - * Also to provide request LSN for smgrnblocks, smgrexists there is pseudokey=InvalidBlockId which stores LSN of last - * relation metadata update. - * Size of the cache is limited by GUC variable lastWrittenLsnCacheSize ("lsn_cache_size"), - * pages are replaced using LRU algorithm, based on L2-list. - * Access to this cache is protected by 'LastWrittenLsnLock'. - */ -static HTAB *lastWrittenLsnCache; + + /* * Statistics for current checkpoint are collected in this global struct. @@ -575,16 +561,7 @@ typedef struct XLogCtlData */ XLogRecPtr lastFpwDisableRecPtr; - /* - * Maximal last written LSN for pages not present in lastWrittenLsnCache - */ - XLogRecPtr maxLastWrittenLsn; - /* - * Double linked list to implement LRU replacement policy for last written LSN cache. - * Access to this list as well as to last written LSN cache is protected by 'LastWrittenLsnLock'. - */ - dlist_head lastWrittenLsnLRU; /* neon: copy of startup's RedoStartLSN for walproposer's use */ XLogRecPtr RedoStartLSN; @@ -764,12 +741,6 @@ static void WALInsertLockAcquireExclusive(void); static void WALInsertLockRelease(void); static void WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt); -static XLogRecPtr SetLastWrittenLSNForBlockRangeInternal(XLogRecPtr lsn, - RelFileLocator rlocator, - ForkNumber forknum, - BlockNumber from, - BlockNumber n_blocks); - /* * 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 @@ -4952,8 +4923,8 @@ XLOGCtlShmemSize(void) Size XLOGShmemSize(void) { - return XLOGCtlShmemSize() + - hash_estimate_size(lastWrittenLsnCacheSize, sizeof(LastWrittenLsnCacheEntry)); + // Removed LwLSN Size as it is no longer in XLog + return XLOGCtlShmemSize(); } void @@ -4985,16 +4956,7 @@ XLOGShmemInit(void) XLogCtl = (XLogCtlData *) ShmemInitStruct("XLOG Ctl", XLOGCtlShmemSize(), &foundXLog); - if (lastWrittenLsnCacheSize > 0) - { - static HASHCTL info; - info.keysize = sizeof(BufferTag); - info.entrysize = sizeof(LastWrittenLsnCacheEntry); - lastWrittenLsnCache = ShmemInitHash("last_written_lsn_cache", - lastWrittenLsnCacheSize, lastWrittenLsnCacheSize, - &info, - HASH_ELEM | HASH_BLOBS); - } + localControlFile = ControlFile; ControlFile = (ControlFileData *) @@ -5829,13 +5791,7 @@ StartupXLOG(void) RedoRecPtr = XLogCtl->RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo; doPageWrites = lastFullPageWrites; - /* - * Setup last written lsn cache, max written LSN. - * Starting from here, we could be modifying pages through REDO, which requires - * the existance of maxLwLsn + LwLsn LRU. - */ - XLogCtl->maxLastWrittenLsn = RedoRecPtr; - dlist_init(&XLogCtl->lastWrittenLsnLRU); + /* REDO */ if (InRecovery) @@ -6682,342 +6638,6 @@ GetInsertRecPtr(void) return recptr; } -/* - * GetLastWrittenLSN -- Returns maximal LSN of written page. - * It returns an upper bound for the last written LSN of a given page, - * either from a cached last written LSN or a global maximum last written LSN. - * If rnode is InvalidOid then we calculate maximum among all cached LSN and maxLastWrittenLsn. - * If cache is large enough, iterating through all hash items may be rather expensive. - * But GetLastWrittenLSN(InvalidOid) is used only by neon_dbsize which is not performance critical. - */ -XLogRecPtr -GetLastWrittenLSN(RelFileLocator rlocator, ForkNumber forknum, BlockNumber blkno) -{ - XLogRecPtr lsn; - LastWrittenLsnCacheEntry* entry; - - Assert(lastWrittenLsnCacheSize != 0); - - LWLockAcquire(LastWrittenLsnLock, LW_SHARED); - - /* Maximal last written LSN among all non-cached pages */ - lsn = XLogCtl->maxLastWrittenLsn; - - if (rlocator.relNumber != InvalidOid) - { - BufferTag key; - key.spcOid = rlocator.spcOid; - key.dbOid = rlocator.dbOid; - key.relNumber = rlocator.relNumber; - key.forkNum = forknum; - key.blockNum = blkno; - entry = hash_search(lastWrittenLsnCache, &key, HASH_FIND, NULL); - if (entry != NULL) - lsn = entry->lsn; - else - { - LWLockRelease(LastWrittenLsnLock); - LWLockAcquire(LastWrittenLsnLock, LW_EXCLUSIVE); - /* - * In case of statements CREATE TABLE AS SELECT... or INSERT FROM SELECT... we are fetching data from source table - * and storing it in destination table. It cause problems with prefetch last-written-lsn is known for the pages of - * source table (which for example happens after compute restart). In this case we get get global value of - * last-written-lsn which is changed frequently as far as we are writing pages of destination table. - * As a result request-lsn for the prefetch and request-let when this page is actually needed are different - * and we got exported prefetch request. So it actually disarms prefetch. - * To prevent that, we re-insert the page with the latest LSN, so that it's - * less likely the LSN for this page will get evicted from the LwLsnCache - * before the page is read. - */ - lsn = SetLastWrittenLSNForBlockRangeInternal(lsn, rlocator, forknum, blkno, 1); - } - } - else - { - HASH_SEQ_STATUS seq; - /* Find maximum of all cached LSNs */ - hash_seq_init(&seq, lastWrittenLsnCache); - while ((entry = (LastWrittenLsnCacheEntry *) hash_seq_search(&seq)) != NULL) - { - if (entry->lsn > lsn) - lsn = entry->lsn; - } - } - LWLockRelease(LastWrittenLsnLock); - - return lsn; -} - -/* - * GetLastWrittenLSN -- Returns maximal LSN of written page. - * It returns an upper bound for the last written LSN of a given page, - * either from a cached last written LSN or a global maximum last written LSN. - * If rnode is InvalidOid then we calculate maximum among all cached LSN and maxLastWrittenLsn. - * If cache is large enough, iterating through all hash items may be rather expensive. - * But GetLastWrittenLSN(InvalidOid) is used only by neon_dbsize which is not performance critical. - */ -void -GetLastWrittenLSNv(RelFileLocator relfilenode, ForkNumber forknum, - BlockNumber blkno, int nblocks, XLogRecPtr *lsns) -{ - LastWrittenLsnCacheEntry* entry; - XLogRecPtr lsn; - - Assert(lastWrittenLsnCacheSize != 0); - Assert(nblocks > 0); - Assert(PointerIsValid(lsns)); - - LWLockAcquire(LastWrittenLsnLock, LW_SHARED); - - if (relfilenode.relNumber != InvalidOid) - { - BufferTag key; - bool missed_keys = false; - - key.spcOid = relfilenode.spcOid; - key.dbOid = relfilenode.dbOid; - key.relNumber = relfilenode.relNumber; - key.forkNum = forknum; - - for (int i = 0; i < nblocks; i++) - { - /* Maximal last written LSN among all non-cached pages */ - key.blockNum = blkno + i; - - entry = hash_search(lastWrittenLsnCache, &key, HASH_FIND, NULL); - if (entry != NULL) - { - lsns[i] = entry->lsn; - } - else - { - /* Mark this block's LSN as missing - we'll update the LwLSN for missing blocks in bulk later */ - lsns[i] = InvalidXLogRecPtr; - missed_keys = true; - } - } - - /* - * If we had any missing LwLSN entries, we add the missing ones now. - * By doing the insertions in one batch, we decrease lock contention. - */ - if (missed_keys) - { - LWLockRelease(LastWrittenLsnLock); - LWLockAcquire(LastWrittenLsnLock, LW_EXCLUSIVE); - - lsn = XLogCtl->maxLastWrittenLsn; - - for (int i = 0; i < nblocks; i++) - { - if (lsns[i] == InvalidXLogRecPtr) - { - lsns[i] = lsn; - SetLastWrittenLSNForBlockRangeInternal(lsn, relfilenode, forknum, blkno + i, 1); - } - } - } - } - else - { - HASH_SEQ_STATUS seq; - lsn = XLogCtl->maxLastWrittenLsn; - /* Find maximum of all cached LSNs */ - hash_seq_init(&seq, lastWrittenLsnCache); - while ((entry = (LastWrittenLsnCacheEntry *) hash_seq_search(&seq)) != NULL) - { - if (entry->lsn > lsn) - lsn = entry->lsn; - } - - for (int i = 0; i < nblocks; i++) - lsns[i] = lsn; - } - LWLockRelease(LastWrittenLsnLock); -} - -/* - * Guts for SetLastWrittenLSNForBlockRange. - * Caller must ensure LastWrittenLsnLock is held in exclusive mode. - */ -static XLogRecPtr -SetLastWrittenLSNForBlockRangeInternal(XLogRecPtr lsn, - RelFileLocator rlocator, - ForkNumber forknum, - BlockNumber from, - BlockNumber n_blocks) -{ - if (rlocator.relNumber == InvalidOid) - { - if (lsn > XLogCtl->maxLastWrittenLsn) - XLogCtl->maxLastWrittenLsn = lsn; - else - lsn = XLogCtl->maxLastWrittenLsn; - } - else - { - LastWrittenLsnCacheEntry* entry; - BufferTag key; - bool found; - BlockNumber i; - - key.spcOid = rlocator.spcOid; - key.dbOid = rlocator.dbOid; - key.relNumber = rlocator.relNumber; - key.forkNum = forknum; - for (i = 0; i < n_blocks; i++) - { - key.blockNum = from + i; - entry = hash_search(lastWrittenLsnCache, &key, HASH_ENTER, &found); - if (found) - { - if (lsn > entry->lsn) - entry->lsn = lsn; - else - lsn = entry->lsn; - /* Unlink from LRU list */ - dlist_delete(&entry->lru_node); - } - else - { - entry->lsn = lsn; - if (hash_get_num_entries(lastWrittenLsnCache) > lastWrittenLsnCacheSize) - { - /* Replace least recently used entry */ - LastWrittenLsnCacheEntry* victim = dlist_container(LastWrittenLsnCacheEntry, lru_node, dlist_pop_head_node(&XLogCtl->lastWrittenLsnLRU)); - /* Adjust max LSN for not cached relations/chunks if needed */ - if (victim->lsn > XLogCtl->maxLastWrittenLsn) - XLogCtl->maxLastWrittenLsn = victim->lsn; - - hash_search(lastWrittenLsnCache, victim, HASH_REMOVE, NULL); - } - } - /* Link to the end of LRU list */ - dlist_push_tail(&XLogCtl->lastWrittenLsnLRU, &entry->lru_node); - } - } - return lsn; -} - -/* - * SetLastWrittenLSNForBlockRange -- Set maximal LSN of written page range. - * We maintain cache of last written LSNs with limited size and LRU replacement - * policy. Keeping last written LSN for each page allows to use old LSN when - * requesting pages of unchanged or appended relations. Also it is critical for - * efficient work of prefetch in case massive update operations (like vacuum or remove). - * - * rlocator.relNumber can be InvalidOid, in this case maxLastWrittenLsn is updated. - * SetLastWrittenLsn with dummy rlocator is used by createdb and dbase_redo functions. - */ -XLogRecPtr -SetLastWrittenLSNForBlockRange(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber forknum, BlockNumber from, BlockNumber n_blocks) -{ - if (lsn == InvalidXLogRecPtr || n_blocks == 0 || lastWrittenLsnCacheSize == 0) - return lsn; - - LWLockAcquire(LastWrittenLsnLock, LW_EXCLUSIVE); - lsn = SetLastWrittenLSNForBlockRangeInternal(lsn, rlocator, forknum, from, n_blocks); - LWLockRelease(LastWrittenLsnLock); - - return lsn; -} - -/* - * SetLastWrittenLSNForBlockv -- Set maximal LSN of pages to their respective - * LSNs. - * - * We maintain cache of last written LSNs with limited size and LRU replacement - * policy. Keeping last written LSN for each page allows to use old LSN when - * requesting pages of unchanged or appended relations. Also it is critical for - * efficient work of prefetch in case massive update operations (like vacuum or remove). - */ -XLogRecPtr -SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, - ForkNumber forknum, BlockNumber blockno, - int nblocks) -{ - LastWrittenLsnCacheEntry* entry; - BufferTag key; - bool found; - XLogRecPtr max = InvalidXLogRecPtr; - - if (lsns == NULL || nblocks == 0 || lastWrittenLsnCacheSize == 0 || - relfilenode.relNumber == InvalidOid) - return InvalidXLogRecPtr; - - key.relNumber = relfilenode.relNumber; - key.dbOid = relfilenode.dbOid; - key.spcOid = relfilenode.spcOid; - key.forkNum = forknum; - - LWLockAcquire(LastWrittenLsnLock, LW_EXCLUSIVE); - - for (int i = 0; i < nblocks; i++) - { - XLogRecPtr lsn = lsns[i]; - - key.blockNum = blockno + i; - entry = hash_search(lastWrittenLsnCache, &key, HASH_ENTER, &found); - if (found) - { - if (lsn > entry->lsn) - entry->lsn = lsn; - else - lsn = entry->lsn; - /* Unlink from LRU list */ - dlist_delete(&entry->lru_node); - } - else - { - entry->lsn = lsn; - if (hash_get_num_entries(lastWrittenLsnCache) > lastWrittenLsnCacheSize) - { - /* Replace least recently used entry */ - LastWrittenLsnCacheEntry* victim = dlist_container(LastWrittenLsnCacheEntry, lru_node, dlist_pop_head_node(&XLogCtl->lastWrittenLsnLRU)); - /* Adjust max LSN for not cached relations/chunks if needed */ - if (victim->lsn > XLogCtl->maxLastWrittenLsn) - XLogCtl->maxLastWrittenLsn = victim->lsn; - - hash_search(lastWrittenLsnCache, victim, HASH_REMOVE, NULL); - } - } - /* Link to the end of LRU list */ - dlist_push_tail(&XLogCtl->lastWrittenLsnLRU, &entry->lru_node); - max = Max(max, lsn); - } - - LWLockRelease(LastWrittenLsnLock); - - return max; -} - -/* - * SetLastWrittenLSNForBlock -- Set maximal LSN for block - */ -XLogRecPtr -SetLastWrittenLSNForBlock(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber forknum, BlockNumber blkno) -{ - return SetLastWrittenLSNForBlockRange(lsn, rlocator, forknum, blkno, 1); -} - -/* - * SetLastWrittenLSNForRelation -- Set maximal LSN for relation metadata - */ -XLogRecPtr -SetLastWrittenLSNForRelation(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber forknum) -{ - return SetLastWrittenLSNForBlock(lsn, rlocator, forknum, REL_METADATA_PSEUDO_BLOCKNO); -} - -/* - * SetLastWrittenLSNForDatabase -- Set maximal LSN for the whole database - */ -XLogRecPtr -SetLastWrittenLSNForDatabase(XLogRecPtr lsn) -{ - RelFileLocator dummyNode = {InvalidOid, InvalidOid, InvalidOid}; - return SetLastWrittenLSNForBlock(lsn, dummyNode, MAIN_FORKNUM, 0); -} void SetRedoStartLsn(XLogRecPtr RedoStartLSN) diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 3a92973bf2f..b1f6e37d739 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -267,25 +267,24 @@ extern XLogRecPtr GetLastImportantRecPtr(void); /* neon specifics */ -extern XLogRecPtr SetLastWrittenLSNForBlock(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); -extern XLogRecPtr SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, - ForkNumber forknum, BlockNumber blockno, - int nblocks); -extern XLogRecPtr SetLastWrittenLSNForBlockRange(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber from, BlockNumber n_blocks); -extern XLogRecPtr SetLastWrittenLSNForDatabase(XLogRecPtr lsn); -extern XLogRecPtr SetLastWrittenLSNForRelation(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum); -extern XLogRecPtr GetLastWrittenLSN(RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); -extern void GetLastWrittenLSNv(RelFileLocator relfilenode, ForkNumber forknum, - BlockNumber blkno, int nblocks, XLogRecPtr *lsns); - extern void SetRedoStartLsn(XLogRecPtr RedoStartLSN); extern XLogRecPtr GetRedoStartLsn(void); + extern void SetWalWriterSleeping(bool sleeping); extern Size WALReadFromBuffers(char *dstbuf, XLogRecPtr startptr, Size count, TimeLineID tli); +/* Hooks for LwLSN */ +typedef XLogRecPtr (*get_lwlsn_hook_type)(RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); +typedef void (*get_lwlsn_v_hook_type)(RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno, int nblocks, XLogRecPtr *lsns); +typedef XLogRecPtr (*set_lwlsn_block_range_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber from, BlockNumber n_blocks); +typedef XLogRecPtr (*set_lwlsn_block_v_hook_type)(const XLogRecPtr *lsns, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blockno, int nblocks); +typedef XLogRecPtr (*set_lwlsn_block_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); +typedef XLogRecPtr (*set_lwlsn_relation_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum); +typedef XLogRecPtr (*set_lwlsn_db_hook_type)(XLogRecPtr lsn); + /* * Routines used by xlogrecovery.c to call back into xlog.c during recovery. */ From 5d209d3a9b50d8531e64528f37e37a8124a20f89 Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Fri, 28 Feb 2025 13:00:18 -0500 Subject: [PATCH 02/19] replaced lwlsn fn calls with hook calls --- src/backend/access/gin/gininsert.c | 4 ++-- src/backend/access/gist/gistbuild.c | 8 ++++---- src/backend/access/spgist/spginsert.c | 4 ++-- src/backend/access/transam/xlog.c | 7 ------- src/backend/catalog/storage.c | 2 +- src/backend/commands/dbcommands.c | 9 +++++---- src/backend/utils/misc/guc_tables.c | 18 +++++++++--------- src/include/access/xlog.h | 12 ++++++++++-- 8 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index bc82e2df9e8..6a9c77bdc51 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -418,8 +418,8 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo) log_newpage_range(index, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index), true); - SetLastWrittenLSNForBlockRange(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); - SetLastWrittenLSNForRelation(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); + set_lwlsn_block_range_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); + set_lwlsn_relation_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); } smgr_end_unlogged_build(index->rd_smgr); diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c index 91ebf84fe2d..feb62489e6e 100644 --- a/src/backend/access/gist/gistbuild.c +++ b/src/backend/access/gist/gistbuild.c @@ -340,10 +340,10 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) log_newpage_range(index, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index), true); - SetLastWrittenLSNForBlockRange(XactLastRecEnd, + set_lwlsn_block_range_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); - SetLastWrittenLSNForRelation(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); + set_lwlsn_relation_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); } smgr_end_unlogged_build(index->rd_smgr); @@ -464,9 +464,9 @@ gist_indexsortbuild(GISTBuildState *state) { XLogRecPtr lsn = GetRedoRecPtr(); - SetLastWrittenLSNForBlock(lsn, state->indexrel->rd_smgr->smgr_rlocator.locator, + set_lwlsn_block_hook(lsn, state->indexrel->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, GIST_ROOT_BLKNO); - SetLastWrittenLSNForRelation(lsn, state->indexrel->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); + set_lwlsn_relation_hook(lsn, state->indexrel->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); } pfree(levelstate); diff --git a/src/backend/access/spgist/spginsert.c b/src/backend/access/spgist/spginsert.c index f3652531867..1a3db737c9e 100644 --- a/src/backend/access/spgist/spginsert.c +++ b/src/backend/access/spgist/spginsert.c @@ -142,9 +142,9 @@ spgbuild(Relation heap, Relation index, IndexInfo *indexInfo) log_newpage_range(index, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index), true); - SetLastWrittenLSNForBlockRange(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, + set_lwlsn_block_range_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); - SetLastWrittenLSNForRelation(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); + set_lwlsn_relation_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); } smgr_end_unlogged_build(index->rd_smgr); diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index dee2ad13169..0fd3626280f 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -139,7 +139,6 @@ int wal_decode_buffer_size = 512 * 1024; bool track_wal_io_timing = false; uint64 predefined_sysidentifier; - #ifdef WAL_DEBUG bool XLOG_DEBUG = false; #endif @@ -210,8 +209,6 @@ const struct config_enum_entry archive_mode_options[] = { - - /* * Statistics for current checkpoint are collected in this global struct. * Because only the checkpointer or a stand-alone backend can perform @@ -4956,8 +4953,6 @@ XLOGShmemInit(void) XLogCtl = (XLogCtlData *) ShmemInitStruct("XLOG Ctl", XLOGCtlShmemSize(), &foundXLog); - - localControlFile = ControlFile; ControlFile = (ControlFileData *) ShmemInitStruct("Control File", sizeof(ControlFileData), &foundCFile); @@ -5791,8 +5786,6 @@ StartupXLOG(void) RedoRecPtr = XLogCtl->RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo; doPageWrites = lastFullPageWrites; - - /* REDO */ if (InRecovery) { diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c index a97e7dc25d3..bde9ac18271 100644 --- a/src/backend/catalog/storage.c +++ b/src/backend/catalog/storage.c @@ -197,7 +197,7 @@ log_smgrcreate(const RelFileLocator *rlocator, ForkNumber forkNum) XLogBeginInsert(); XLogRegisterData((char *) &xlrec, sizeof(xlrec)); lsn = XLogInsert(RM_SMGR_ID, XLOG_SMGR_CREATE | XLR_SPECIAL_REL_UPDATE); - SetLastWrittenLSNForRelation(lsn, *rlocator, forkNum); + set_lwlsn_relation_hook(lsn, *rlocator, forkNum); } /* diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 253c3c36c99..2baf5dbe1b0 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -29,6 +29,7 @@ #include "access/multixact.h" #include "access/tableam.h" #include "access/xact.h" +#include "access/xlog.h" #include "access/xloginsert.h" #include "access/xlogrecovery.h" #include "access/xlogutils.h" @@ -1515,7 +1516,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) /* * Update global last written LSN after wal-logging create database command */ - SetLastWrittenLSNForDatabase(XactLastRecEnd); + set_lwlsn_db_hook(XactLastRecEnd); /* * Close pg_database, but keep lock till commit. @@ -2182,7 +2183,7 @@ movedb(const char *dbname, const char *tblspcname) lsn = XLogInsert(RM_DBASE_ID, XLOG_DBASE_CREATE_FILE_COPY | XLR_SPECIAL_REL_UPDATE); // TODO: Do we really need to set the LSN here? - SetLastWrittenLSNForDatabase(lsn); + set_lwlsn_db_hook(lsn); } /* @@ -3357,7 +3358,7 @@ dbase_redo(XLogReaderState *record) */ { XLogRecPtr lsn = record->EndRecPtr; - SetLastWrittenLSNForDatabase(lsn); + set_lwlsn_db_hook(lsn); } pfree(src_path); @@ -3387,7 +3388,7 @@ dbase_redo(XLogReaderState *record) */ { XLogRecPtr lsn = record->EndRecPtr; - SetLastWrittenLSNForDatabase(lsn); + set_lwlsn_db_hook(lsn); } pfree(dbpath); diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 743be6fcc3e..cb7e46171ae 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -2410,15 +2410,15 @@ struct config_int ConfigureNamesInt[] = check_transaction_buffers, NULL, NULL }, - { - {"lsn_cache_size", PGC_POSTMASTER, UNGROUPED, - gettext_noop("Size of last written LSN cache used by Neon."), - NULL - }, - &lastWrittenLsnCacheSize, - 128*1024, 1024, INT_MAX, - NULL, NULL, NULL - }, + // { + // {"lsn_cache_size", PGC_POSTMASTER, UNGROUPED, + // gettext_noop("Size of last written LSN cache used by Neon."), + // NULL + // }, + // &lastWrittenLsnCacheSize, + // 128*1024, 1024, INT_MAX, + // NULL, NULL, NULL + // }, { {"temp_buffers", PGC_USERSET, RESOURCES_MEM, diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index b1f6e37d739..3b0825be58e 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -68,7 +68,6 @@ extern PGDLLIMPORT bool track_wal_io_timing; extern PGDLLIMPORT int wal_decode_buffer_size; extern PGDLLIMPORT int CheckPointSegments; -extern int lastWrittenLsnCacheSize; /* Archive modes */ @@ -270,7 +269,6 @@ extern XLogRecPtr GetLastImportantRecPtr(void); extern void SetRedoStartLsn(XLogRecPtr RedoStartLSN); extern XLogRecPtr GetRedoStartLsn(void); - extern void SetWalWriterSleeping(bool sleeping); extern Size WALReadFromBuffers(char *dstbuf, XLogRecPtr startptr, Size count, @@ -284,6 +282,16 @@ typedef XLogRecPtr (*set_lwlsn_block_v_hook_type)(const XLogRecPtr *lsns, RelFil typedef XLogRecPtr (*set_lwlsn_block_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); typedef XLogRecPtr (*set_lwlsn_relation_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum); typedef XLogRecPtr (*set_lwlsn_db_hook_type)(XLogRecPtr lsn); +typedef int (*get_lwlsn_cache_size_type) (void); + +extern get_lwlsn_hook_type get_lwlsn_hook; +extern get_lwlsn_v_hook_type get_lwlsn_v_hook; +extern set_lwlsn_block_range_hook_type set_lwlsn_block_range_hook; +extern set_lwlsn_block_v_hook_type set_lwlsn_block_v_hook; +extern set_lwlsn_block_hook_type set_lwlsn_block_hook; +extern set_lwlsn_relation_hook_type set_lwlsn_relation_hook; +extern set_lwlsn_db_hook_type set_lwlsn_db_hook; +extern get_lwlsn_cache_size_type get_lwlsn_cache_size; /* * Routines used by xlogrecovery.c to call back into xlog.c during recovery. From af7e7e9a62305e4031c637f0af3bba551295d931 Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Fri, 28 Feb 2025 16:33:08 -0500 Subject: [PATCH 03/19] removed unnecessary function name changes, got pg17 building with lwlsn cache moved to neon ext --- src/backend/access/gin/gininsert.c | 4 +- src/backend/access/gist/gistbuild.c | 8 +- src/backend/access/spgist/spginsert.c | 4 +- src/backend/access/transam/xlog.c | 118 ++++++++++++++++++++++++++ src/backend/catalog/storage.c | 2 +- src/backend/commands/dbcommands.c | 6 +- src/backend/utils/misc/guc_tables.c | 10 --- src/include/access/xlog.h | 11 +++ 8 files changed, 141 insertions(+), 22 deletions(-) diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index 6a9c77bdc51..bc82e2df9e8 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -418,8 +418,8 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo) log_newpage_range(index, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index), true); - set_lwlsn_block_range_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); - set_lwlsn_relation_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); + SetLastWrittenLSNForBlockRange(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); + SetLastWrittenLSNForRelation(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); } smgr_end_unlogged_build(index->rd_smgr); diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c index feb62489e6e..91ebf84fe2d 100644 --- a/src/backend/access/gist/gistbuild.c +++ b/src/backend/access/gist/gistbuild.c @@ -340,10 +340,10 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) log_newpage_range(index, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index), true); - set_lwlsn_block_range_hook(XactLastRecEnd, + SetLastWrittenLSNForBlockRange(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); - set_lwlsn_relation_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); + SetLastWrittenLSNForRelation(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); } smgr_end_unlogged_build(index->rd_smgr); @@ -464,9 +464,9 @@ gist_indexsortbuild(GISTBuildState *state) { XLogRecPtr lsn = GetRedoRecPtr(); - set_lwlsn_block_hook(lsn, state->indexrel->rd_smgr->smgr_rlocator.locator, + SetLastWrittenLSNForBlock(lsn, state->indexrel->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, GIST_ROOT_BLKNO); - set_lwlsn_relation_hook(lsn, state->indexrel->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); + SetLastWrittenLSNForRelation(lsn, state->indexrel->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); } pfree(levelstate); diff --git a/src/backend/access/spgist/spginsert.c b/src/backend/access/spgist/spginsert.c index 1a3db737c9e..f3652531867 100644 --- a/src/backend/access/spgist/spginsert.c +++ b/src/backend/access/spgist/spginsert.c @@ -142,9 +142,9 @@ spgbuild(Relation heap, Relation index, IndexInfo *indexInfo) log_newpage_range(index, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index), true); - set_lwlsn_block_range_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, + SetLastWrittenLSNForBlockRange(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); - set_lwlsn_relation_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); + SetLastWrittenLSNForRelation(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); } smgr_end_unlogged_build(index->rd_smgr); diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 0fd3626280f..e66b3ed7d20 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6631,6 +6631,124 @@ GetInsertRecPtr(void) return recptr; } +get_lwlsn_hook_type get_lwlsn_hook = NULL; +get_lwlsn_v_hook_type get_lwlsn_v_hook = NULL; +set_lwlsn_block_range_hook_type set_lwlsn_block_range_hook = NULL; +set_lwlsn_block_v_hook_type set_lwlsn_block_v_hook = NULL; +set_lwlsn_block_hook_type set_lwlsn_block_hook = NULL; +set_lwlsn_relation_hook_type set_lwlsn_relation_hook = NULL; +set_lwlsn_db_hook_type set_lwlsn_db_hook = NULL; +get_lwlsn_cache_size_type get_lwlsn_cache_size = NULL; + +/* + * GetLastWrittenLSN -- Returns maximal LSN of written page. + * It returns an upper bound for the last written LSN of a given page, + * either from a cached last written LSN or a global maximum last written LSN. + * If rnode is InvalidOid then we calculate maximum among all cached LSN and maxLastWrittenLsn. + * If cache is large enough, iterating through all hash items may be rather expensive. + * But GetLastWrittenLSN(InvalidOid) is used only by neon_dbsize which is not performance critical. + */ +XLogRecPtr +GetLastWrittenLSN(RelFileLocator rlocator, ForkNumber forknum, BlockNumber blkno) +{ + if (get_lwlsn_hook) + { + get_lwlsn_hook(rlocator, forknum, blkno); + } +} + +/* + * GetLastWrittenLSN -- Returns maximal LSN of written page. + * It returns an upper bound for the last written LSN of a given page, + * either from a cached last written LSN or a global maximum last written LSN. + * If rnode is InvalidOid then we calculate maximum among all cached LSN and maxLastWrittenLsn. + * If cache is large enough, iterating through all hash items may be rather expensive. + * But GetLastWrittenLSN(InvalidOid) is used only by neon_dbsize which is not performance critical. + */ +void +GetLastWrittenLSNv(RelFileLocator relfilenode, ForkNumber forknum, + BlockNumber blkno, int nblocks, XLogRecPtr *lsns) +{ + if (get_lwlsn_v_hook) + { + get_lwlsn_v_hook(relfilenode, forknum, blkno, nblocks, lsns); + } +} + +/* + * SetLastWrittenLSNForBlockRange -- Set maximal LSN of written page range. + * We maintain cache of last written LSNs with limited size and LRU replacement + * policy. Keeping last written LSN for each page allows to use old LSN when + * requesting pages of unchanged or appended relations. Also it is critical for + * efficient work of prefetch in case massive update operations (like vacuum or remove). + * + * rlocator.relNumber can be InvalidOid, in this case maxLastWrittenLsn is updated. + * SetLastWrittenLsn with dummy rlocator is used by createdb and dbase_redo functions. + */ +XLogRecPtr +SetLastWrittenLSNForBlockRange(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber forknum, BlockNumber from, BlockNumber n_blocks) +{ + if (set_lwlsn_block_range_hook) + { + set_lwlsn_block_range_hook(lsn, rlocator, forknum, from, n_blocks); + } +} + +/* + * SetLastWrittenLSNForBlockv -- Set maximal LSN of pages to their respective + * LSNs. + * + * We maintain cache of last written LSNs with limited size and LRU replacement + * policy. Keeping last written LSN for each page allows to use old LSN when + * requesting pages of unchanged or appended relations. Also it is critical for + * efficient work of prefetch in case massive update operations (like vacuum or remove). + */ +XLogRecPtr +SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, + ForkNumber forknum, BlockNumber blockno, + int nblocks) +{ + if (set_lwlsn_block_v_hook) + { + set_lwlsn_block_v_hook(lsns, relfilenode, forknum, blockno, nblocks); + } +} + +/* + * SetLastWrittenLSNForBlock -- Set maximal LSN for block + */ +XLogRecPtr +SetLastWrittenLSNForBlock(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber forknum, BlockNumber blkno) +{ + if (set_lwlsn_block_hook) + { + set_lwlsn_block_hook(lsn, rlocator, forknum, blkno); + } +} + +/* + * SetLastWrittenLSNForRelation -- Set maximal LSN for relation metadata + */ +XLogRecPtr +SetLastWrittenLSNForRelation(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber forknum) +{ + if (set_lwlsn_relation_hook) + { + set_lwlsn_relation_hook(lsn, rlocator, forknum); + } +} + +/* + * SetLastWrittenLSNForDatabase -- Set maximal LSN for the whole database + */ +XLogRecPtr +SetLastWrittenLSNForDatabase(XLogRecPtr lsn) +{ + if (set_lwlsn_db_hook) + { + set_lwlsn_db_hook(lsn); + } +}g void SetRedoStartLsn(XLogRecPtr RedoStartLSN) diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c index bde9ac18271..a97e7dc25d3 100644 --- a/src/backend/catalog/storage.c +++ b/src/backend/catalog/storage.c @@ -197,7 +197,7 @@ log_smgrcreate(const RelFileLocator *rlocator, ForkNumber forkNum) XLogBeginInsert(); XLogRegisterData((char *) &xlrec, sizeof(xlrec)); lsn = XLogInsert(RM_SMGR_ID, XLOG_SMGR_CREATE | XLR_SPECIAL_REL_UPDATE); - set_lwlsn_relation_hook(lsn, *rlocator, forkNum); + SetLastWrittenLSNForRelation(lsn, *rlocator, forkNum); } /* diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 2baf5dbe1b0..05c23ff6f53 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -1516,7 +1516,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) /* * Update global last written LSN after wal-logging create database command */ - set_lwlsn_db_hook(XactLastRecEnd); + SetLastWrittenLSNForDatabase(XactLastRecEnd); /* * Close pg_database, but keep lock till commit. @@ -2183,7 +2183,7 @@ movedb(const char *dbname, const char *tblspcname) lsn = XLogInsert(RM_DBASE_ID, XLOG_DBASE_CREATE_FILE_COPY | XLR_SPECIAL_REL_UPDATE); // TODO: Do we really need to set the LSN here? - set_lwlsn_db_hook(lsn); + SetLastWrittenLSNForDatabase(lsn); } /* @@ -3358,7 +3358,7 @@ dbase_redo(XLogReaderState *record) */ { XLogRecPtr lsn = record->EndRecPtr; - set_lwlsn_db_hook(lsn); + SetLastWrittenLSNForDatabase(lsn); } pfree(src_path); diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index cb7e46171ae..5ec8d12570d 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -2410,16 +2410,6 @@ struct config_int ConfigureNamesInt[] = check_transaction_buffers, NULL, NULL }, - // { - // {"lsn_cache_size", PGC_POSTMASTER, UNGROUPED, - // gettext_noop("Size of last written LSN cache used by Neon."), - // NULL - // }, - // &lastWrittenLsnCacheSize, - // 128*1024, 1024, INT_MAX, - // NULL, NULL, NULL - // }, - { {"temp_buffers", PGC_USERSET, RESOURCES_MEM, gettext_noop("Sets the maximum number of temporary buffers used by each session."), diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 3b0825be58e..1f16bcfc10f 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -266,6 +266,17 @@ extern XLogRecPtr GetLastImportantRecPtr(void); /* neon specifics */ +extern XLogRecPtr SetLastWrittenLSNForBlock(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); +extern XLogRecPtr SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, + ForkNumber forknum, BlockNumber blockno, + int nblocks); +extern XLogRecPtr SetLastWrittenLSNForBlockRange(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber from, BlockNumber n_blocks); +extern XLogRecPtr SetLastWrittenLSNForDatabase(XLogRecPtr lsn); +extern XLogRecPtr SetLastWrittenLSNForRelation(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum); +extern XLogRecPtr GetLastWrittenLSN(RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); +extern void GetLastWrittenLSNv(RelFileLocator relfilenode, ForkNumber forknum, + BlockNumber blkno, int nblocks, XLogRecPtr *lsns); + extern void SetRedoStartLsn(XLogRecPtr RedoStartLSN); extern XLogRecPtr GetRedoStartLsn(void); From 282ca243337cfa8231e44c3c43d5dd49164c7f56 Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Mon, 3 Mar 2025 10:47:38 -0500 Subject: [PATCH 04/19] fixed syntax issues --- src/backend/access/transam/xlog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index e66b3ed7d20..adadba432c0 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6748,7 +6748,7 @@ SetLastWrittenLSNForDatabase(XLogRecPtr lsn) { set_lwlsn_db_hook(lsn); } -}g +} void SetRedoStartLsn(XLogRecPtr RedoStartLSN) From 8b83aa1e01e5649be40e464222eb65eb6edba5fd Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Mon, 3 Mar 2025 11:42:47 -0500 Subject: [PATCH 05/19] made setter methods of lwlsn neon-internal only as they aren't called in postgres --- src/backend/access/transam/xlog.c | 40 ++++--------------------------- src/include/access/xlog.h | 3 --- 2 files changed, 5 insertions(+), 38 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index adadba432c0..db998cbbd0a 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6640,41 +6640,6 @@ set_lwlsn_relation_hook_type set_lwlsn_relation_hook = NULL; set_lwlsn_db_hook_type set_lwlsn_db_hook = NULL; get_lwlsn_cache_size_type get_lwlsn_cache_size = NULL; -/* - * GetLastWrittenLSN -- Returns maximal LSN of written page. - * It returns an upper bound for the last written LSN of a given page, - * either from a cached last written LSN or a global maximum last written LSN. - * If rnode is InvalidOid then we calculate maximum among all cached LSN and maxLastWrittenLsn. - * If cache is large enough, iterating through all hash items may be rather expensive. - * But GetLastWrittenLSN(InvalidOid) is used only by neon_dbsize which is not performance critical. - */ -XLogRecPtr -GetLastWrittenLSN(RelFileLocator rlocator, ForkNumber forknum, BlockNumber blkno) -{ - if (get_lwlsn_hook) - { - get_lwlsn_hook(rlocator, forknum, blkno); - } -} - -/* - * GetLastWrittenLSN -- Returns maximal LSN of written page. - * It returns an upper bound for the last written LSN of a given page, - * either from a cached last written LSN or a global maximum last written LSN. - * If rnode is InvalidOid then we calculate maximum among all cached LSN and maxLastWrittenLsn. - * If cache is large enough, iterating through all hash items may be rather expensive. - * But GetLastWrittenLSN(InvalidOid) is used only by neon_dbsize which is not performance critical. - */ -void -GetLastWrittenLSNv(RelFileLocator relfilenode, ForkNumber forknum, - BlockNumber blkno, int nblocks, XLogRecPtr *lsns) -{ - if (get_lwlsn_v_hook) - { - get_lwlsn_v_hook(relfilenode, forknum, blkno, nblocks, lsns); - } -} - /* * SetLastWrittenLSNForBlockRange -- Set maximal LSN of written page range. * We maintain cache of last written LSNs with limited size and LRU replacement @@ -6692,6 +6657,7 @@ SetLastWrittenLSNForBlockRange(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumb { set_lwlsn_block_range_hook(lsn, rlocator, forknum, from, n_blocks); } + return lsn; } /* @@ -6712,6 +6678,7 @@ SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, { set_lwlsn_block_v_hook(lsns, relfilenode, forknum, blockno, nblocks); } + return lsn; } /* @@ -6724,6 +6691,7 @@ SetLastWrittenLSNForBlock(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber fo { set_lwlsn_block_hook(lsn, rlocator, forknum, blkno); } + return lsn; } /* @@ -6736,6 +6704,7 @@ SetLastWrittenLSNForRelation(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber { set_lwlsn_relation_hook(lsn, rlocator, forknum); } + return lsn; } /* @@ -6748,6 +6717,7 @@ SetLastWrittenLSNForDatabase(XLogRecPtr lsn) { set_lwlsn_db_hook(lsn); } + return lsn; } void diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 1f16bcfc10f..b8e71742e5a 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -273,9 +273,6 @@ extern XLogRecPtr SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLoca extern XLogRecPtr SetLastWrittenLSNForBlockRange(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber from, BlockNumber n_blocks); extern XLogRecPtr SetLastWrittenLSNForDatabase(XLogRecPtr lsn); extern XLogRecPtr SetLastWrittenLSNForRelation(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum); -extern XLogRecPtr GetLastWrittenLSN(RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); -extern void GetLastWrittenLSNv(RelFileLocator relfilenode, ForkNumber forknum, - BlockNumber blkno, int nblocks, XLogRecPtr *lsns); extern void SetRedoStartLsn(XLogRecPtr RedoStartLSN); extern XLogRecPtr GetRedoStartLsn(void); From 623de69a47de8755e4f80bca94a0b5fe57ad6d6c Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Mon, 3 Mar 2025 14:29:50 -0500 Subject: [PATCH 06/19] updated null hook behaviour for SetLastWrittenLSNForBlockv --- src/backend/access/transam/xlog.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index db998cbbd0a..ede87dd3dd5 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6678,7 +6678,16 @@ SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, { set_lwlsn_block_v_hook(lsns, relfilenode, forknum, blockno, nblocks); } - return lsn; + // Behaviour in case the hook is not set. Taken from the implemenatation of SetLastWrittenLSNForBlockv in neon_lwlc.c + if (lsns == NULL || nblocks == 0) { + return InvalidXLogRecPtr; + } else { + XLogRecPtr max = InvalidXLogRecPtr; + for (int i = 0; i < nblocks; i ++) { + max = Max(max, lsns[i]); + } + return max; + } } /* From 24595554c8c3ec7e0082428d436041d58962ee89 Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Tue, 4 Mar 2025 13:04:30 -0500 Subject: [PATCH 07/19] added callback to startup shmem init hook --- src/backend/access/transam/xlog.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index ede87dd3dd5..43c9919b725 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -4953,6 +4953,10 @@ XLOGShmemInit(void) XLogCtl = (XLogCtlData *) ShmemInitStruct("XLOG Ctl", XLOGCtlShmemSize(), &foundXLog); + if (shmem_startup_hook) { + shmem_startup_hook(); + } + localControlFile = ControlFile; ControlFile = (ControlFileData *) ShmemInitStruct("Control File", sizeof(ControlFileData), &foundCFile); From ab6693bbfb5a0e33283771d8a14a2e055f2a294c Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Wed, 5 Mar 2025 10:14:11 -0500 Subject: [PATCH 08/19] added missing return statements --- src/backend/access/transam/xlog.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 43c9919b725..193ded91a44 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6659,7 +6659,7 @@ SetLastWrittenLSNForBlockRange(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumb { if (set_lwlsn_block_range_hook) { - set_lwlsn_block_range_hook(lsn, rlocator, forknum, from, n_blocks); + return set_lwlsn_block_range_hook(lsn, rlocator, forknum, from, n_blocks); } return lsn; } @@ -6680,7 +6680,7 @@ SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, { if (set_lwlsn_block_v_hook) { - set_lwlsn_block_v_hook(lsns, relfilenode, forknum, blockno, nblocks); + return set_lwlsn_block_v_hook(lsns, relfilenode, forknum, blockno, nblocks); } // Behaviour in case the hook is not set. Taken from the implemenatation of SetLastWrittenLSNForBlockv in neon_lwlc.c if (lsns == NULL || nblocks == 0) { @@ -6702,7 +6702,7 @@ SetLastWrittenLSNForBlock(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber fo { if (set_lwlsn_block_hook) { - set_lwlsn_block_hook(lsn, rlocator, forknum, blkno); + return set_lwlsn_block_hook(lsn, rlocator, forknum, blkno); } return lsn; } @@ -6715,7 +6715,7 @@ SetLastWrittenLSNForRelation(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber { if (set_lwlsn_relation_hook) { - set_lwlsn_relation_hook(lsn, rlocator, forknum); + return set_lwlsn_relation_hook(lsn, rlocator, forknum); } return lsn; } @@ -6728,7 +6728,7 @@ SetLastWrittenLSNForDatabase(XLogRecPtr lsn) { if (set_lwlsn_db_hook) { - set_lwlsn_db_hook(lsn); + return et_lwlsn_db_hook(lsn); } return lsn; } From 8f5faea84c244d675d5b6c5cbb5c1cd2fff69b67 Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Wed, 5 Mar 2025 10:14:11 -0500 Subject: [PATCH 09/19] i# This is a combination of 2 commits. added missing return statements --- src/backend/access/transam/xlog.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 43c9919b725..4d23c379c89 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6659,7 +6659,7 @@ SetLastWrittenLSNForBlockRange(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumb { if (set_lwlsn_block_range_hook) { - set_lwlsn_block_range_hook(lsn, rlocator, forknum, from, n_blocks); + return set_lwlsn_block_range_hook(lsn, rlocator, forknum, from, n_blocks); } return lsn; } @@ -6680,7 +6680,7 @@ SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, { if (set_lwlsn_block_v_hook) { - set_lwlsn_block_v_hook(lsns, relfilenode, forknum, blockno, nblocks); + return set_lwlsn_block_v_hook(lsns, relfilenode, forknum, blockno, nblocks); } // Behaviour in case the hook is not set. Taken from the implemenatation of SetLastWrittenLSNForBlockv in neon_lwlc.c if (lsns == NULL || nblocks == 0) { @@ -6702,7 +6702,7 @@ SetLastWrittenLSNForBlock(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber fo { if (set_lwlsn_block_hook) { - set_lwlsn_block_hook(lsn, rlocator, forknum, blkno); + return set_lwlsn_block_hook(lsn, rlocator, forknum, blkno); } return lsn; } @@ -6715,7 +6715,7 @@ SetLastWrittenLSNForRelation(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber { if (set_lwlsn_relation_hook) { - set_lwlsn_relation_hook(lsn, rlocator, forknum); + return set_lwlsn_relation_hook(lsn, rlocator, forknum); } return lsn; } @@ -6728,7 +6728,7 @@ SetLastWrittenLSNForDatabase(XLogRecPtr lsn) { if (set_lwlsn_db_hook) { - set_lwlsn_db_hook(lsn); + return set_lwlsn_db_hook(lsn); } return lsn; } From 8de5b9ac12e8a740de9304dd00fa955e624d7cdd Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Wed, 5 Mar 2025 10:27:14 -0500 Subject: [PATCH 10/19] fixed return statement for block range --- src/backend/access/transam/xlog.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 97779221a91..4d23c379c89 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6660,7 +6660,6 @@ SetLastWrittenLSNForBlockRange(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumb if (set_lwlsn_block_range_hook) { return set_lwlsn_block_range_hook(lsn, rlocator, forknum, from, n_blocks); - return set_lwlsn_block_range_hook(lsn, rlocator, forknum, from, n_blocks); } return lsn; } From d9170273924860085eab8097dc381844f2f02fbb Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Thu, 6 Mar 2025 16:35:36 -0500 Subject: [PATCH 11/19] removed shmem hookup call to prevent duplicate memory allocations --- src/backend/access/transam/xlog.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 4d23c379c89..77c22a459aa 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -4953,10 +4953,6 @@ XLOGShmemInit(void) XLogCtl = (XLogCtlData *) ShmemInitStruct("XLOG Ctl", XLOGCtlShmemSize(), &foundXLog); - if (shmem_startup_hook) { - shmem_startup_hook(); - } - localControlFile = ControlFile; ControlFile = (ControlFileData *) ShmemInitStruct("Control File", sizeof(ControlFileData), &foundCFile); From c28913db6b94f2e73fb8fcce44a283bebb7ae5ef Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Mon, 10 Mar 2025 20:24:40 -0400 Subject: [PATCH 12/19] removed unnecessary changes in dbcommands --- src/backend/commands/dbcommands.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 05c23ff6f53..253c3c36c99 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -29,7 +29,6 @@ #include "access/multixact.h" #include "access/tableam.h" #include "access/xact.h" -#include "access/xlog.h" #include "access/xloginsert.h" #include "access/xlogrecovery.h" #include "access/xlogutils.h" @@ -3388,7 +3387,7 @@ dbase_redo(XLogReaderState *record) */ { XLogRecPtr lsn = record->EndRecPtr; - set_lwlsn_db_hook(lsn); + SetLastWrittenLSNForDatabase(lsn); } pfree(dbpath); From cf73c345ff452b5f2deb50d198514616fddbd8ba Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Wed, 12 Mar 2025 11:39:14 -0400 Subject: [PATCH 13/19] added hook to update maxlastwrittenlsn --- src/backend/access/transam/xlog.c | 6 ++++++ src/include/access/xlog.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 77c22a459aa..b80df3f51bd 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -5514,6 +5514,8 @@ readZenithSignalFile(void) } } +update_max_lwlsn_hook_type update_max_lwlsn_hook = NULL; + /* * This must be called ONCE during postmaster or standalone-backend startup */ @@ -5786,6 +5788,10 @@ StartupXLOG(void) RedoRecPtr = XLogCtl->RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo; doPageWrites = lastFullPageWrites; + if (update_max_lwlsn_hook) { + update_max_lwlsn_hook(RedoRecPtr); + } + /* REDO */ if (InRecovery) { diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index b8e71742e5a..2c65bf7c37a 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -291,6 +291,7 @@ typedef XLogRecPtr (*set_lwlsn_block_hook_type)(XLogRecPtr lsn, RelFileLocator r typedef XLogRecPtr (*set_lwlsn_relation_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum); typedef XLogRecPtr (*set_lwlsn_db_hook_type)(XLogRecPtr lsn); typedef int (*get_lwlsn_cache_size_type) (void); +typedef void (*update_max_lwlsn_hook_type) (XLogRecPtr lsn); extern get_lwlsn_hook_type get_lwlsn_hook; extern get_lwlsn_v_hook_type get_lwlsn_v_hook; @@ -300,6 +301,7 @@ extern set_lwlsn_block_hook_type set_lwlsn_block_hook; extern set_lwlsn_relation_hook_type set_lwlsn_relation_hook; extern set_lwlsn_db_hook_type set_lwlsn_db_hook; extern get_lwlsn_cache_size_type get_lwlsn_cache_size; +extern update_max_lwlsn_hook_type update_max_lwlsn_hook; /* * Routines used by xlogrecovery.c to call back into xlog.c during recovery. From faff7e3b457265c672fd04cb71d364f5ec36ea74 Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Wed, 12 Mar 2025 13:26:04 -0400 Subject: [PATCH 14/19] removed unnecesary hooks --- src/backend/access/transam/xlog.c | 18 +++--------------- src/include/access/xlog.h | 10 ---------- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index b80df3f51bd..a3e0d097776 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6637,14 +6637,9 @@ GetInsertRecPtr(void) return recptr; } -get_lwlsn_hook_type get_lwlsn_hook = NULL; -get_lwlsn_v_hook_type get_lwlsn_v_hook = NULL; set_lwlsn_block_range_hook_type set_lwlsn_block_range_hook = NULL; set_lwlsn_block_v_hook_type set_lwlsn_block_v_hook = NULL; set_lwlsn_block_hook_type set_lwlsn_block_hook = NULL; -set_lwlsn_relation_hook_type set_lwlsn_relation_hook = NULL; -set_lwlsn_db_hook_type set_lwlsn_db_hook = NULL; -get_lwlsn_cache_size_type get_lwlsn_cache_size = NULL; /* * SetLastWrittenLSNForBlockRange -- Set maximal LSN of written page range. @@ -6715,11 +6710,7 @@ SetLastWrittenLSNForBlock(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber fo XLogRecPtr SetLastWrittenLSNForRelation(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber forknum) { - if (set_lwlsn_relation_hook) - { - return set_lwlsn_relation_hook(lsn, rlocator, forknum); - } - return lsn; + return SetLastWrittenLSNForBlock(lsn, rlocator, forknum, REL_METADATA_PSEUDO_BLOCKNO); } /* @@ -6728,11 +6719,8 @@ SetLastWrittenLSNForRelation(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber XLogRecPtr SetLastWrittenLSNForDatabase(XLogRecPtr lsn) { - if (set_lwlsn_db_hook) - { - return set_lwlsn_db_hook(lsn); - } - return lsn; + RelFileLocator dummyNode = {InvalidOid, InvalidOid, InvalidOid}; + return SetLastWrittenLSNForBlock(lsn, dummyNode, MAIN_FORKNUM, 0); } void diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 2c65bf7c37a..2791076c811 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -283,24 +283,14 @@ extern Size WALReadFromBuffers(char *dstbuf, XLogRecPtr startptr, Size count, TimeLineID tli); /* Hooks for LwLSN */ -typedef XLogRecPtr (*get_lwlsn_hook_type)(RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); -typedef void (*get_lwlsn_v_hook_type)(RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno, int nblocks, XLogRecPtr *lsns); typedef XLogRecPtr (*set_lwlsn_block_range_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber from, BlockNumber n_blocks); typedef XLogRecPtr (*set_lwlsn_block_v_hook_type)(const XLogRecPtr *lsns, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blockno, int nblocks); typedef XLogRecPtr (*set_lwlsn_block_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); -typedef XLogRecPtr (*set_lwlsn_relation_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum); -typedef XLogRecPtr (*set_lwlsn_db_hook_type)(XLogRecPtr lsn); -typedef int (*get_lwlsn_cache_size_type) (void); typedef void (*update_max_lwlsn_hook_type) (XLogRecPtr lsn); -extern get_lwlsn_hook_type get_lwlsn_hook; -extern get_lwlsn_v_hook_type get_lwlsn_v_hook; extern set_lwlsn_block_range_hook_type set_lwlsn_block_range_hook; extern set_lwlsn_block_v_hook_type set_lwlsn_block_v_hook; extern set_lwlsn_block_hook_type set_lwlsn_block_hook; -extern set_lwlsn_relation_hook_type set_lwlsn_relation_hook; -extern set_lwlsn_db_hook_type set_lwlsn_db_hook; -extern get_lwlsn_cache_size_type get_lwlsn_cache_size; extern update_max_lwlsn_hook_type update_max_lwlsn_hook; /* From de9e6e84e12181b4ed8559c5cd80807110983198 Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Thu, 13 Mar 2025 10:20:28 -0400 Subject: [PATCH 15/19] addressed comments, resolved style issues --- src/backend/access/transam/xlog.c | 44 +++++++++++-------------------- src/backend/storage/ipc/ipci.c | 2 +- src/include/access/xlog.h | 2 +- 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index a3e0d097776..35b52054923 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -147,6 +147,13 @@ int wal_segment_size = DEFAULT_XLOG_SEG_SIZE; /* NEON: Hook to allow the neon extension to restore running-xacts from CLOG at replica startup */ restore_running_xacts_callback_t restore_running_xacts_callback; + +/* NEON: Hook Definitions that enabled the moving of LastWrittenLSN Cache to the neon extension*/ +update_max_lwlsn_hook_type update_max_lwlsn_hook = NULL; +set_lwlsn_block_range_hook_type set_lwlsn_block_range_hook = NULL; +set_lwlsn_block_v_hook_type set_lwlsn_block_v_hook = NULL; +set_lwlsn_block_hook_type set_lwlsn_block_hook = NULL; + /* * Number of WAL insertion locks to use. A higher value allows more insertions * to happen concurrently, but adds some CPU overhead to flushing the WAL, @@ -4864,7 +4871,7 @@ GetActiveWalLevelOnStandby(void) return ControlFile->wal_level; } -static Size +Size XLOGCtlShmemSize(void) { Size size; @@ -4914,16 +4921,6 @@ XLOGCtlShmemSize(void) return size; } -/* - * Initialization of shared memory for XLOG - */ -Size -XLOGShmemSize(void) -{ - // Removed LwLSN Size as it is no longer in XLog - return XLOGCtlShmemSize(); -} - void XLOGShmemInit(void) { @@ -5514,8 +5511,6 @@ readZenithSignalFile(void) } } -update_max_lwlsn_hook_type update_max_lwlsn_hook = NULL; - /* * This must be called ONCE during postmaster or standalone-backend startup */ @@ -5788,9 +5783,8 @@ StartupXLOG(void) RedoRecPtr = XLogCtl->RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo; doPageWrites = lastFullPageWrites; - if (update_max_lwlsn_hook) { + if (update_max_lwlsn_hook) update_max_lwlsn_hook(RedoRecPtr); - } /* REDO */ if (InRecovery) @@ -6637,10 +6631,6 @@ GetInsertRecPtr(void) return recptr; } -set_lwlsn_block_range_hook_type set_lwlsn_block_range_hook = NULL; -set_lwlsn_block_v_hook_type set_lwlsn_block_v_hook = NULL; -set_lwlsn_block_hook_type set_lwlsn_block_hook = NULL; - /* * SetLastWrittenLSNForBlockRange -- Set maximal LSN of written page range. * We maintain cache of last written LSNs with limited size and LRU replacement @@ -6655,9 +6645,8 @@ XLogRecPtr SetLastWrittenLSNForBlockRange(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber forknum, BlockNumber from, BlockNumber n_blocks) { if (set_lwlsn_block_range_hook) - { return set_lwlsn_block_range_hook(lsn, rlocator, forknum, from, n_blocks); - } + return lsn; } @@ -6676,17 +6665,17 @@ SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, int nblocks) { if (set_lwlsn_block_v_hook) - { return set_lwlsn_block_v_hook(lsns, relfilenode, forknum, blockno, nblocks); - } + // Behaviour in case the hook is not set. Taken from the implemenatation of SetLastWrittenLSNForBlockv in neon_lwlc.c - if (lsns == NULL || nblocks == 0) { + if (lsns == NULL || nblocks == 0) + { return InvalidXLogRecPtr; } else { XLogRecPtr max = InvalidXLogRecPtr; - for (int i = 0; i < nblocks; i ++) { + for (int i = 0; i < nblocks; i ++) max = Max(max, lsns[i]); - } + return max; } } @@ -6698,9 +6687,8 @@ XLogRecPtr SetLastWrittenLSNForBlock(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber forknum, BlockNumber blkno) { if (set_lwlsn_block_hook) - { return set_lwlsn_block_hook(lsn, rlocator, forknum, blkno); - } + return lsn; } diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 2100150f01c..3dd65e5b500 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -122,7 +122,7 @@ CalculateShmemSize(int *num_semaphores) size = add_size(size, ProcGlobalShmemSize()); size = add_size(size, XLogPrefetchShmemSize()); size = add_size(size, VarsupShmemSize()); - size = add_size(size, XLOGShmemSize()); + size = add_size(size, XLOGCtlShmemSize()); size = add_size(size, XLogRecoveryShmemSize()); size = add_size(size, CLOGShmemSize()); size = add_size(size, CommitTsShmemSize()); diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 2791076c811..949b70d6f31 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -242,7 +242,7 @@ extern uint64 GetSystemIdentifier(void); extern char *GetMockAuthenticationNonce(void); extern bool DataChecksumsEnabled(void); extern XLogRecPtr GetFakeLSNForUnloggedRel(void); -extern Size XLOGShmemSize(void); +extern Size XLOGCtlShmemSize(void); extern void XLOGShmemInit(void); extern void BootStrapXLOG(void); extern void InitializeWalConsistencyChecking(void); From 53fa165b7b83f24db11e711de7ebd594f50e8c82 Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Thu, 13 Mar 2025 12:11:17 -0400 Subject: [PATCH 16/19] updated styling --- src/backend/access/transam/xlog.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 35b52054923..80aca16c30c 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6667,11 +6667,13 @@ SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, if (set_lwlsn_block_v_hook) return set_lwlsn_block_v_hook(lsns, relfilenode, forknum, blockno, nblocks); - // Behaviour in case the hook is not set. Taken from the implemenatation of SetLastWrittenLSNForBlockv in neon_lwlc.c + // Behaviour in case the hook is not set if (lsns == NULL || nblocks == 0) { return InvalidXLogRecPtr; - } else { + } + else + { XLogRecPtr max = InvalidXLogRecPtr; for (int i = 0; i < nblocks; i ++) max = Max(max, lsns[i]); From fecca787abe5213d8195fcaf69c93430e6caba4e Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Thu, 13 Mar 2025 12:32:43 -0400 Subject: [PATCH 17/19] resolved comments, updated description for set_lwlsn_block_v --- src/backend/access/transam/xlog.c | 14 ++++++++++---- src/backend/storage/ipc/ipci.c | 2 +- src/include/access/xlog.h | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 80aca16c30c..87dc0ae1bbb 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -148,7 +148,7 @@ int wal_segment_size = DEFAULT_XLOG_SEG_SIZE; /* NEON: Hook to allow the neon extension to restore running-xacts from CLOG at replica startup */ restore_running_xacts_callback_t restore_running_xacts_callback; -/* NEON: Hook Definitions that enabled the moving of LastWrittenLSN Cache to the neon extension*/ +/* NEON: Hooks to facilitate the last written LSN cache */ update_max_lwlsn_hook_type update_max_lwlsn_hook = NULL; set_lwlsn_block_range_hook_type set_lwlsn_block_range_hook = NULL; set_lwlsn_block_v_hook_type set_lwlsn_block_v_hook = NULL; @@ -4872,7 +4872,7 @@ GetActiveWalLevelOnStandby(void) } Size -XLOGCtlShmemSize(void) +XLOGShmemSize(void) { Size size; @@ -4948,7 +4948,7 @@ XLOGShmemInit(void) XLogCtl = (XLogCtlData *) - ShmemInitStruct("XLOG Ctl", XLOGCtlShmemSize(), &foundXLog); + ShmemInitStruct("XLOG Ctl", XLOGShmemSize(), &foundXLog); localControlFile = ControlFile; ControlFile = (ControlFileData *) @@ -6667,13 +6667,19 @@ SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, if (set_lwlsn_block_v_hook) return set_lwlsn_block_v_hook(lsns, relfilenode, forknum, blockno, nblocks); - // Behaviour in case the hook is not set + // Behavior in case the hook is not set if (lsns == NULL || nblocks == 0) { + // If no valid LSNs were provided, fallback to the InvalidXLogRecPtr return InvalidXLogRecPtr; } else { + // In the case when the hook is present, we would return the + // maximal LSN of all the given LSNs, taking care to update the + // given LSN when it's value is lesser than the one found in the + // corresponding entry. As the hook is not present, we just return + // the maximal lsn without performing a search in the hash table XLogRecPtr max = InvalidXLogRecPtr; for (int i = 0; i < nblocks; i ++) max = Max(max, lsns[i]); diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 3dd65e5b500..2100150f01c 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -122,7 +122,7 @@ CalculateShmemSize(int *num_semaphores) size = add_size(size, ProcGlobalShmemSize()); size = add_size(size, XLogPrefetchShmemSize()); size = add_size(size, VarsupShmemSize()); - size = add_size(size, XLOGCtlShmemSize()); + size = add_size(size, XLOGShmemSize()); size = add_size(size, XLogRecoveryShmemSize()); size = add_size(size, CLOGShmemSize()); size = add_size(size, CommitTsShmemSize()); diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 949b70d6f31..2791076c811 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -242,7 +242,7 @@ extern uint64 GetSystemIdentifier(void); extern char *GetMockAuthenticationNonce(void); extern bool DataChecksumsEnabled(void); extern XLogRecPtr GetFakeLSNForUnloggedRel(void); -extern Size XLOGCtlShmemSize(void); +extern Size XLOGShmemSize(void); extern void XLOGShmemInit(void); extern void BootStrapXLOG(void); extern void InitializeWalConsistencyChecking(void); From affd399bf3ffce5d5bbca184880d0dee515f5b20 Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Fri, 14 Mar 2025 17:10:07 -0400 Subject: [PATCH 18/19] converted all function calls to hook calls --- src/backend/access/gin/gininsert.c | 6 +- src/backend/access/gist/gistbuild.c | 14 +++-- src/backend/access/spgist/spginsert.c | 8 ++- src/backend/access/transam/xlog.c | 90 +-------------------------- src/backend/catalog/storage.c | 3 +- src/backend/commands/dbcommands.c | 12 ++-- src/include/access/xlog.h | 12 ++-- 7 files changed, 34 insertions(+), 111 deletions(-) diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index bc82e2df9e8..64e2562630c 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -418,8 +418,10 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo) log_newpage_range(index, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index), true); - SetLastWrittenLSNForBlockRange(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); - SetLastWrittenLSNForRelation(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); + if (set_lwlsn_block_range_hook) + set_lwlsn_block_range_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); + if (set_lwlsn_relation_hook) + set_lwlsn_relation_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); } smgr_end_unlogged_build(index->rd_smgr); diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c index 91ebf84fe2d..4d1d7e19b1f 100644 --- a/src/backend/access/gist/gistbuild.c +++ b/src/backend/access/gist/gistbuild.c @@ -340,10 +340,12 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) log_newpage_range(index, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index), true); - SetLastWrittenLSNForBlockRange(XactLastRecEnd, + if (set_lwlsn_block_range_hook) + set_lwlsn_block_range_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); - SetLastWrittenLSNForRelation(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); + if (set_lwlsn_relation_hook) + set_lwlsn_relation_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); } smgr_end_unlogged_build(index->rd_smgr); @@ -464,9 +466,11 @@ gist_indexsortbuild(GISTBuildState *state) { XLogRecPtr lsn = GetRedoRecPtr(); - SetLastWrittenLSNForBlock(lsn, state->indexrel->rd_smgr->smgr_rlocator.locator, - MAIN_FORKNUM, GIST_ROOT_BLKNO); - SetLastWrittenLSNForRelation(lsn, state->indexrel->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); + if (set_lwlsn_block_hook) + set_lwlsn_block_hook(lsn, state->indexrel->rd_smgr->smgr_rlocator.locator, + MAIN_FORKNUM, GIST_ROOT_BLKNO); + if (set_lwlsn_relation_hook) + set_lwlsn_relation_hook(lsn, state->indexrel->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); } pfree(levelstate); diff --git a/src/backend/access/spgist/spginsert.c b/src/backend/access/spgist/spginsert.c index f3652531867..814f34a3241 100644 --- a/src/backend/access/spgist/spginsert.c +++ b/src/backend/access/spgist/spginsert.c @@ -142,9 +142,11 @@ spgbuild(Relation heap, Relation index, IndexInfo *indexInfo) log_newpage_range(index, MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index), true); - SetLastWrittenLSNForBlockRange(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, - MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); - SetLastWrittenLSNForRelation(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); + if (set_lwlsn_block_range_hook) + set_lwlsn_block_range_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, + MAIN_FORKNUM, 0, RelationGetNumberOfBlocks(index)); + if (set_lwlsn_relation_hook) + set_lwlsn_relation_hook(XactLastRecEnd, index->rd_smgr->smgr_rlocator.locator, MAIN_FORKNUM); } smgr_end_unlogged_build(index->rd_smgr); diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 87dc0ae1bbb..66410be987d 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -153,6 +153,8 @@ update_max_lwlsn_hook_type update_max_lwlsn_hook = NULL; set_lwlsn_block_range_hook_type set_lwlsn_block_range_hook = NULL; set_lwlsn_block_v_hook_type set_lwlsn_block_v_hook = NULL; set_lwlsn_block_hook_type set_lwlsn_block_hook = NULL; +set_lwlsn_relation_hook_type set_lwlsn_relation_hook = NULL; +set_lwlsn_db_hook_type set_lwlsn_db_hook = NULL; /* * Number of WAL insertion locks to use. A higher value allows more insertions @@ -6631,94 +6633,6 @@ GetInsertRecPtr(void) return recptr; } -/* - * SetLastWrittenLSNForBlockRange -- Set maximal LSN of written page range. - * We maintain cache of last written LSNs with limited size and LRU replacement - * policy. Keeping last written LSN for each page allows to use old LSN when - * requesting pages of unchanged or appended relations. Also it is critical for - * efficient work of prefetch in case massive update operations (like vacuum or remove). - * - * rlocator.relNumber can be InvalidOid, in this case maxLastWrittenLsn is updated. - * SetLastWrittenLsn with dummy rlocator is used by createdb and dbase_redo functions. - */ -XLogRecPtr -SetLastWrittenLSNForBlockRange(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber forknum, BlockNumber from, BlockNumber n_blocks) -{ - if (set_lwlsn_block_range_hook) - return set_lwlsn_block_range_hook(lsn, rlocator, forknum, from, n_blocks); - - return lsn; -} - -/* - * SetLastWrittenLSNForBlockv -- Set maximal LSN of pages to their respective - * LSNs. - * - * We maintain cache of last written LSNs with limited size and LRU replacement - * policy. Keeping last written LSN for each page allows to use old LSN when - * requesting pages of unchanged or appended relations. Also it is critical for - * efficient work of prefetch in case massive update operations (like vacuum or remove). - */ -XLogRecPtr -SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, - ForkNumber forknum, BlockNumber blockno, - int nblocks) -{ - if (set_lwlsn_block_v_hook) - return set_lwlsn_block_v_hook(lsns, relfilenode, forknum, blockno, nblocks); - - // Behavior in case the hook is not set - if (lsns == NULL || nblocks == 0) - { - // If no valid LSNs were provided, fallback to the InvalidXLogRecPtr - return InvalidXLogRecPtr; - } - else - { - // In the case when the hook is present, we would return the - // maximal LSN of all the given LSNs, taking care to update the - // given LSN when it's value is lesser than the one found in the - // corresponding entry. As the hook is not present, we just return - // the maximal lsn without performing a search in the hash table - XLogRecPtr max = InvalidXLogRecPtr; - for (int i = 0; i < nblocks; i ++) - max = Max(max, lsns[i]); - - return max; - } -} - -/* - * SetLastWrittenLSNForBlock -- Set maximal LSN for block - */ -XLogRecPtr -SetLastWrittenLSNForBlock(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber forknum, BlockNumber blkno) -{ - if (set_lwlsn_block_hook) - return set_lwlsn_block_hook(lsn, rlocator, forknum, blkno); - - return lsn; -} - -/* - * SetLastWrittenLSNForRelation -- Set maximal LSN for relation metadata - */ -XLogRecPtr -SetLastWrittenLSNForRelation(XLogRecPtr lsn, RelFileLocator rlocator, ForkNumber forknum) -{ - return SetLastWrittenLSNForBlock(lsn, rlocator, forknum, REL_METADATA_PSEUDO_BLOCKNO); -} - -/* - * SetLastWrittenLSNForDatabase -- Set maximal LSN for the whole database - */ -XLogRecPtr -SetLastWrittenLSNForDatabase(XLogRecPtr lsn) -{ - RelFileLocator dummyNode = {InvalidOid, InvalidOid, InvalidOid}; - return SetLastWrittenLSNForBlock(lsn, dummyNode, MAIN_FORKNUM, 0); -} - void SetRedoStartLsn(XLogRecPtr RedoStartLSN) { diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c index a97e7dc25d3..e0dc76209ce 100644 --- a/src/backend/catalog/storage.c +++ b/src/backend/catalog/storage.c @@ -197,7 +197,8 @@ log_smgrcreate(const RelFileLocator *rlocator, ForkNumber forkNum) XLogBeginInsert(); XLogRegisterData((char *) &xlrec, sizeof(xlrec)); lsn = XLogInsert(RM_SMGR_ID, XLOG_SMGR_CREATE | XLR_SPECIAL_REL_UPDATE); - SetLastWrittenLSNForRelation(lsn, *rlocator, forkNum); + if (set_lwlsn_relation_hook) + set_lwlsn_relation_hook(lsn, *rlocator, forkNum); } /* diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 253c3c36c99..a8b2a116b3a 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -1515,7 +1515,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) /* * Update global last written LSN after wal-logging create database command */ - SetLastWrittenLSNForDatabase(XactLastRecEnd); + if (set_lwlsn_db_hook) + set_lwlsn_db_hook(XactLastRecEnd); /* * Close pg_database, but keep lock till commit. @@ -2182,7 +2183,8 @@ movedb(const char *dbname, const char *tblspcname) lsn = XLogInsert(RM_DBASE_ID, XLOG_DBASE_CREATE_FILE_COPY | XLR_SPECIAL_REL_UPDATE); // TODO: Do we really need to set the LSN here? - SetLastWrittenLSNForDatabase(lsn); + if (set_lwlsn_db_hook) + set_lwlsn_db_hook(lsn); } /* @@ -3357,7 +3359,8 @@ dbase_redo(XLogReaderState *record) */ { XLogRecPtr lsn = record->EndRecPtr; - SetLastWrittenLSNForDatabase(lsn); + if (set_lwlsn_db_hook) + set_lwlsn_db_hook(lsn); } pfree(src_path); @@ -3387,7 +3390,8 @@ dbase_redo(XLogReaderState *record) */ { XLogRecPtr lsn = record->EndRecPtr; - SetLastWrittenLSNForDatabase(lsn); + if (set_lwlsn_db_hook) + set_lwlsn_db_hook(lsn); } pfree(dbpath); diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 2791076c811..0546ea5866a 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -266,14 +266,6 @@ extern XLogRecPtr GetLastImportantRecPtr(void); /* neon specifics */ -extern XLogRecPtr SetLastWrittenLSNForBlock(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); -extern XLogRecPtr SetLastWrittenLSNForBlockv(const XLogRecPtr *lsns, RelFileLocator relfilenode, - ForkNumber forknum, BlockNumber blockno, - int nblocks); -extern XLogRecPtr SetLastWrittenLSNForBlockRange(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber from, BlockNumber n_blocks); -extern XLogRecPtr SetLastWrittenLSNForDatabase(XLogRecPtr lsn); -extern XLogRecPtr SetLastWrittenLSNForRelation(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum); - extern void SetRedoStartLsn(XLogRecPtr RedoStartLSN); extern XLogRecPtr GetRedoStartLsn(void); @@ -286,12 +278,16 @@ extern Size WALReadFromBuffers(char *dstbuf, XLogRecPtr startptr, Size count, typedef XLogRecPtr (*set_lwlsn_block_range_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber from, BlockNumber n_blocks); typedef XLogRecPtr (*set_lwlsn_block_v_hook_type)(const XLogRecPtr *lsns, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blockno, int nblocks); typedef XLogRecPtr (*set_lwlsn_block_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); +typedef XLogRecPtr (*set_lwlsn_relation_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum); +typedef XLogRecPtr (*set_lwlsn_db_hook_type)(XLogRecPtr lsn); typedef void (*update_max_lwlsn_hook_type) (XLogRecPtr lsn); extern set_lwlsn_block_range_hook_type set_lwlsn_block_range_hook; extern set_lwlsn_block_v_hook_type set_lwlsn_block_v_hook; extern set_lwlsn_block_hook_type set_lwlsn_block_hook; extern update_max_lwlsn_hook_type update_max_lwlsn_hook; +extern set_lwlsn_relation_hook_type set_lwlsn_relation_hook; +extern set_lwlsn_db_hook_type set_lwlsn_db_hook; /* * Routines used by xlogrecovery.c to call back into xlog.c during recovery. From f8d62e5450fd0bb3001f940de3450be3ff3d5d13 Mon Sep 17 00:00:00 2001 From: Suhas Thalanki Date: Mon, 17 Mar 2025 16:33:11 -0400 Subject: [PATCH 19/19] addressed comments --- src/backend/access/transam/xlog.c | 12 ++++++------ src/backend/commands/dbcommands.c | 15 +++++---------- src/include/access/xlog.h | 12 ++++++------ 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 66410be987d..86287161a21 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -149,12 +149,12 @@ int wal_segment_size = DEFAULT_XLOG_SEG_SIZE; restore_running_xacts_callback_t restore_running_xacts_callback; /* NEON: Hooks to facilitate the last written LSN cache */ -update_max_lwlsn_hook_type update_max_lwlsn_hook = NULL; +set_lwlsn_block_hook_type set_lwlsn_block_hook = NULL; set_lwlsn_block_range_hook_type set_lwlsn_block_range_hook = NULL; set_lwlsn_block_v_hook_type set_lwlsn_block_v_hook = NULL; -set_lwlsn_block_hook_type set_lwlsn_block_hook = NULL; -set_lwlsn_relation_hook_type set_lwlsn_relation_hook = NULL; set_lwlsn_db_hook_type set_lwlsn_db_hook = NULL; +set_lwlsn_relation_hook_type set_lwlsn_relation_hook = NULL; +set_max_lwlsn_hook_type set_max_lwlsn_hook = NULL; /* * Number of WAL insertion locks to use. A higher value allows more insertions @@ -4950,7 +4950,7 @@ XLOGShmemInit(void) XLogCtl = (XLogCtlData *) - ShmemInitStruct("XLOG Ctl", XLOGShmemSize(), &foundXLog); + ShmemInitStruct("XLOG Ctl", XLOGShmemSize(), &foundXLog); localControlFile = ControlFile; ControlFile = (ControlFileData *) @@ -5785,8 +5785,8 @@ StartupXLOG(void) RedoRecPtr = XLogCtl->RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo; doPageWrites = lastFullPageWrites; - if (update_max_lwlsn_hook) - update_max_lwlsn_hook(RedoRecPtr); + if (set_max_lwlsn_hook) + set_max_lwlsn_hook(RedoRecPtr); /* REDO */ if (InRecovery) diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index a8b2a116b3a..a8478e61b43 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -3357,11 +3357,9 @@ dbase_redo(XLogReaderState *record) * Make sure any future requests to the page server see the new * database. */ - { - XLogRecPtr lsn = record->EndRecPtr; - if (set_lwlsn_db_hook) - set_lwlsn_db_hook(lsn); - } + if (set_lwlsn_db_hook) + set_lwlsn_db_hook(record->EndRecPtr); + pfree(src_path); pfree(dst_path); @@ -3388,11 +3386,8 @@ dbase_redo(XLogReaderState *record) * Make sure any future requests to the page server see the new * database. */ - { - XLogRecPtr lsn = record->EndRecPtr; - if (set_lwlsn_db_hook) - set_lwlsn_db_hook(lsn); - } + if (set_lwlsn_db_hook) + set_lwlsn_db_hook(record->EndRecPtr); pfree(dbpath); } diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 0546ea5866a..eb1ebf4101d 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -275,19 +275,19 @@ extern Size WALReadFromBuffers(char *dstbuf, XLogRecPtr startptr, Size count, TimeLineID tli); /* Hooks for LwLSN */ +typedef XLogRecPtr (*set_lwlsn_block_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); typedef XLogRecPtr (*set_lwlsn_block_range_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber from, BlockNumber n_blocks); typedef XLogRecPtr (*set_lwlsn_block_v_hook_type)(const XLogRecPtr *lsns, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blockno, int nblocks); -typedef XLogRecPtr (*set_lwlsn_block_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum, BlockNumber blkno); -typedef XLogRecPtr (*set_lwlsn_relation_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum); typedef XLogRecPtr (*set_lwlsn_db_hook_type)(XLogRecPtr lsn); -typedef void (*update_max_lwlsn_hook_type) (XLogRecPtr lsn); +typedef XLogRecPtr (*set_lwlsn_relation_hook_type)(XLogRecPtr lsn, RelFileLocator relfilenode, ForkNumber forknum); +typedef void (*set_max_lwlsn_hook_type) (XLogRecPtr lsn); +extern set_lwlsn_block_hook_type set_lwlsn_block_hook; extern set_lwlsn_block_range_hook_type set_lwlsn_block_range_hook; extern set_lwlsn_block_v_hook_type set_lwlsn_block_v_hook; -extern set_lwlsn_block_hook_type set_lwlsn_block_hook; -extern update_max_lwlsn_hook_type update_max_lwlsn_hook; -extern set_lwlsn_relation_hook_type set_lwlsn_relation_hook; extern set_lwlsn_db_hook_type set_lwlsn_db_hook; +extern set_lwlsn_relation_hook_type set_lwlsn_relation_hook; +extern set_max_lwlsn_hook_type set_max_lwlsn_hook; /* * Routines used by xlogrecovery.c to call back into xlog.c during recovery.