diff --git a/contrib/pagehack/pagehack.cpp b/contrib/pagehack/pagehack.cpp index ce3b933d768a527c39e5e76bd4288f56e3405d3c..c1fb986751cddcc544ebeeca5782256b6913193e 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 026857a12998220afabd22f7497995315c77f810..bbfcb2788407817e9fe4728afe260be863a0dc94 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 6fdc7107a861638d8dc11fb02e8d7b41cc3900b4..747a1ffdc0a5e4d69c031c080dd243a157409b23 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 e1ce0b94327a08450f6294f85d96e5c54589cae6..e1c3f14455d59fbaae64cb7d0c4edff9d953a5df 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;