From 7b8f609c3859f23c90951e158973467ca185ab75 Mon Sep 17 00:00:00 2001 From: mujinqiang <1165845907@qq.com> Date: Sat, 26 Jun 2021 17:27:48 +0800 Subject: [PATCH] =?UTF-8?q?lsn=20check=E4=BE=8B=E5=A4=96=E5=9C=BA=E6=99=AF?= =?UTF-8?q?:truncate=E4=B9=8B=E5=90=8E=E5=86=8Dinit=E5=87=BA=E6=9D=A5?= =?UTF-8?q?=E7=9A=84page=EF=BC=8C=E4=B8=8D=E5=81=9A=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../optimizer/commands/dbcommands.cpp | 2 +- .../storage/access/redo/redo_xlogutils.cpp | 3 ++ .../storage/access/transam/xlogutils.cpp | 40 +++++++++++-------- src/include/access/xlogutils.h | 8 +++- src/include/storage/buf/bufpage.h | 2 + 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/gausskernel/optimizer/commands/dbcommands.cpp b/src/gausskernel/optimizer/commands/dbcommands.cpp index d6bcbb953..d35ea51e0 100644 --- a/src/gausskernel/optimizer/commands/dbcommands.cpp +++ b/src/gausskernel/optimizer/commands/dbcommands.cpp @@ -2191,7 +2191,7 @@ void xlog_db_create(Oid dstDbId, Oid dstTbSpcId, Oid srcDbId, Oid srcTbSpcId) RelFileNode tmp = {srcTbSpcId, srcDbId, 0, InvalidBktId}; /* forknum and blockno has no meaning */ - log_invalid_page(tmp, MAIN_FORKNUM, 0, false); + log_invalid_page(tmp, MAIN_FORKNUM, 0, NOT_PRESENT); } } diff --git a/src/gausskernel/storage/access/redo/redo_xlogutils.cpp b/src/gausskernel/storage/access/redo/redo_xlogutils.cpp index 939bdd357..8cebaac0d 100644 --- a/src/gausskernel/storage/access/redo/redo_xlogutils.cpp +++ b/src/gausskernel/storage/access/redo/redo_xlogutils.cpp @@ -109,6 +109,9 @@ void DoLsnCheck(RedoBufferInfo *bufferinfo, bool willInit, XLogRecPtr lastLsn) "lsn in current page %lu, page info:%u/%u/%u forknum %d lsn %lu blknum:%u", lastLsn, pageCurLsn, blockinfo->rnode.spcNode, blockinfo->rnode.dbNode, blockinfo->rnode.relNode, blockinfo->forknum, lsn, blockinfo->blkno))); + } else if (pageCurLsn == InvalidXLogRecPtr && PageIsEmpty(page) && PageUpperIsInitNew(page)) { + log_invalid_page(bufferinfo->blockinfo.rnode, bufferinfo->blockinfo.forknum, bufferinfo->blockinfo.blkno, + LSN_CHECK_ERROR); } else { ereport(PANIC, (errmsg("lsn check error, lsn in record (%X/%X) ,lsn in current page %X/%X, " "page info:%u/%u/%u forknum %d blknum:%u lsn %X/%X", diff --git a/src/gausskernel/storage/access/transam/xlogutils.cpp b/src/gausskernel/storage/access/transam/xlogutils.cpp index b81775bfa..3c7de449e 100644 --- a/src/gausskernel/storage/access/transam/xlogutils.cpp +++ b/src/gausskernel/storage/access/transam/xlogutils.cpp @@ -62,20 +62,28 @@ typedef struct xl_invalid_page_key { typedef struct xl_invalid_page { xl_invalid_page_key key; /* hash key ... must be first */ - bool present; /* page existed but contained zeroes */ + InvalidPageType type; /* invalid page type */ } xl_invalid_page; /* Report a reference to an invalid page */ -static void report_invalid_page(int elevel, const RelFileNode &node, ForkNumber forkno, BlockNumber blkno, bool present) +static void report_invalid_page(int elevel, const RelFileNode &node, ForkNumber forkno, BlockNumber blkno, InvalidPageType type) { char *path = relpathperm(node, forkno); - if (present) + if (type == NOT_INITIALIZED) { ereport(elevel, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("page %u of relation %s is uninitialized", blkno, path))); + } + else if (type == NOT_PRESENT) { + ereport(elevel, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("page %u of relation %s does not exist", blkno, path))); + } else if (type == LSN_CHECK_ERROR) { + ereport(elevel, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("page %u of relation %s lsn check error", blkno, path))); + } else ereport(elevel, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("page %u of relation %s does not exist", blkno, path))); + errmsg("page %u of relation %s unkown error", blkno, path))); pfree(path); } @@ -103,7 +111,7 @@ void closeXLogRead() } /* Log a reference to an invalid page */ -void log_invalid_page(const RelFileNode &node, ForkNumber forkno, BlockNumber blkno, bool present) +void log_invalid_page(const RelFileNode &node, ForkNumber forkno, BlockNumber blkno, InvalidPageType type) { xl_invalid_page_key key; xl_invalid_page *hentry = NULL; @@ -120,7 +128,7 @@ void log_invalid_page(const RelFileNode &node, ForkNumber forkno, BlockNumber bl * something about the XLOG record that generated the reference). */ if (log_min_messages <= DEBUG1 || client_min_messages <= DEBUG1) - report_invalid_page(LOG, node, forkno, blkno, present); + report_invalid_page(LOG, node, forkno, blkno, type); if (t_thrd.xlog_cxt.invalid_page_tab == NULL) { /* create hash table when first needed */ @@ -148,7 +156,7 @@ void log_invalid_page(const RelFileNode &node, ForkNumber forkno, BlockNumber bl if (!found) { /* hash_search already filled in the key */ - hentry->present = present; + hentry->type = type; } else { /* repeat reference ... leave "present" as it was */ } @@ -236,7 +244,7 @@ void PrintInvalidPage() xl_invalid_page *hentry = NULL; hash_seq_init(&status, t_thrd.xlog_cxt.invalid_page_tab); while ((hentry = (xl_invalid_page *)hash_seq_search(&status)) != NULL) { - report_invalid_page(LOG, hentry->key.node, hentry->key.forkno, hentry->key.blkno, hentry->present); + report_invalid_page(LOG, hentry->key.node, hentry->key.forkno, hentry->key.blkno, hentry->type); } } } @@ -290,7 +298,7 @@ static bool XLogCheckInvalidPages_ForSingle(void) * only PANIC after we've dumped all the available info. */ while ((hentry = (xl_invalid_page *)hash_seq_search(&status)) != NULL) { - report_invalid_page(WARNING, hentry->key.node, hentry->key.forkno, hentry->key.blkno, hentry->present); + report_invalid_page(WARNING, hentry->key.node, hentry->key.forkno, hentry->key.blkno, hentry->type); t_thrd.xlog_cxt.invaildPageCnt++; foundone = true; } @@ -351,7 +359,7 @@ void XLogCheckInvalidPages(void) */ while ((hentry = (xl_invalid_page *)hash_seq_search(&status)) != NULL) { report_invalid_page(WARNING, hentry->key.node, hentry->key.forkno, hentry->key.blkno, - hentry->present); + hentry->type); t_thrd.xlog_cxt.invaildPageCnt++; foundone = true; } @@ -581,7 +589,7 @@ Buffer XLogReadBufferExtendedWithLocalBuffer(RelFileNode rnode, ForkNumber forkn buffer = ReadBuffer_common_for_localbuf(rnode, RELPERSISTENCE_PERMANENT, forknum, blkno, mode, NULL, &hit); } else { if (mode == RBM_NORMAL) { - log_invalid_page(rnode, forknum, blkno, false); + log_invalid_page(rnode, forknum, blkno, NOT_PRESENT); return InvalidBuffer; } if (mode == RBM_NORMAL_NO_LOG) @@ -612,7 +620,7 @@ Buffer XLogReadBufferExtendedWithLocalBuffer(RelFileNode rnode, ForkNumber forkn if (PageIsNew(page)) { Assert(!PageIsLogical(page)); ReleaseBuffer(buffer); - log_invalid_page(rnode, forknum, blkno, true); + log_invalid_page(rnode, forknum, blkno, NOT_INITIALIZED); return InvalidBuffer; } } @@ -646,7 +654,7 @@ Buffer XLogReadBufferExtendedWithoutBuffer(RelFileNode rnode, ForkNumber forknum buffer = ReadBuffer_common_for_direct(rnode, RELPERSISTENCE_PERMANENT, forknum, blkno, mode); } else { if (mode == RBM_NORMAL) { - log_invalid_page(rnode, forknum, blkno, false); + log_invalid_page(rnode, forknum, blkno, NOT_PRESENT); return InvalidBuffer; } if (mode == RBM_NORMAL_NO_LOG) @@ -677,7 +685,7 @@ Buffer XLogReadBufferExtendedWithoutBuffer(RelFileNode rnode, ForkNumber forknum if (PageIsNew(page)) { Assert(!PageIsLogical(page)); XLogRedoBufferReleaseFunc(buffer); - log_invalid_page(rnode, forknum, blkno, true); + log_invalid_page(rnode, forknum, blkno, NOT_INITIALIZED); return InvalidBuffer; } } @@ -741,7 +749,7 @@ Buffer XLogReadBufferExtended(const RelFileNode &rnode, ForkNumber forknum, Bloc } else { /* hm, page doesn't exist in file */ if (mode == RBM_NORMAL) { - log_invalid_page(rnode, forknum, blkno, false); + log_invalid_page(rnode, forknum, blkno, NOT_PRESENT); return InvalidBuffer; } if (mode == RBM_NORMAL_NO_LOG) @@ -785,7 +793,7 @@ Buffer XLogReadBufferExtended(const RelFileNode &rnode, ForkNumber forknum, Bloc if (PageIsNew(page)) { Assert(!PageIsLogical(page)); ReleaseBuffer(buffer); - log_invalid_page(rnode, forknum, blkno, true); + log_invalid_page(rnode, forknum, blkno, NOT_INITIALIZED); return InvalidBuffer; } } diff --git a/src/include/access/xlogutils.h b/src/include/access/xlogutils.h index cdf9c492f..08879e83d 100644 --- a/src/include/access/xlogutils.h +++ b/src/include/access/xlogutils.h @@ -27,6 +27,12 @@ typedef enum { * replayed) */ } XLogRedoAction; +typedef enum { + NOT_PRESENT, + NOT_INITIALIZED, + LSN_CHECK_ERROR, +}InvalidPageType; + extern bool XLogHaveInvalidPages(void); extern void* XLogGetInvalidPages(); @@ -44,7 +50,7 @@ extern XLogRedoAction XLogReadBufferForRedo(XLogReaderState* record, uint8 buffe extern Relation CreateFakeRelcacheEntry(const RelFileNode& rnode); extern Relation CreateCUReplicationRelation(const RelFileNode& rnode, int BackendId, char relpersistence, const char* relname); extern void FreeFakeRelcacheEntry(Relation fakerel); -extern void log_invalid_page(const RelFileNode& node, ForkNumber forkno, BlockNumber blkno, bool present); +extern void log_invalid_page(const RelFileNode& node, ForkNumber forkno, BlockNumber blkno, InvalidPageType type); extern int read_local_xlog_page(XLogReaderState* state, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char* cur_page, TimeLineID* pageTLI); extern void closeXLogRead(); diff --git a/src/include/storage/buf/bufpage.h b/src/include/storage/buf/bufpage.h index c03e0ae33..cab832018 100644 --- a/src/include/storage/buf/bufpage.h +++ b/src/include/storage/buf/bufpage.h @@ -253,6 +253,8 @@ typedef HeapPageHeaderData* HeapPageHeader; */ #define PageIsNew(page) (((PageHeader)(page))->pd_upper == 0) +#define PageUpperIsInitNew(page) (((PageHeader)(page))->pd_upper == ((PageHeader)(page))->pd_special) + /* * PageGetItemId * Returns an item identifier of a page.