diff options
Diffstat (limited to 'innobase/page')
-rw-r--r-- | innobase/page/page0cur.c | 19 | ||||
-rw-r--r-- | innobase/page/page0page.c | 69 |
2 files changed, 80 insertions, 8 deletions
diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index d3a40668c4b..7e2fc19c00f 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -14,6 +14,7 @@ Created 10/4/1994 Heikki Tuuri #include "rem0cmp.h" #include "mtr0log.h" #include "log0recv.h" +#include "rem0cmp.h" ulint page_cur_short_succ = 0; @@ -218,6 +219,8 @@ page_cur_search_with_match( || (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE) || (mode == PAGE_CUR_LE_OR_EXTENDS) || (mode == PAGE_CUR_DBG)); + page_check_dir(page); + #ifdef PAGE_CUR_ADAPT if ((page_header_get_field(page, PAGE_LEVEL) == 0) && (mode == PAGE_CUR_LE) @@ -595,6 +598,7 @@ page_cur_parse_insert_rec( rec_t* cursor_rec; byte buf1[1024]; byte* buf; + byte* ptr2 = ptr; ulint info_bits = 0; /* remove warning */ page_cur_t cursor; @@ -697,7 +701,20 @@ page_cur_parse_insert_rec( /* Build the inserted record to buf */ - ut_a(mismatch_index < UNIV_PAGE_SIZE); + if (mismatch_index >= UNIV_PAGE_SIZE) { + printf("Is short %lu, info_bits %lu, offset %lu, o_offset %lu\n" + "mismatch index %lu, end_seg_len %lu\n" + "parsed len %lu\n", + is_short, info_bits, offset, origin_offset, + mismatch_index, end_seg_len, (ulint)(ptr - ptr2)); + + printf("Dump of 300 bytes of log:\n"); + ut_print_buf(ptr2, 300); + + buf_page_print(page); + + ut_a(0); + } ut_memcpy(buf, rec_get_start(cursor_rec), mismatch_index); ut_memcpy(buf + mismatch_index, ptr, end_seg_len); diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c index 7d240bdd5b0..e087941a970 100644 --- a/innobase/page/page0page.c +++ b/innobase/page/page0page.c @@ -353,7 +353,7 @@ page_create( infimum_rec = rec_convert_dtuple_to_rec(heap_top, tuple); - ut_ad(infimum_rec == page + PAGE_INFIMUM); + ut_a(infimum_rec == page + PAGE_INFIMUM); rec_set_n_owned(infimum_rec, 1); rec_set_heap_no(infimum_rec, 0); @@ -370,7 +370,7 @@ page_create( supremum_rec = rec_convert_dtuple_to_rec(heap_top, tuple); - ut_ad(supremum_rec == page + PAGE_SUPREMUM); + ut_a(supremum_rec == page + PAGE_SUPREMUM); rec_set_n_owned(supremum_rec, 1); rec_set_heap_no(supremum_rec, 1); @@ -389,6 +389,8 @@ page_create( page_header_set_ptr(page, PAGE_FREE, NULL); page_header_set_field(page, PAGE_GARBAGE, 0); page_header_set_ptr(page, PAGE_LAST_INSERT, NULL); + page_header_set_field(page, PAGE_DIRECTION, PAGE_NO_DIRECTION); + page_header_set_field(page, PAGE_N_DIRECTION, 0); page_header_set_field(page, PAGE_N_RECS, 0); page_set_max_trx_id(page, ut_dulint_zero); @@ -402,17 +404,22 @@ page_create( slot = page_dir_get_nth_slot(page, 1); page_dir_slot_set_rec(slot, supremum_rec); - /* Set next pointers in infimum and supremum */ + /* Set the next pointers in infimum and supremum */ rec_set_next_offs(infimum_rec, (ulint)(supremum_rec - page)); rec_set_next_offs(supremum_rec, 0); +#ifdef notdefined + /* Disable the use of page_template: there is a race condition here: + while one thread is creating page_template, another one can start + using it before the memcpy completes! */ + if (page_template == NULL) { page_template = mem_alloc(UNIV_PAGE_SIZE); ut_memcpy(page_template, page, UNIV_PAGE_SIZE); } - +#endif return(page); } @@ -439,6 +446,8 @@ page_copy_rec_list_end_no_locks( page_cur_move_to_next(&cur1); } + ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == PAGE_INFIMUM); + page_cur_set_before_first(new_page, &cur2); /* Copy records from the original page to the new page */ @@ -446,8 +455,22 @@ page_copy_rec_list_end_no_locks( sup = page_get_supremum_rec(page); while (sup != page_cur_get_rec(&cur1)) { - ut_a( - page_cur_rec_insert(&cur2, page_cur_get_rec(&cur1), mtr)); + if (!page_cur_rec_insert(&cur2, + page_cur_get_rec(&cur1), mtr)) { + /* Track an assertion failure reported on the mailing + list on June 18th, 2003 */ + + buf_page_print(new_page); + buf_page_print(page); + ut_print_timestamp(stderr); + + fprintf(stderr, +"InnoDB: rec offset %lu, cur1 offset %lu, cur2 offset %lu\n", + (ulint)(rec - page), + (ulint)(page_cur_get_rec(&cur1) - page), + (ulint)(page_cur_get_rec(&cur2) - new_page)); + ut_a(0); + } page_cur_move_to_next(&cur1); page_cur_move_to_next(&cur2); @@ -1315,6 +1338,37 @@ page_rec_validate( return(TRUE); } + +/******************************************************************* +Checks that the first directory slot points to the infimum record and +the last to the supremum. This function is intended to track if the +bug fixed in 4.0.14 has caused corruption to users' databases. */ + +void +page_check_dir( +/*===========*/ + page_t* page) /* in: index page */ +{ + ulint n_slots; + + n_slots = page_dir_get_n_slots(page); + + if (page_dir_slot_get_rec(page_dir_get_nth_slot(page, 0)) + != page_get_infimum_rec(page)) { + + fprintf(stderr, +"InnoDB: Page directory corruption: supremum not pointed to\n"); + buf_page_print(page); + } + + if (page_dir_slot_get_rec(page_dir_get_nth_slot(page, n_slots - 1)) + != page_get_supremum_rec(page)) { + + fprintf(stderr, +"InnoDB: Page directory corruption: supremum not pointed to\n"); + buf_page_print(page); + } +} /******************************************************************* This function checks the consistency of an index page when we do not @@ -1598,7 +1652,8 @@ page_validate( "InnoDB: previous record %s\n", err_buf); rec_sprintf(err_buf, 900, rec); - fprintf(stderr, "InnoDB: record %s\n", err_buf); + fprintf(stderr, + "InnoDB: record %s\n", err_buf); goto func_exit; } |