!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};
/* 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",
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",

View File

@ -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
}
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 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;
}
}

View File

@ -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();

View File

@ -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.