Loading Docs/manual.texi +8 −0 Original line number Diff line number Diff line Loading @@ -45921,6 +45921,14 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.45 @itemize @bullet @item Fix a bug which could cause InnoDB to complain if it cannot find free blocks from the buffer cache during recovery. @item Fixed a bug in InnoDB insert buffer B-tree handling that could cause crashes. @item Fixed bug in @code{OPTIMIZE TABLE} that reset index cardinality if it was up to date. @item Fixed problem with @code{t1 LEFT_JOIN t2 ... WHERE t2.date_column IS NULL} when date_column was declared as @code{NOT NULL}. @item innobase/btr/btr0btr.c +13 −11 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ Created 6/2/1994 Heikki Tuuri #include "lock0lock.h" #include "ibuf0ibuf.h" /** /* Node pointers ------------- Leaf pages of a B-tree contain the index records stored in the Loading Loading @@ -550,14 +550,15 @@ btr_page_get_father_for_rec( ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), MTR_MEMO_X_LOCK)); ut_ad(user_rec != page_get_supremum_rec(page)); ut_ad(user_rec != page_get_infimum_rec(page)); ut_a(user_rec != page_get_supremum_rec(page)); ut_a(user_rec != page_get_infimum_rec(page)); ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page)); heap = mem_heap_create(100); tuple = dict_tree_build_node_ptr(tree, user_rec, 0, heap); tuple = dict_tree_build_node_ptr(tree, user_rec, 0, heap, btr_page_get_level(page, mtr)); /* In the following, we choose just any index from the tree as the first parameter for btr_cur_search_to_nth_level. */ Loading @@ -569,7 +570,7 @@ btr_page_get_father_for_rec( node_ptr = btr_cur_get_rec(&cursor); ut_ad(btr_node_ptr_get_child_page_no(node_ptr) == ut_a(btr_node_ptr_get_child_page_no(node_ptr) == buf_frame_get_page_no(page)); mem_heap_free(heap); Loading Loading @@ -949,8 +950,8 @@ btr_root_raise_and_insert( /* Build the node pointer (= node key and page address) for the child */ node_ptr = dict_tree_build_node_ptr(tree, rec, new_page_no, heap); node_ptr = dict_tree_build_node_ptr(tree, rec, new_page_no, heap, level); /* Reorganize the root to get free space */ btr_page_reorganize(root, mtr); Loading Loading @@ -1365,7 +1366,7 @@ btr_attach_half_pages( half */ node_ptr_upper = dict_tree_build_node_ptr(tree, split_rec, upper_page_no, heap); upper_page_no, heap, level); /* Insert it next to the pointer to the lower half. Note that this may generate recursion leading to a split on the higher level. */ Loading Loading @@ -2230,7 +2231,7 @@ btr_check_node_ptr( node_ptr_tuple = dict_tree_build_node_ptr( tree, page_rec_get_next(page_get_infimum_rec(page)), 0, heap); 0, heap, btr_page_get_level(page, mtr)); ut_a(cmp_dtuple_rec(node_ptr_tuple, node_ptr) == 0); Loading Loading @@ -2488,7 +2489,8 @@ btr_validate_level( tree, page_rec_get_next( page_get_infimum_rec(page)), 0, heap); 0, heap, btr_page_get_level(page, &mtr)); if (cmp_dtuple_rec(node_ptr_tuple, node_ptr) != 0) { Loading innobase/btr/btr0cur.c +3 −3 Original line number Diff line number Diff line Loading @@ -2347,7 +2347,7 @@ btr_cur_pessimistic_delete( node_ptr = dict_tree_build_node_ptr( tree, page_rec_get_next(rec), buf_frame_get_page_no(page), heap); heap, btr_page_get_level(page, mtr)); btr_insert_on_non_leaf_level(tree, btr_page_get_level(page, mtr) + 1, Loading innobase/buf/buf0flu.c +11 −6 Original line number Diff line number Diff line Loading @@ -138,15 +138,11 @@ buf_flush_ready_for_flush( return(TRUE); } else if ((block->old || (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN)) && (block->buf_fix_count == 0)) { } else if (block->buf_fix_count == 0) { /* If we are flushing the LRU list, to avoid deadlocks we require the block not to be bufferfixed, and hence not latched. Since LRU flushed blocks are soon moved to the free list, it is good to flush only old blocks from the end of the LRU list. */ not latched. */ return(TRUE); } Loading Loading @@ -560,6 +556,15 @@ buf_flush_try_neighbors( block = buf_page_hash_get(space, i); if (block && flush_type == BUF_FLUSH_LRU && i != offset && !block->old) { /* We avoid flushing 'non-old' blocks in an LRU flush, because the flushed blocks are soon freed */ continue; } if (block && buf_flush_ready_for_flush(block, flush_type)) { mutex_exit(&(buf_pool->mutex)); Loading innobase/dict/dict0dict.c +11 −2 Original line number Diff line number Diff line Loading @@ -2415,7 +2415,9 @@ dict_tree_build_node_ptr( dict_tree_t* tree, /* in: index tree */ rec_t* rec, /* in: record for which to build node pointer */ ulint page_no,/* in: page number to put in node pointer */ mem_heap_t* heap) /* in: memory heap where pointer created */ mem_heap_t* heap, /* in: memory heap where pointer created */ ulint level) /* in: level of rec in tree: 0 means leaf level */ { dtuple_t* tuple; dict_index_t* ind; Loading @@ -2427,9 +2429,16 @@ dict_tree_build_node_ptr( if (tree->type & DICT_UNIVERSAL) { /* In a universal index tree, we take the whole record as the node pointer */ the node pointer if the reord is on the leaf level, on non-leaf levels we remove the last field, which contains the page number of the child page */ n_unique = rec_get_n_fields(rec); if (level > 0) { ut_a(n_unique > 1); n_unique--; } } else { n_unique = dict_index_get_n_unique_in_tree(ind); } Loading Loading
Docs/manual.texi +8 −0 Original line number Diff line number Diff line Loading @@ -45921,6 +45921,14 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.45 @itemize @bullet @item Fix a bug which could cause InnoDB to complain if it cannot find free blocks from the buffer cache during recovery. @item Fixed a bug in InnoDB insert buffer B-tree handling that could cause crashes. @item Fixed bug in @code{OPTIMIZE TABLE} that reset index cardinality if it was up to date. @item Fixed problem with @code{t1 LEFT_JOIN t2 ... WHERE t2.date_column IS NULL} when date_column was declared as @code{NOT NULL}. @item
innobase/btr/btr0btr.c +13 −11 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ Created 6/2/1994 Heikki Tuuri #include "lock0lock.h" #include "ibuf0ibuf.h" /** /* Node pointers ------------- Leaf pages of a B-tree contain the index records stored in the Loading Loading @@ -550,14 +550,15 @@ btr_page_get_father_for_rec( ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), MTR_MEMO_X_LOCK)); ut_ad(user_rec != page_get_supremum_rec(page)); ut_ad(user_rec != page_get_infimum_rec(page)); ut_a(user_rec != page_get_supremum_rec(page)); ut_a(user_rec != page_get_infimum_rec(page)); ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page)); heap = mem_heap_create(100); tuple = dict_tree_build_node_ptr(tree, user_rec, 0, heap); tuple = dict_tree_build_node_ptr(tree, user_rec, 0, heap, btr_page_get_level(page, mtr)); /* In the following, we choose just any index from the tree as the first parameter for btr_cur_search_to_nth_level. */ Loading @@ -569,7 +570,7 @@ btr_page_get_father_for_rec( node_ptr = btr_cur_get_rec(&cursor); ut_ad(btr_node_ptr_get_child_page_no(node_ptr) == ut_a(btr_node_ptr_get_child_page_no(node_ptr) == buf_frame_get_page_no(page)); mem_heap_free(heap); Loading Loading @@ -949,8 +950,8 @@ btr_root_raise_and_insert( /* Build the node pointer (= node key and page address) for the child */ node_ptr = dict_tree_build_node_ptr(tree, rec, new_page_no, heap); node_ptr = dict_tree_build_node_ptr(tree, rec, new_page_no, heap, level); /* Reorganize the root to get free space */ btr_page_reorganize(root, mtr); Loading Loading @@ -1365,7 +1366,7 @@ btr_attach_half_pages( half */ node_ptr_upper = dict_tree_build_node_ptr(tree, split_rec, upper_page_no, heap); upper_page_no, heap, level); /* Insert it next to the pointer to the lower half. Note that this may generate recursion leading to a split on the higher level. */ Loading Loading @@ -2230,7 +2231,7 @@ btr_check_node_ptr( node_ptr_tuple = dict_tree_build_node_ptr( tree, page_rec_get_next(page_get_infimum_rec(page)), 0, heap); 0, heap, btr_page_get_level(page, mtr)); ut_a(cmp_dtuple_rec(node_ptr_tuple, node_ptr) == 0); Loading Loading @@ -2488,7 +2489,8 @@ btr_validate_level( tree, page_rec_get_next( page_get_infimum_rec(page)), 0, heap); 0, heap, btr_page_get_level(page, &mtr)); if (cmp_dtuple_rec(node_ptr_tuple, node_ptr) != 0) { Loading
innobase/btr/btr0cur.c +3 −3 Original line number Diff line number Diff line Loading @@ -2347,7 +2347,7 @@ btr_cur_pessimistic_delete( node_ptr = dict_tree_build_node_ptr( tree, page_rec_get_next(rec), buf_frame_get_page_no(page), heap); heap, btr_page_get_level(page, mtr)); btr_insert_on_non_leaf_level(tree, btr_page_get_level(page, mtr) + 1, Loading
innobase/buf/buf0flu.c +11 −6 Original line number Diff line number Diff line Loading @@ -138,15 +138,11 @@ buf_flush_ready_for_flush( return(TRUE); } else if ((block->old || (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN)) && (block->buf_fix_count == 0)) { } else if (block->buf_fix_count == 0) { /* If we are flushing the LRU list, to avoid deadlocks we require the block not to be bufferfixed, and hence not latched. Since LRU flushed blocks are soon moved to the free list, it is good to flush only old blocks from the end of the LRU list. */ not latched. */ return(TRUE); } Loading Loading @@ -560,6 +556,15 @@ buf_flush_try_neighbors( block = buf_page_hash_get(space, i); if (block && flush_type == BUF_FLUSH_LRU && i != offset && !block->old) { /* We avoid flushing 'non-old' blocks in an LRU flush, because the flushed blocks are soon freed */ continue; } if (block && buf_flush_ready_for_flush(block, flush_type)) { mutex_exit(&(buf_pool->mutex)); Loading
innobase/dict/dict0dict.c +11 −2 Original line number Diff line number Diff line Loading @@ -2415,7 +2415,9 @@ dict_tree_build_node_ptr( dict_tree_t* tree, /* in: index tree */ rec_t* rec, /* in: record for which to build node pointer */ ulint page_no,/* in: page number to put in node pointer */ mem_heap_t* heap) /* in: memory heap where pointer created */ mem_heap_t* heap, /* in: memory heap where pointer created */ ulint level) /* in: level of rec in tree: 0 means leaf level */ { dtuple_t* tuple; dict_index_t* ind; Loading @@ -2427,9 +2429,16 @@ dict_tree_build_node_ptr( if (tree->type & DICT_UNIVERSAL) { /* In a universal index tree, we take the whole record as the node pointer */ the node pointer if the reord is on the leaf level, on non-leaf levels we remove the last field, which contains the page number of the child page */ n_unique = rec_get_n_fields(rec); if (level > 0) { ut_a(n_unique > 1); n_unique--; } } else { n_unique = dict_index_get_n_unique_in_tree(ind); } Loading