From d5fed4ae839b9cf33c43cea066727440b09526cf Mon Sep 17 00:00:00 2001 From: LiHeng Date: Tue, 30 Mar 2021 20:27:21 +0800 Subject: [PATCH] add smgr cached nblocks for main fork Avoid repeatedly calling smgrnblocks() in read query on standby. Now, we only add cached nblocks in main fork. --- src/common/backend/catalog/storage.cpp | 1 + src/gausskernel/storage/buffer/bufmgr.cpp | 11 +++++-- src/gausskernel/storage/smgr/smgr.cpp | 35 ++++++++++++++++++++++- src/include/storage/smgr.h | 2 ++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/common/backend/catalog/storage.cpp b/src/common/backend/catalog/storage.cpp index 8e35672a4..86a3099fd 100644 --- a/src/common/backend/catalog/storage.cpp +++ b/src/common/backend/catalog/storage.cpp @@ -687,6 +687,7 @@ void RelationTruncate(Relation rel, BlockNumber nblocks) rel->rd_smgr->smgr_targblock = InvalidBlockNumber; rel->rd_smgr->smgr_fsm_nblocks = InvalidBlockNumber; rel->rd_smgr->smgr_vm_nblocks = InvalidBlockNumber; + rel->rd_smgr->smgr_cached_nblocks = InvalidBlockNumber; for (int i = 0; i < rel->rd_smgr->smgr_bcmarry_size; i++) rel->rd_smgr->smgr_bcm_nblocks[i] = InvalidBlockNumber; diff --git a/src/gausskernel/storage/buffer/bufmgr.cpp b/src/gausskernel/storage/buffer/bufmgr.cpp index 1d8b11b26..114abf2c4 100644 --- a/src/gausskernel/storage/buffer/bufmgr.cpp +++ b/src/gausskernel/storage/buffer/bufmgr.cpp @@ -2029,9 +2029,16 @@ static Buffer ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumb */ #ifndef ENABLE_MULTIPLE_NODES } else if (RecoveryInProgress()) { - if (blockNum >= smgrnblocks(smgr, forkNum)) - return InvalidBuffer; + BlockNumber totalBlkNum = smgrnblocks_cached(smgr, forkNum); + /* Update cached blocks */ + if (totalBlkNum == InvalidBlockNumber || blockNum >= totalBlkNum) { + totalBlkNum = smgrnblocks(smgr, forkNum); + } + + if (blockNum >= totalBlkNum) { + return InvalidBuffer; + } #endif } diff --git a/src/gausskernel/storage/smgr/smgr.cpp b/src/gausskernel/storage/smgr/smgr.cpp index cf540fa86..996e2ad5b 100644 --- a/src/gausskernel/storage/smgr/smgr.cpp +++ b/src/gausskernel/storage/smgr/smgr.cpp @@ -150,6 +150,7 @@ static void _smgr_init(SMgrRelation reln, int col = 0) reln->smgr_targblock = InvalidBlockNumber; reln->smgr_fsm_nblocks = InvalidBlockNumber; reln->smgr_vm_nblocks = InvalidBlockNumber; + reln->smgr_cached_nblocks = InvalidBlockNumber; reln->smgr_which = 0; /* we only have md.c at present */ @@ -809,7 +810,36 @@ void smgrwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, */ BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum) { - return (*(smgrsw[reln->smgr_which].smgr_nblocks))(reln, forknum); + BlockNumber result = InvalidBlockNumber; + + result = (*(smgrsw[reln->smgr_which].smgr_nblocks))(reln, forknum); + if (forknum == MAIN_FORKNUM) { + reln->smgr_cached_nblocks = result; + } + + return result; +} + +/* + * smgrnblocks_cached() -- Get the cached number of blocks in the supplied + * relation. + * + * Returns an InvalidBlockNumber when not in recovery and when the relation + * fork size is not cached. Now, we only support cache main fork. + */ +BlockNumber +smgrnblocks_cached(SMgrRelation reln, ForkNumber forknum) +{ + /* + * For now, we only use cached values in recovery due to lack of a shared + * invalidation mechanism for changes in file size. + */ + if (RecoveryInProgress() && forknum == MAIN_FORKNUM && + reln->smgr_cached_nblocks != InvalidBlockNumber) { + return reln->smgr_cached_nblocks; + } + + return InvalidBlockNumber; } void smgrtruncatefunc(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks) @@ -839,6 +869,9 @@ void smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks) if (forknum == BCM_FORKNUM) BCMArrayDropAllBlocks(reln->smgr_rnode.node); + /* Make the cached size is invalid if we encounter an error. */ + reln->smgr_cached_nblocks = InvalidBlockNumber; + /* * Send a shared-inval message to force other backends to close any smgr * references they may have for this rel. This is useful because they diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index dd007558f..2cd8e5353 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.h @@ -60,6 +60,7 @@ typedef struct SMgrRelationData { BlockNumber smgr_targblock; /* current insertion target block */ BlockNumber smgr_fsm_nblocks; /* last known size of fsm fork */ BlockNumber smgr_vm_nblocks; /* last known size of vm fork */ + BlockNumber smgr_cached_nblocks; /* last known size of main fork*/ int smgr_bcmarry_size; BlockNumber* smgr_bcm_nblocks; /* last known size of bcm fork */ @@ -106,6 +107,7 @@ extern bool smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum extern void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const char* buffer, bool skipFsync); extern void smgrwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber nblocks); extern BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum); +extern BlockNumber smgrnblocks_cached(SMgrRelation reln, ForkNumber forknum); extern void smgrtruncatefunc(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks); extern void smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks); extern void smgrimmedsync(SMgrRelation reln, ForkNumber forknum);