From ca0d4f93f01eea154fa9a6eeba822bf99c903296 Mon Sep 17 00:00:00 2001 From: ljy Date: Wed, 23 Apr 2025 15:22:26 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E5=A4=84double=20wr?= =?UTF-8?q?ite=E6=97=A5=E5=BF=97=E6=89=93=E5=8D=B0=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E5=B4=A9=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/pagehack/pagehack.cpp | 12 +++++++----- .../storage/access/transam/double_write.cpp | 7 +++++-- src/include/access/double_write.h | 6 ++++-- src/include/knl/knl_instance.h | 2 ++ 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/contrib/pagehack/pagehack.cpp b/contrib/pagehack/pagehack.cpp index ce3b933d76..c1fb986751 100644 --- a/contrib/pagehack/pagehack.cpp +++ b/contrib/pagehack/pagehack.cpp @@ -4659,7 +4659,7 @@ static bool read_batch_pages( return true; } -static bool verify_batch_continous(dw_batch_t* curr_head, uint16 dwn) +static bool verify_batch_continous(dw_batch_t* curr_head, char* max_page_addr, uint16 dwn) { dw_batch_t* curr_tail = dw_batch_tail_page(curr_head); if (dw_verify_page(curr_head) && dw_verify_page(curr_tail)) { @@ -4674,7 +4674,7 @@ static bool verify_batch_continous(dw_batch_t* curr_head, uint16 dwn) curr_tail->head.dwn, curr_tail->page_num); } - } else if (!dw_verify_batch(curr_head, dwn)) { + } else if (!dw_verify_batch(curr_head, max_page_addr, dwn)) { if (dw_verify_page(curr_head) && (curr_head->page_num == 0 || curr_head->head.page_id == DW_BATCH_FILE_START)) { fprintf(stdout, "no double write pages since last ckpt or file full: " @@ -4771,7 +4771,7 @@ static uint16 calc_reading_pages(dw_batch_t** curr_head, char* start_buf, uint16 return (uint16)readingPages; } -static void parse_dw_batch(char* buf, FILE* fd, dw_file_head_t* file_head, uint16 page_num, uint16 dw_batch_page_num) +static void parse_dw_batch(char* buf, char* max_page_addr, FILE* fd, dw_file_head_t* file_head, uint16 page_num, uint16 dw_batch_page_num) { uint16 file_page_id, read_pages; uint16 reading_pages; @@ -4799,7 +4799,7 @@ static void parse_dw_batch(char* buf, FILE* fd, dw_file_head_t* file_head, uint1 fprintf(stdout, "no double write pages since last ckpt or file full\n"); break; } - if (!verify_batch_continous(curr_head, file_head->head.dwn)) { + if (!verify_batch_continous(curr_head, max_page_addr, file_head->head.dwn)) { break; } @@ -4834,6 +4834,7 @@ static bool parse_dw_file(const char* file_name, uint32 start_page, uint32 page_ dw_batch_meta_file* batch_meta_file; char* meta_buf = NULL; char* dw_buf = NULL; + char* max_page_addr; /* copy the full path of dw file to meta_full_path */ if (realpath(file_name, meta_full_path) == NULL && file_name[0] == '\0') { @@ -4895,6 +4896,7 @@ static bool parse_dw_file(const char* file_name, uint32 start_page, uint32 page_ return false; } + max_page_addr = dw_buf + BLCKSZ * (DW_BUF_MAX_FOR_NOHBK - 1); result = fread(dw_buf, BLCKSZ, 1, fd); if (result != 1) { free(dw_buf); @@ -4927,7 +4929,7 @@ static bool parse_dw_file(const char* file_name, uint32 start_page, uint32 page_ page_num = dw_batch_page_num - start_page; } - parse_dw_batch(dw_buf, fd, &file_head, (uint16)page_num, (uint16)dw_batch_page_num); + parse_dw_batch(dw_buf, max_page_addr, fd, &file_head, (uint16)page_num, (uint16)dw_batch_page_num); free(dw_buf); fclose(fd); diff --git a/src/gausskernel/storage/access/transam/double_write.cpp b/src/gausskernel/storage/access/transam/double_write.cpp index 026857a129..bbfcb27884 100644 --- a/src/gausskernel/storage/access/transam/double_write.cpp +++ b/src/gausskernel/storage/access/transam/double_write.cpp @@ -960,7 +960,9 @@ static bool dw_batch_head_broken(dw_batch_file_context *cxt, dw_batch_t *curr_he } } else { dw_log_recover_state(cxt, WARNING, "Head broken", curr_head); - dw_log_recover_state(cxt, WARNING, "Tail unknown", curr_tail); + if ((char*)curr_tail <= cxt->max_page_addr) { + dw_log_recover_state(cxt, WARNING, "Tail unknown", curr_tail); + } broken = true; } return broken; @@ -1049,7 +1051,7 @@ static void dw_recover_partial_write_batch(dw_batch_file_context *cxt) dw_read_pages(&read_asst, reading_pages); curr_head = (dw_batch_t *)(read_asst.buf + (read_asst.buf_start * BLCKSZ)); - if (!dw_verify_batch(curr_head, cxt->file_head->head.dwn)) { + if (!dw_verify_batch(curr_head, cxt->max_page_addr, cxt->file_head->head.dwn)) { dw_file_broken = dw_batch_head_broken(cxt, curr_head); break; } @@ -1540,6 +1542,7 @@ static void dw_file_cxt_init_batch(int id, dw_batch_file_context *batch_file_cxt batch_file_cxt->fd = dw_open_file(batch_file_cxt->file_name); buf_size = DW_MEM_CTX_MAX_BLOCK_SIZE_FOR_NOHBK; batch_file_cxt->unaligned_buf = (char *)palloc0(buf_size); /* one more BLCKSZ for alignment */ + batch_file_cxt->max_page_addr = batch_file_cxt->unaligned_buf + buf_size - BLCKSZ; buf = (char *)TYPEALIGN(BLCKSZ, batch_file_cxt->unaligned_buf); batch_file_cxt->file_head = (dw_file_head_t *)buf; diff --git a/src/include/access/double_write.h b/src/include/access/double_write.h index 6fdc7107a8..747a1ffdc0 100644 --- a/src/include/access/double_write.h +++ b/src/include/access/double_write.h @@ -232,11 +232,13 @@ inline dw_batch_t* dw_batch_tail_page(dw_batch_t* head_page) * @param dwn double write number * @return true dwn and checksum match */ -inline bool dw_verify_batch(dw_batch_t* head_page, uint16 dwn) +inline bool dw_verify_batch(dw_batch_t* head_page, char* max_page_addr, uint16 dwn) { if (head_page->head.dwn == dwn && dw_verify_page(head_page)) { dw_batch_t* tail_page = dw_batch_tail_page(head_page); - return tail_page->head.dwn == dwn && dw_verify_page(tail_page); + return (char*) tail_page <= max_page_addr && + tail_page->head.dwn == dwn && + dw_verify_page(tail_page); } return false; diff --git a/src/include/knl/knl_instance.h b/src/include/knl/knl_instance.h index e1ce0b9432..e1c3f14455 100755 --- a/src/include/knl/knl_instance.h +++ b/src/include/knl/knl_instance.h @@ -596,6 +596,8 @@ typedef struct dw_batch_file_context{ char* unaligned_buf; char* buf; + /*The address of the last page in unaligned_buf, it is used to verify the validity of the memory*/ + char* max_page_addr; struct LWLock* flush_lock; dw_file_head_t* file_head; -- Gitee