!1056 同步lsn check例外场景:truncate之后再init出来的page,不做检查

Merge pull request !1056 from mujinqiang/master0626
This commit is contained in:
opengauss-bot
2021-06-28 12:03:49 +00:00
committed by Gitee
5 changed files with 37 additions and 18 deletions

View File

@ -2191,7 +2191,7 @@ void xlog_db_create(Oid dstDbId, Oid dstTbSpcId, Oid srcDbId, Oid srcTbSpcId)
RelFileNode tmp = {srcTbSpcId, srcDbId, 0, InvalidBktId}; RelFileNode tmp = {srcTbSpcId, srcDbId, 0, InvalidBktId};
/* forknum and blockno has no meaning */ /* forknum and blockno has no meaning */
log_invalid_page(tmp, MAIN_FORKNUM, 0, false); log_invalid_page(tmp, MAIN_FORKNUM, 0, NOT_PRESENT);
} }
} }

View File

@ -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", "lsn in current page %lu, page info:%u/%u/%u forknum %d lsn %lu blknum:%u",
lastLsn, pageCurLsn, blockinfo->rnode.spcNode, blockinfo->rnode.dbNode, lastLsn, pageCurLsn, blockinfo->rnode.spcNode, blockinfo->rnode.dbNode,
blockinfo->rnode.relNode, blockinfo->forknum, lsn, blockinfo->blkno))); 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 { } else {
ereport(PANIC, (errmsg("lsn check error, lsn in record (%X/%X) ,lsn in current page %X/%X, " 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", "page info:%u/%u/%u forknum %d blknum:%u lsn %X/%X",

View File

@ -62,20 +62,28 @@ typedef struct xl_invalid_page_key {
typedef struct xl_invalid_page { typedef struct xl_invalid_page {
xl_invalid_page_key key; /* hash key ... must be first */ 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; } xl_invalid_page;
/* Report a reference to an 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); char *path = relpathperm(node, forkno);
if (present) if (type == NOT_INITIALIZED) {
ereport(elevel, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), ereport(elevel, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("page %u of relation %s is uninitialized", blkno, path))); 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 else
ereport(elevel, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), 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); pfree(path);
} }
@ -103,7 +111,7 @@ void closeXLogRead()
} }
/* Log a reference to an invalid page */ /* 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_key key;
xl_invalid_page *hentry = NULL; 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). * something about the XLOG record that generated the reference).
*/ */
if (log_min_messages <= DEBUG1 || client_min_messages <= DEBUG1) 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) { if (t_thrd.xlog_cxt.invalid_page_tab == NULL) {
/* create hash table when first needed */ /* create hash table when first needed */
@ -148,7 +156,7 @@ void log_invalid_page(const RelFileNode &node, ForkNumber forkno, BlockNumber bl
if (!found) { if (!found) {
/* hash_search already filled in the key */ /* hash_search already filled in the key */
hentry->present = present; hentry->type = type;
} else { } else {
/* repeat reference ... leave "present" as it was */ /* repeat reference ... leave "present" as it was */
} }
@ -236,7 +244,7 @@ void PrintInvalidPage()
xl_invalid_page *hentry = NULL; xl_invalid_page *hentry = NULL;
hash_seq_init(&status, t_thrd.xlog_cxt.invalid_page_tab); hash_seq_init(&status, t_thrd.xlog_cxt.invalid_page_tab);
while ((hentry = (xl_invalid_page *)hash_seq_search(&status)) != NULL) { 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. * only PANIC after we've dumped all the available info.
*/ */
while ((hentry = (xl_invalid_page *)hash_seq_search(&status)) != NULL) { 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++; t_thrd.xlog_cxt.invaildPageCnt++;
foundone = true; foundone = true;
} }
@ -351,7 +359,7 @@ void XLogCheckInvalidPages(void)
*/ */
while ((hentry = (xl_invalid_page *)hash_seq_search(&status)) != NULL) { while ((hentry = (xl_invalid_page *)hash_seq_search(&status)) != NULL) {
report_invalid_page(WARNING, hentry->key.node, hentry->key.forkno, hentry->key.blkno, report_invalid_page(WARNING, hentry->key.node, hentry->key.forkno, hentry->key.blkno,
hentry->present); hentry->type);
t_thrd.xlog_cxt.invaildPageCnt++; t_thrd.xlog_cxt.invaildPageCnt++;
foundone = true; 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); buffer = ReadBuffer_common_for_localbuf(rnode, RELPERSISTENCE_PERMANENT, forknum, blkno, mode, NULL, &hit);
} else { } else {
if (mode == RBM_NORMAL) { if (mode == RBM_NORMAL) {
log_invalid_page(rnode, forknum, blkno, false); log_invalid_page(rnode, forknum, blkno, NOT_PRESENT);
return InvalidBuffer; return InvalidBuffer;
} }
if (mode == RBM_NORMAL_NO_LOG) if (mode == RBM_NORMAL_NO_LOG)
@ -612,7 +620,7 @@ Buffer XLogReadBufferExtendedWithLocalBuffer(RelFileNode rnode, ForkNumber forkn
if (PageIsNew(page)) { if (PageIsNew(page)) {
Assert(!PageIsLogical(page)); Assert(!PageIsLogical(page));
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
log_invalid_page(rnode, forknum, blkno, true); log_invalid_page(rnode, forknum, blkno, NOT_INITIALIZED);
return InvalidBuffer; return InvalidBuffer;
} }
} }
@ -646,7 +654,7 @@ Buffer XLogReadBufferExtendedWithoutBuffer(RelFileNode rnode, ForkNumber forknum
buffer = ReadBuffer_common_for_direct(rnode, RELPERSISTENCE_PERMANENT, forknum, blkno, mode); buffer = ReadBuffer_common_for_direct(rnode, RELPERSISTENCE_PERMANENT, forknum, blkno, mode);
} else { } else {
if (mode == RBM_NORMAL) { if (mode == RBM_NORMAL) {
log_invalid_page(rnode, forknum, blkno, false); log_invalid_page(rnode, forknum, blkno, NOT_PRESENT);
return InvalidBuffer; return InvalidBuffer;
} }
if (mode == RBM_NORMAL_NO_LOG) if (mode == RBM_NORMAL_NO_LOG)
@ -677,7 +685,7 @@ Buffer XLogReadBufferExtendedWithoutBuffer(RelFileNode rnode, ForkNumber forknum
if (PageIsNew(page)) { if (PageIsNew(page)) {
Assert(!PageIsLogical(page)); Assert(!PageIsLogical(page));
XLogRedoBufferReleaseFunc(buffer); XLogRedoBufferReleaseFunc(buffer);
log_invalid_page(rnode, forknum, blkno, true); log_invalid_page(rnode, forknum, blkno, NOT_INITIALIZED);
return InvalidBuffer; return InvalidBuffer;
} }
} }
@ -741,7 +749,7 @@ Buffer XLogReadBufferExtended(const RelFileNode &rnode, ForkNumber forknum, Bloc
} else { } else {
/* hm, page doesn't exist in file */ /* hm, page doesn't exist in file */
if (mode == RBM_NORMAL) { if (mode == RBM_NORMAL) {
log_invalid_page(rnode, forknum, blkno, false); log_invalid_page(rnode, forknum, blkno, NOT_PRESENT);
return InvalidBuffer; return InvalidBuffer;
} }
if (mode == RBM_NORMAL_NO_LOG) if (mode == RBM_NORMAL_NO_LOG)
@ -785,7 +793,7 @@ Buffer XLogReadBufferExtended(const RelFileNode &rnode, ForkNumber forknum, Bloc
if (PageIsNew(page)) { if (PageIsNew(page)) {
Assert(!PageIsLogical(page)); Assert(!PageIsLogical(page));
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
log_invalid_page(rnode, forknum, blkno, true); log_invalid_page(rnode, forknum, blkno, NOT_INITIALIZED);
return InvalidBuffer; return InvalidBuffer;
} }
} }

View File

@ -27,6 +27,12 @@ typedef enum {
* replayed) */ * replayed) */
} XLogRedoAction; } XLogRedoAction;
typedef enum {
NOT_PRESENT,
NOT_INITIALIZED,
LSN_CHECK_ERROR,
}InvalidPageType;
extern bool XLogHaveInvalidPages(void); extern bool XLogHaveInvalidPages(void);
extern void* XLogGetInvalidPages(); extern void* XLogGetInvalidPages();
@ -44,7 +50,7 @@ extern XLogRedoAction XLogReadBufferForRedo(XLogReaderState* record, uint8 buffe
extern Relation CreateFakeRelcacheEntry(const RelFileNode& rnode); extern Relation CreateFakeRelcacheEntry(const RelFileNode& rnode);
extern Relation CreateCUReplicationRelation(const RelFileNode& rnode, int BackendId, char relpersistence, const char* relname); extern Relation CreateCUReplicationRelation(const RelFileNode& rnode, int BackendId, char relpersistence, const char* relname);
extern void FreeFakeRelcacheEntry(Relation fakerel); 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, extern int read_local_xlog_page(XLogReaderState* state, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr,
char* cur_page, TimeLineID* pageTLI); char* cur_page, TimeLineID* pageTLI);
extern void closeXLogRead(); extern void closeXLogRead();

View File

@ -253,6 +253,8 @@ typedef HeapPageHeaderData* HeapPageHeader;
*/ */
#define PageIsNew(page) (((PageHeader)(page))->pd_upper == 0) #define PageIsNew(page) (((PageHeader)(page))->pd_upper == 0)
#define PageUpperIsInitNew(page) (((PageHeader)(page))->pd_upper == ((PageHeader)(page))->pd_special)
/* /*
* PageGetItemId * PageGetItemId
* Returns an item identifier of a page. * Returns an item identifier of a page.