diff options
Diffstat (limited to 'innobase/btr/btr0btr.c')
-rw-r--r-- | innobase/btr/btr0btr.c | 174 |
1 files changed, 96 insertions, 78 deletions
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 1744fc36f4d..2d84586216a 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -20,6 +20,7 @@ Created 6/2/1994 Heikki Tuuri #include "rem0cmp.h" #include "lock0lock.h" #include "ibuf0ibuf.h" +#include "trx0trx.h" /* Latching strategy of the InnoDB B-tree @@ -137,13 +138,13 @@ btr_root_get( ulint space; ulint root_page_no; page_t* root; - ibool comp = UT_LIST_GET_FIRST(tree->tree_indexes)->table->comp; space = dict_tree_get_space(tree); root_page_no = dict_tree_get_page(tree); root = btr_page_get(space, root_page_no, RW_X_LATCH, mtr); - ut_a(page_is_comp(root) == comp); + ut_a(!!page_is_comp(root) == + UT_LIST_GET_FIRST(tree->tree_indexes)->table->comp); return(root); } @@ -163,21 +164,19 @@ btr_get_prev_user_rec( page_t* page; page_t* prev_page; ulint prev_page_no; - rec_t* prev_rec; ulint space; - page = buf_frame_align(rec); - - if (page_get_infimum_rec(page) != rec) { + if (!page_rec_is_infimum(rec)) { - prev_rec = page_rec_get_prev(rec); + rec_t* prev_rec = page_rec_get_prev(rec); - if (page_get_infimum_rec(page) != prev_rec) { + if (!page_rec_is_infimum(prev_rec)) { return(prev_rec); } } + page = buf_frame_align(rec); prev_page_no = btr_page_get_prev(page, mtr); space = buf_frame_get_space_id(page); @@ -192,9 +191,7 @@ btr_get_prev_user_rec( MTR_MEMO_PAGE_X_FIX))); ut_a(page_is_comp(prev_page) == page_is_comp(page)); - prev_rec = page_rec_get_prev(page_get_supremum_rec(prev_page)); - - return(prev_rec); + return(page_rec_get_prev(page_get_supremum_rec(prev_page))); } return(NULL); @@ -215,21 +212,19 @@ btr_get_next_user_rec( page_t* page; page_t* next_page; ulint next_page_no; - rec_t* next_rec; ulint space; - page = buf_frame_align(rec); - - if (page_get_supremum_rec(page) != rec) { + if (!page_rec_is_supremum(rec)) { - next_rec = page_rec_get_next(rec); + rec_t* next_rec = page_rec_get_next(rec); - if (page_get_supremum_rec(page) != next_rec) { + if (!page_rec_is_supremum(next_rec)) { return(next_rec); } } + page = buf_frame_align(rec); next_page_no = btr_page_get_next(page, mtr); space = buf_frame_get_space_id(page); @@ -244,9 +239,7 @@ btr_get_next_user_rec( MTR_MEMO_PAGE_X_FIX))); ut_a(page_is_comp(next_page) == page_is_comp(page)); - next_rec = page_rec_get_next(page_get_infimum_rec(next_page)); - - return(next_rec); + return(page_rec_get_next(page_get_infimum_rec(next_page))); } return(NULL); @@ -573,8 +566,7 @@ btr_page_get_father_for_rec( ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), MTR_MEMO_X_LOCK)); - ut_a(user_rec != page_get_supremum_rec(page)); - ut_a(user_rec != page_get_infimum_rec(page)); + ut_a(page_rec_is_user_rec(user_rec)); ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page)); @@ -598,6 +590,7 @@ btr_page_get_father_for_rec( if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != buf_frame_get_page_no(page)) { + rec_t* print_rec; fputs("InnoDB: Dump of the child page:\n", stderr); buf_page_print(buf_frame_align(page)); fputs("InnoDB: Dump of the parent page:\n", stderr); @@ -612,11 +605,10 @@ btr_page_get_father_for_rec( (ulong) btr_node_ptr_get_child_page_no(node_ptr, offsets), (ulong) buf_frame_get_page_no(page)); - offsets = rec_get_offsets(page_rec_get_next( - page_get_infimum_rec(page)), index, + print_rec = page_rec_get_next(page_get_infimum_rec(page)); + offsets = rec_get_offsets(print_rec, index, offsets, ULINT_UNDEFINED, &heap); - page_rec_print(page_rec_get_next(page_get_infimum_rec(page)), - offsets); + page_rec_print(print_rec, offsets); offsets = rec_get_offsets(node_ptr, index, offsets, ULINT_UNDEFINED, &heap); page_rec_print(node_ptr, offsets); @@ -663,7 +655,7 @@ btr_create( ulint type, /* in: type of the index */ ulint space, /* in: space where created */ dulint index_id,/* in: index id */ - ibool comp, /* in: TRUE=compact page format */ + ulint comp, /* in: nonzero=compact page format */ mtr_t* mtr) /* in: mini-transaction handle */ { ulint page_no; @@ -854,11 +846,12 @@ btr_page_reorganize_low( ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); + ut_ad(!!page_is_comp(page) == index->table->comp); data_size1 = page_get_data_size(page); max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1); /* Write the log record */ - mlog_open_and_write_index(mtr, page, index, index->table->comp + mlog_open_and_write_index(mtr, page, index, page_is_comp(page) ? MLOG_COMP_PAGE_REORGANIZE : MLOG_PAGE_REORGANIZE, 0); @@ -877,7 +870,7 @@ btr_page_reorganize_low( /* Recreate the page: note that global data on page (possible segment headers, next page-field, etc.) is preserved intact */ - page_create(page, mtr, index->table->comp); + page_create(page, mtr, page_is_comp(page)); buf_block_align(page)->check_index_page_at_flush = TRUE; /* Copy the records from the temporary space to the recreated page; @@ -1070,7 +1063,7 @@ btr_root_raise_and_insert( as there is no lower alphabetical limit to records in the leftmost node of a level: */ - btr_set_min_rec_mark(node_ptr_rec, cursor->index->table->comp, mtr); + btr_set_min_rec_mark(node_ptr_rec, page_is_comp(root), mtr); /* Free the memory heap */ mem_heap_free(heap); @@ -1151,7 +1144,6 @@ btr_page_get_split_rec_to_right( { page_t* page; rec_t* insert_point; - rec_t* supremum; page = btr_cur_get_page(cursor); insert_point = btr_cur_get_rec(cursor); @@ -1160,13 +1152,23 @@ btr_page_get_split_rec_to_right( the previous insert on the same page, we assume that there is a pattern of sequential inserts here. */ - if (page_header_get_ptr(page, PAGE_LAST_INSERT) == insert_point) { + if (UNIV_LIKELY(page_header_get_ptr(page, PAGE_LAST_INSERT) + == insert_point)) { + + rec_t* next_rec; + + next_rec = page_rec_get_next(insert_point); - supremum = page_get_supremum_rec(page); - - if (page_rec_get_next(insert_point) != supremum - && page_rec_get_next(page_rec_get_next(insert_point)) - != supremum) { + if (page_rec_is_supremum(next_rec)) { +split_at_new: + /* Split at the new record to insert */ + *split_rec = NULL; + } else { + rec_t* next_next_rec = page_rec_get_next(next_rec); + if (page_rec_is_supremum(next_next_rec)) { + + goto split_at_new; + } /* If there are >= 2 user records up from the insert point, split all but 1 off. We want to keep one because @@ -1175,12 +1177,8 @@ btr_page_get_split_rec_to_right( search position just by looking at the records on this page. */ - *split_rec = page_rec_get_next( - page_rec_get_next(insert_point)); - } else { - /* Else split at the new record to insert */ - *split_rec = NULL; - } + *split_rec = next_next_rec; + } return(TRUE); } @@ -1220,7 +1218,7 @@ btr_page_get_sure_split_rec( page = btr_cur_get_page(cursor); insert_size = rec_get_converted_size(cursor->index, tuple); - free_space = page_get_free_space_of_empty(cursor->index->table->comp); + free_space = page_get_free_space_of_empty(page_is_comp(page)); /* free_space is now the free space of a created new page */ @@ -1276,21 +1274,22 @@ btr_page_get_sure_split_rec( supremum record of page */ if (rec == ins_rec) { - next_rec = NULL; + rec = NULL; + + goto func_exit; } else if (rec == NULL) { next_rec = page_rec_get_next(ins_rec); } else { next_rec = page_rec_get_next(rec); } - if (next_rec != page_get_supremum_rec(page)) { - if (heap) { - mem_heap_free(heap); - } - return(next_rec); + ut_ad(next_rec); + if (!page_rec_is_supremum(next_rec)) { + rec = next_rec; } } - if (heap) { +func_exit: + if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } return(rec); @@ -1329,13 +1328,12 @@ btr_page_insert_fits( ut_ad(!split_rec == !offsets); ut_ad(!offsets - || cursor->index->table->comp == rec_offs_comp(offsets)); + || !page_is_comp(page) == !rec_offs_comp(offsets)); ut_ad(!offsets || rec_offs_validate(split_rec, cursor->index, offsets)); - ut_ad(page_is_comp(page) == cursor->index->table->comp); insert_size = rec_get_converted_size(cursor->index, tuple); - free_space = page_get_free_space_of_empty(cursor->index->table->comp); + free_space = page_get_free_space_of_empty(page_is_comp(page)); /* free_space is now the free space of a created new page */ @@ -1832,14 +1830,15 @@ void btr_set_min_rec_mark_log( /*=====================*/ rec_t* rec, /* in: record */ - ibool comp, /* TRUE=compact record format */ + ulint comp, /* nonzero=compact record format */ mtr_t* mtr) /* in: mtr */ { mlog_write_initial_log_record(rec, comp ? MLOG_COMP_REC_MIN_MARK : MLOG_REC_MIN_MARK, mtr); /* Write rec offset as a 2-byte ulint */ - mlog_catenate_ulint(mtr, rec - buf_frame_align(rec), MLOG_2BYTES); + mlog_catenate_ulint(mtr, ut_align_offset(rec, UNIV_PAGE_SIZE), + MLOG_2BYTES); } /******************************************************************** @@ -1852,7 +1851,7 @@ btr_parse_set_min_rec_mark( /* out: end of log record or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ - ibool comp, /* in: TRUE=compact page format */ + ulint comp, /* in: nonzero=compact page format */ page_t* page, /* in: page or NULL */ mtr_t* mtr) /* in: mtr or NULL */ { @@ -1864,6 +1863,8 @@ btr_parse_set_min_rec_mark( } if (page) { + ut_a(!page_is_comp(page) == !comp); + rec = page + mach_read_from_2(ptr); btr_set_min_rec_mark(rec, comp, mtr); @@ -1879,7 +1880,7 @@ void btr_set_min_rec_mark( /*=================*/ rec_t* rec, /* in: record */ - ibool comp, /* in: TRUE=compact page format */ + ulint comp, /* in: nonzero=compact page format */ mtr_t* mtr) /* in: mtr */ { ulint info_bits; @@ -2008,11 +2009,12 @@ btr_compress( ulint max_ins_size; ulint max_ins_size_reorg; ulint level; - ibool comp = cursor->index->table->comp; + ulint comp; page = btr_cur_get_page(cursor); tree = btr_cur_get_tree(cursor); - ut_a(comp == page_is_comp(page)); + comp = page_is_comp(page); + ut_a(!!comp == cursor->index->table->comp); ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), MTR_MEMO_X_LOCK)); @@ -2055,7 +2057,7 @@ btr_compress( n_recs = page_get_n_recs(page); data_size = page_get_data_size(page); - ut_a(page_is_comp(merge_page) == page_is_comp(page)); + ut_a(page_is_comp(merge_page) == comp); max_ins_size_reorg = page_get_max_insert_size_after_reorganize( merge_page, n_recs); @@ -2108,7 +2110,7 @@ btr_compress( rec_get_offsets(node_ptr, cursor->index, offsets_, ULINT_UNDEFINED, &heap), right_page_no, mtr); - if (heap) { + if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } btr_node_ptr_delete(tree, merge_page, mtr); @@ -2250,10 +2252,9 @@ btr_discard_page( node_ptr = page_rec_get_next(page_get_infimum_rec(merge_page)); - ut_ad(node_ptr != page_get_supremum_rec(merge_page)); + ut_ad(page_rec_is_user_rec(node_ptr)); - btr_set_min_rec_mark(node_ptr, - cursor->index->table->comp, mtr); + btr_set_min_rec_mark(node_ptr, page_is_comp(merge_page), mtr); } btr_node_ptr_delete(tree, page, mtr); @@ -2274,6 +2275,7 @@ btr_discard_page( ut_ad(btr_check_node_ptr(tree, merge_page, mtr)); } +#ifdef UNIV_BTR_PRINT /***************************************************************** Prints size info of a B-tree. */ @@ -2401,14 +2403,15 @@ btr_print_tree( root = btr_root_get(tree, &mtr); btr_print_recursive(tree, root, width, &heap, &offsets, &mtr); - if (heap) { + if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } mtr_commit(&mtr); - btr_validate_tree(tree); + btr_validate_tree(tree, NULL); } +#endif /* UNIV_BTR_PRINT */ /**************************************************************** Checks that the node pointer to a page is appropriate. */ @@ -2496,8 +2499,8 @@ btr_index_rec_validate( *offsets_ = (sizeof offsets_) / sizeof *offsets_; page = buf_frame_align(rec); - - if (index->type & DICT_UNIVERSAL) { + + if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) { /* The insert buffer index tree can contain records from any other index: we cannot check the number of fields or their length */ @@ -2505,9 +2508,18 @@ btr_index_rec_validate( return(TRUE); } + if (UNIV_UNLIKELY(!!page_is_comp(page) != index->table->comp)) { + btr_index_rec_validate_report(page, rec, index); + fprintf(stderr, "InnoDB: compact flag=%lu, should be %lu\n", + (ulong) !!page_is_comp(page), + (ulong) index->table->comp); + return(FALSE); + } + n = dict_index_get_n_fields(index); - if (!index->table->comp && rec_get_n_fields_old(rec) != n) { + if (!page_is_comp(page) + && UNIV_UNLIKELY(rec_get_n_fields_old(rec) != n)) { btr_index_rec_validate_report(page, rec, index); fprintf(stderr, "InnoDB: has %lu fields, should have %lu\n", (ulong) rec_get_n_fields_old(rec), (ulong) n); @@ -2554,14 +2566,14 @@ btr_index_rec_validate( rec_print_new(stderr, rec, offsets); putc('\n', stderr); } - if (heap) { + if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } return(FALSE); } } - if (heap) { + if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } return(TRUE); @@ -2649,6 +2661,7 @@ btr_validate_level( /*===============*/ /* out: TRUE if ok */ dict_tree_t* tree, /* in: index tree */ + trx_t* trx, /* in: transaction or NULL */ ulint level) /* in: level number */ { ulint space; @@ -2696,6 +2709,11 @@ btr_validate_level( /* Now we are on the desired level. Loop through the pages on that level. */ loop: + if (trx_is_interrupted(trx)) { + mtr_commit(&mtr); + mem_heap_free(heap); + return(ret); + } mem_heap_empty(heap); offsets = offsets2 = NULL; mtr_x_lock(dict_tree_get_lock(tree), &mtr); @@ -2765,7 +2783,7 @@ loop: if (level > 0 && left_page_no == FIL_NULL) { ut_a(REC_INFO_MIN_REC_FLAG & rec_get_info_bits( page_rec_get_next(page_get_infimum_rec(page)), - index->table->comp)); + page_is_comp(page))); } if (buf_frame_get_page_no(page) != dict_tree_get_page(tree)) { @@ -2921,7 +2939,7 @@ node_ptr_fails: mtr_commit(&mtr); if (right_page_no != FIL_NULL) { - ibool comp = page_is_comp(page); + ulint comp = page_is_comp(page); mtr_start(&mtr); page = btr_page_get(space, right_page_no, RW_X_LATCH, &mtr); @@ -2941,7 +2959,8 @@ ibool btr_validate_tree( /*==============*/ /* out: TRUE if ok */ - dict_tree_t* tree) /* in: tree */ + dict_tree_t* tree, /* in: tree */ + trx_t* trx) /* in: transaction or NULL */ { mtr_t mtr; page_t* root; @@ -2954,9 +2973,8 @@ btr_validate_tree( root = btr_root_get(tree, &mtr); n = btr_page_get_level(root, &mtr); - for (i = 0; i <= n; i++) { - - if (!btr_validate_level(tree, n - i)) { + for (i = 0; i <= n && !trx_is_interrupted(trx); i++) { + if (!btr_validate_level(tree, trx, n - i)) { mtr_commit(&mtr); |