diff --git a/src/gausskernel/storage/buffer/bufmgr.cpp b/src/gausskernel/storage/buffer/bufmgr.cpp index 22ed1ee61..b79a06da3 100644 --- a/src/gausskernel/storage/buffer/bufmgr.cpp +++ b/src/gausskernel/storage/buffer/bufmgr.cpp @@ -115,8 +115,9 @@ static inline int32 GetPrivateRefCount(Buffer buffer); static void ForgetPrivateRefCountEntry(PrivateRefCountEntry* ref); static void CheckForBufferLeaks(void); static int ts_ckpt_progress_comparator(Datum a, Datum b, void* arg); -static bool ReadBuffer_common_ReadBlock(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, - BlockNumber blockNum, ReadBufferMode mode, bool isExtend, Block bufBlock); +static bool ReadBuffer_common_ReadBlock(SMgrRelation smgr, char relpersistence, + ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, bool isExtend, + Block bufBlock, bool *blockExist); /* @@ -1839,8 +1840,12 @@ Buffer ReadBuffer_common_for_localbuf(RelFileNode rnode, char relpersistence, Fo bufBlock = LocalBufHdrGetBlock(bufHdr); // ReadBuffer_common_ReadBlock(); - - (void)ReadBuffer_common_ReadBlock(smgr, relpersistence, forkNum, blockNum, mode, isExtend, bufBlock); + bool block_exist = true; + (void)ReadBuffer_common_ReadBlock(smgr, relpersistence, forkNum, blockNum, mode, + isExtend, bufBlock, &block_exist); + if (!block_exist) { + return InvalidBuffer; + } uint32 buf_state = pg_atomic_read_u32(&bufHdr->state); buf_state |= BM_VALID; @@ -1872,7 +1877,12 @@ Buffer ReadBuffer_common_for_direct( XLogRedoBufferGetBlkFunc(bufferslot, &bufBlock); Assert(bufBlock != NULL); - (void)ReadBuffer_common_ReadBlock(smgr, relpersistence, forkNum, blockNum, mode, isExtend, bufBlock); + bool block_exist = true; + (void)ReadBuffer_common_ReadBlock(smgr, relpersistence, forkNum, blockNum, mode, + isExtend, bufBlock, &block_exist); + if (!block_exist) { + return InvalidBuffer; + } XLogRedoBufferSetStateFunc(bufferslot, BM_VALID); return RedoBufferSlotGetBuffer(bufferslot); } @@ -1883,7 +1893,7 @@ Buffer ReadBuffer_common_for_direct( * * 2020-03-05 */ static bool ReadBuffer_common_ReadBlock(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, - BlockNumber blockNum, ReadBufferMode mode, bool isExtend, Block bufBlock) + BlockNumber blockNum, ReadBufferMode mode, bool isExtend, Block bufBlock, bool *blockExist) { bool needputtodirty = false; @@ -1928,7 +1938,7 @@ static bool ReadBuffer_common_ReadBlock(SMgrRelation smgr, char relpersistence, INSTR_TIME_SET_CURRENT(io_start); - smgrread(smgr, forkNum, blockNum, (char*)bufBlock); + *blockExist = smgrread(smgr, forkNum, blockNum, (char*)bufBlock); if (u_sess->attr.attr_common.track_io_timing) { INSTR_TIME_SET_CURRENT(io_time); @@ -1942,6 +1952,13 @@ static bool ReadBuffer_common_ReadBlock(SMgrRelation smgr, char relpersistence, pgstatCountBlocksReadTime4SessionLevel(INSTR_TIME_GET_MICROSEC(io_time)); } +#ifndef ENABLE_MULTIPLE_NODES + /* Block not exists */ + if (!(*blockExist)) { + return false; + } +#endif + /* check for garbage data */ if (!PageIsVerified((Page)bufBlock, blockNum)) { addBadBlockStat(&smgr->smgr_rnode.node, forkNum); @@ -2021,22 +2038,6 @@ static Buffer ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumb if (is_extend) block_num = smgrnblocks(smgr, fork_num); - /* When the parallel redo is enabled, there may be a scenario where - * the index is replayed before the page replayed. For single-mode, - * readable standby feature, Operators related to index scan access - * the index first, then access the table, and you will find that - * the tid or the heap(page) does not exist. Because the transaction - * was not originally committed, the tid or the heap(page) should not - * be visible. So accessing the non-existent heap tuple by the tid - * should return that the tuple does not exist without error reporting. - */ -#ifndef ENABLE_MULTIPLE_NODES - else if(RecoveryInProgress()) { - if(block_num >= smgrnblocks(smgr, fork_num)) - return InvalidBuffer; - } -#endif - if (isLocalBuf) { buf_desc = LocalBufferAlloc(smgr, fork_num, block_num, &found); if (found) { @@ -2166,8 +2167,24 @@ static Buffer ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumb buf_block = isLocalBuf ? LocalBufHdrGetBlock(buf_desc) : BufHdrGetBlock(buf_desc); + bool block_exist = true; bool needputtodirty = - ReadBuffer_common_ReadBlock(smgr, relpersistence, fork_num, block_num, mode, is_extend, buf_block); + ReadBuffer_common_ReadBlock(smgr, relpersistence, fork_num, block_num, + mode, is_extend, buf_block, &block_exist); + /* + * When the parallel redo is enabled, there may be a scenario where + * the index is replayed before the page replayed. For single-mode, + * readable standby feature, Operators related to index scan access + * the index first, then access the table, and you will find that + * the tid or the heap(page) does not exist. Because the transaction + * was not originally committed, the tid or the heap(page) should not + * be visible. So accessing the non-existent heap tuple by the tid + * should return that the tuple does not exist without error reporting. + */ + if (!block_exist) { + return InvalidBuffer; + } + if (needputtodirty) { /* set BM_DIRTY to overwrite later */ uint32 old_buf_state = LockBufHdr(buf_desc); diff --git a/src/gausskernel/storage/smgr/md.cpp b/src/gausskernel/storage/smgr/md.cpp index 8f09fbce2..0e2b7b65f 100755 --- a/src/gausskernel/storage/smgr/md.cpp +++ b/src/gausskernel/storage/smgr/md.cpp @@ -968,7 +968,7 @@ do {\ /* * mdread() -- Read the specified block from a relation. */ -void mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char* buffer) +bool mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char* buffer) { off_t seekpos; int nbytes; @@ -1058,6 +1058,12 @@ void mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char* b } if (nbytes != BLCKSZ) { +#ifndef ENABLE_MULTIPLE_NODES + if(RecoveryInProgress()) { + return false; + } +#endif + if (nbytes < 0) { ereport(ERROR, (errcode_for_file_access(), @@ -1085,6 +1091,9 @@ void mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char* b BLCKSZ))); } } + + /* Target block exists */ + return true; } /* diff --git a/src/gausskernel/storage/smgr/smgr.cpp b/src/gausskernel/storage/smgr/smgr.cpp index 470dd4f11..9ea1c8a45 100755 --- a/src/gausskernel/storage/smgr/smgr.cpp +++ b/src/gausskernel/storage/smgr/smgr.cpp @@ -50,7 +50,7 @@ typedef struct f_smgr { void (*smgr_extend)( SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const char* buffer, bool skipFsync); void (*smgr_prefetch)(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum); - void (*smgr_read)(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char* buffer); + bool (*smgr_read)(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char* buffer); void (*smgr_write)(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const char* buffer, bool skipFsync); void (*smgr_writeback)(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber nblocks); BlockNumber (*smgr_nblocks)(SMgrRelation reln, ForkNumber forknum); @@ -560,9 +560,9 @@ void smgrasyncwrite(SMgrRelation reln, ForkNumber forknum, AioDispatchDesc_t** d * instantiate pages in the shared buffer cache. All storage managers * return pages in the format that POSTGRES expects. */ -void smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char* buffer) +bool smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char* buffer) { - (*(g_smgrsw[reln->smgr_which].smgr_read))(reln, forknum, blocknum, buffer); + return (*(g_smgrsw[reln->smgr_which].smgr_read))(reln, forknum, blocknum, buffer); } /* diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index f59db0724..fdf9859df 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.h @@ -95,7 +95,7 @@ extern void smgrdounlink(SMgrRelation reln, bool isRedo); extern void smgrdounlinkfork(SMgrRelation reln, ForkNumber forknum, bool isRedo); extern void smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const char* buffer, bool skipFsync); extern void smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum); -extern void smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char* buffer); +extern bool smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char* buffer); 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); @@ -117,7 +117,7 @@ extern bool mdexists(SMgrRelation reln, ForkNumber forknum); extern void mdunlink(const RelFileNodeBackend& rnode, ForkNumber forknum, bool isRedo); extern void mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const char* buffer, bool skipFsync); extern void mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum); -extern void mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char* buffer); +extern bool mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char* buffer); extern void mdwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const char* buffer, bool skipFsync); extern void mdwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber nblocks); extern BlockNumber mdnblocks(SMgrRelation reln, ForkNumber forknum);