#include "univ.i"#include "dict0dict.h"#include "data0data.h"#include "page0cur.h"#include "rem0rec.h"#include "mtr0mtr.h"#include "btr0types.h"Include dependency graph for btr0btr.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
| #define BTR_CONT_MODIFY_TREE 34 |
Definition at line 31 of file btr0btr.h.
Referenced by btr_cur_open_at_index_side(), btr_cur_search_to_nth_level(), btr_insert_on_non_leaf_level(), and btr_page_get_father_for_rec().
| #define BTR_ESTIMATE 1024 |
Definition at line 41 of file btr0btr.h.
Referenced by btr_cur_open_at_index_side(), btr_cur_search_to_nth_level(), and btr_estimate_n_rows_in_range().
| #define BTR_IGNORE_SEC_UNIQUE 2048 |
Definition at line 46 of file btr0btr.h.
Referenced by btr_cur_search_to_nth_level(), and row_ins_index_entry_low().
| #define BTR_INSERT 512 |
Definition at line 37 of file btr0btr.h.
Referenced by btr_cur_search_to_nth_level(), and row_ins_index_entry_low().
| #define BTR_MODIFY_LEAF RW_X_LATCH |
Definition at line 28 of file btr0btr.h.
Referenced by btr_cur_latch_leaves(), btr_cur_search_to_nth_level(), btr_pcur_move_backward_from_page(), btr_pcur_restore_position(), btr_search_guess_on_hash(), dict_create_index_tree_step(), ibuf_delete_for_discarded_space(), ibuf_merge_or_delete_for_page(), pars_update_statement(), row_ins_clust_index_entry_by_modify(), row_ins_index_entry(), row_ins_index_entry_low(), row_ins_sec_index_entry_by_modify(), row_purge_remove_clust_if_poss(), row_purge_remove_clust_if_poss_low(), row_purge_remove_sec_if_poss(), row_purge_remove_sec_if_poss_low(), row_truncate_table_for_mysql(), row_undo_ins_remove_clust_rec(), row_undo_ins_remove_sec(), row_undo_ins_remove_sec_low(), row_undo_mod_clust(), row_undo_mod_clust_low(), row_undo_mod_del_mark_or_remove_sec(), row_undo_mod_del_mark_or_remove_sec_low(), row_undo_mod_del_mark_sec(), row_undo_mod_del_unmark_sec_and_undo_update(), row_undo_mod_remove_clust_low(), row_undo_mod_upd_exist_sec(), row_undo_search_clust_to_pcur(), row_upd_clust_step(), row_upd_in_place_in_select(), and row_upd_sec_index_entry().
| #define BTR_MODIFY_PREV 36 |
Definition at line 33 of file btr0btr.h.
Referenced by btr_cur_latch_leaves(), btr_pcur_move_backward_from_page(), ibuf_get_volume_buffered(), ibuf_insert(), and ibuf_insert_low().
| #define BTR_MODIFY_TREE 33 |
Definition at line 30 of file btr0btr.h.
Referenced by btr_cur_latch_leaves(), btr_cur_open_at_index_side(), btr_cur_open_at_rnd_pos(), btr_cur_search_to_nth_level(), ibuf_delete_rec(), ibuf_get_volume_buffered(), ibuf_insert(), ibuf_insert_low(), row_ins_clust_index_entry_by_modify(), row_ins_index_entry(), row_ins_index_entry_low(), row_ins_sec_index_entry_by_modify(), row_purge_remove_clust_if_poss(), row_purge_remove_clust_if_poss_low(), row_purge_remove_sec_if_poss(), row_purge_remove_sec_if_poss_low(), row_undo_ins_remove_clust_rec(), row_undo_ins_remove_sec(), row_undo_ins_remove_sec_low(), row_undo_mod_clust(), row_undo_mod_clust_low(), row_undo_mod_del_mark_or_remove_sec(), row_undo_mod_del_mark_or_remove_sec_low(), row_undo_mod_del_mark_sec(), row_undo_mod_del_unmark_sec_and_undo_update(), row_undo_mod_remove_clust_low(), row_undo_mod_upd_exist_sec(), and row_upd_clust_rec().
| #define BTR_N_LEAF_PAGES 1 |
Definition at line 434 of file btr0btr.h.
Referenced by btr_get_size(), and dict_update_statistics_low().
| #define BTR_NO_LATCHES RW_NO_LATCH |
Definition at line 29 of file btr0btr.h.
Referenced by btr_pcur_free_for_mysql(), btr_pcur_move_backward_from_page(), btr_pcur_move_to_next_page(), btr_pcur_move_to_prev(), btr_pcur_release_leaf(), btr_pcur_store_position(), and row_upd_store_row().
| #define BTR_PAGE_MAX_REC_SIZE (UNIV_PAGE_SIZE / 2 - 200) |
Definition at line 24 of file btr0btr.h.
Referenced by btr_create(), and dict_build_table_def_step().
| #define BTR_SEARCH_LEAF RW_S_LATCH |
Definition at line 27 of file btr0btr.h.
Referenced by btr_cur_latch_leaves(), btr_estimate_n_rows_in_range(), btr_estimate_number_of_different_key_vals(), btr_pcur_move_backward_from_page(), btr_pcur_restore_position(), btr_search_guess_on_hash(), dict_check_tablespaces_and_store_max_id(), dict_get_first_table_name_in_db(), dict_load_columns(), dict_load_fields(), dict_load_foreign(), dict_load_foreign_cols(), dict_load_foreigns(), dict_load_indexes(), dict_load_table(), dict_load_table_on_id(), dict_print(), ibuf_update_max_tablespace_id(), row_ins_foreign_check_on_constraint(), row_ins_scan_sec_index_for_duplicate(), row_purge_remove_sec_if_poss_low(), row_search_for_mysql(), row_sel_get_clust_rec_for_mysql(), row_sel_try_search_shortcut_for_mysql(), row_undo_mod_del_mark_or_remove_sec_low(), row_unlock_for_mysql(), row_vers_impl_x_locked_off_kernel(), and sel_node_create().
| #define BTR_SEARCH_PREV 35 |
Definition at line 32 of file btr0btr.h.
Referenced by btr_cur_latch_leaves(), and btr_pcur_move_backward_from_page().
| #define BTR_TOTAL_SIZE 2 |
Definition at line 435 of file btr0btr.h.
Referenced by btr_get_size(), and dict_update_statistics_low().
Definition at line 2003 of file btr0btr.c.
References btr_cur_get_page(), btr_cur_get_tree(), btr_level_list_remove(), btr_lift_page_up(), btr_node_ptr_delete(), btr_node_ptr_set_child_page_no(), btr_page_free(), btr_page_get(), btr_page_get_father_node_ptr(), btr_page_get_level(), btr_page_get_next(), btr_page_get_prev(), btr_page_reorganize(), btr_search_drop_page_hash_index(), buf_block_align(), buf_frame_align(), buf_frame_get_page_no(), dict_table_is_comp(), dict_tree_get_lock(), dict_tree_get_space(), FIL_NULL, ibuf_update_free_bits_if_full(), btr_cur_struct::index, lock_update_merge_left(), lock_update_merge_right(), mem_heap_free, mtr_memo_contains(), MTR_MEMO_PAGE_X_FIX, MTR_MEMO_X_LOCK, NULL, page, page_copy_rec_list_end(), page_copy_rec_list_start(), page_get_data_size(), page_get_infimum_rec(), page_get_max_insert_size(), page_get_max_insert_size_after_reorganize(), page_get_n_recs(), page_get_supremum_rec(), page_is_comp(), page_rec_get_next(), page_rec_get_prev(), page_t, page_validate(), rec_get_offsets, rec_get_status(), REC_OFFS_NORMAL_SIZE, REC_STATUS_NODE_PTR, RW_X_LATCH, dict_index_struct::table, UNIV_PAGE_SIZE, ut_a, and ut_ad.
Referenced by btr_cur_compress(), and btr_cur_compress_if_useful().
02005 : cursor on the page to merge or lift; 02006 the page must not be empty: in record delete 02007 use btr_discard_page if the page would become 02008 empty */ 02009 mtr_t* mtr) /* in: mtr */ 02010 { 02011 dict_tree_t* tree; 02012 ulint space; 02013 ulint left_page_no; 02014 ulint right_page_no; 02015 page_t* merge_page; 02016 page_t* father_page; 02017 ibool is_left; 02018 page_t* page; 02019 rec_t* orig_pred; 02020 rec_t* orig_succ; 02021 rec_t* node_ptr; 02022 ulint data_size; 02023 ulint n_recs; 02024 ulint max_ins_size; 02025 ulint max_ins_size_reorg; 02026 ulint level; 02027 ulint comp; 02028 02029 page = btr_cur_get_page(cursor); 02030 tree = btr_cur_get_tree(cursor); 02031 comp = page_is_comp(page); 02032 ut_a((ibool)!!comp == dict_table_is_comp(cursor->index->table)); 02033 02034 ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), 02035 MTR_MEMO_X_LOCK)); 02036 ut_ad(mtr_memo_contains(mtr, buf_block_align(page), 02037 MTR_MEMO_PAGE_X_FIX)); 02038 level = btr_page_get_level(page, mtr); 02039 space = dict_tree_get_space(tree); 02040 02041 left_page_no = btr_page_get_prev(page, mtr); 02042 right_page_no = btr_page_get_next(page, mtr); 02043 02044 /* fprintf(stderr, "Merge left page %lu right %lu \n", left_page_no, 02045 right_page_no); */ 02046 02047 node_ptr = btr_page_get_father_node_ptr(tree, page, mtr); 02048 ut_ad(!comp || rec_get_status(node_ptr) == REC_STATUS_NODE_PTR); 02049 father_page = buf_frame_align(node_ptr); 02050 ut_a(comp == page_is_comp(father_page)); 02051 02052 /* Decide the page to which we try to merge and which will inherit 02053 the locks */ 02054 02055 is_left = left_page_no != FIL_NULL; 02056 02057 if (is_left) { 02058 02059 merge_page = btr_page_get(space, left_page_no, RW_X_LATCH, 02060 mtr); 02061 #ifdef UNIV_BTR_DEBUG 02062 ut_a(btr_page_get_next(merge_page, mtr) 02063 == buf_frame_get_page_no(page)); 02064 #endif /* UNIV_BTR_DEBUG */ 02065 } else if (right_page_no != FIL_NULL) { 02066 02067 merge_page = btr_page_get(space, right_page_no, RW_X_LATCH, 02068 mtr); 02069 #ifdef UNIV_BTR_DEBUG 02070 ut_a(btr_page_get_prev(merge_page, mtr) 02071 == buf_frame_get_page_no(page)); 02072 #endif /* UNIV_BTR_DEBUG */ 02073 } else { 02074 /* The page is the only one on the level, lift the records 02075 to the father */ 02076 btr_lift_page_up(tree, page, mtr); 02077 02078 return; 02079 } 02080 02081 n_recs = page_get_n_recs(page); 02082 data_size = page_get_data_size(page); 02083 ut_a(page_is_comp(merge_page) == comp); 02084 02085 max_ins_size_reorg = page_get_max_insert_size_after_reorganize( 02086 merge_page, n_recs); 02087 if (data_size > max_ins_size_reorg) { 02088 02089 /* No space for merge */ 02090 02091 return; 02092 } 02093 02094 ut_ad(page_validate(merge_page, cursor->index)); 02095 02096 max_ins_size = page_get_max_insert_size(merge_page, n_recs); 02097 02098 if (data_size > max_ins_size) { 02099 02100 /* We have to reorganize merge_page */ 02101 02102 btr_page_reorganize(merge_page, cursor->index, mtr); 02103 02104 max_ins_size = page_get_max_insert_size(merge_page, n_recs); 02105 02106 ut_ad(page_validate(merge_page, cursor->index)); 02107 ut_ad(page_get_max_insert_size(merge_page, n_recs) 02108 == max_ins_size_reorg); 02109 } 02110 02111 if (data_size > max_ins_size) { 02112 02113 /* Add fault tolerance, though this should never happen */ 02114 02115 return; 02116 } 02117 02118 btr_search_drop_page_hash_index(page); 02119 02120 /* Remove the page from the level list */ 02121 btr_level_list_remove(tree, page, mtr); 02122 02123 if (is_left) { 02124 btr_node_ptr_delete(tree, page, mtr); 02125 } else { 02126 mem_heap_t* heap = NULL; 02127 ulint offsets_[REC_OFFS_NORMAL_SIZE]; 02128 *offsets_ = (sizeof offsets_) / sizeof *offsets_; 02129 /* Replace the address of the old child node (= page) with the 02130 address of the merge page to the right */ 02131 02132 btr_node_ptr_set_child_page_no(node_ptr, 02133 rec_get_offsets(node_ptr, cursor->index, 02134 offsets_, ULINT_UNDEFINED, &heap), 02135 right_page_no, mtr); 02136 if (UNIV_LIKELY_NULL(heap)) { 02137 mem_heap_free(heap); 02138 } 02139 btr_node_ptr_delete(tree, merge_page, mtr); 02140 } 02141 02142 /* Move records to the merge page */ 02143 if (is_left) { 02144 orig_pred = page_rec_get_prev( 02145 page_get_supremum_rec(merge_page)); 02146 page_copy_rec_list_start(merge_page, page, 02147 page_get_supremum_rec(page), cursor->index, mtr); 02148 02149 lock_update_merge_left(merge_page, orig_pred, page); 02150 } else { 02151 orig_succ = page_rec_get_next( 02152 page_get_infimum_rec(merge_page)); 02153 page_copy_rec_list_end(merge_page, page, 02154 page_get_infimum_rec(page), cursor->index, mtr); 02155 02156 lock_update_merge_right(orig_succ, page); 02157 } 02158 02159 /* We have added new records to merge_page: update its free bits */ 02160 ibuf_update_free_bits_if_full(cursor->index, merge_page, 02161 UNIV_PAGE_SIZE, ULINT_UNDEFINED); 02162 02163 ut_ad(page_validate(merge_page, cursor->index)); 02164 02165 /* Free the file page */ 02166 btr_page_free(tree, page, mtr); 02167 02168 ut_ad(btr_check_node_ptr(tree, merge_page, mtr)); 02169 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 659 of file btr0btr.c.
References BTR_PAGE_MAX_REC_SIZE, buf_block_align(), buf_frame_get_page_no(), buf_page_get, buf_block_struct::check_index_page_at_flush, DICT_IBUF, FIL_NULL, flst_init(), fseg_alloc_free_page(), fseg_create(), FSP_UP, IBUF_HEADER, IBUF_HEADER_PAGE_NO, ibuf_reset_free_bits_with_type(), IBUF_TREE_ROOT_PAGE_NO, IBUF_TREE_SEG_HEADER, NULL, page, PAGE_BTR_IBUF_FREE_LIST, PAGE_BTR_SEG_LEAF, PAGE_BTR_SEG_TOP, page_create(), page_get_max_insert_size(), PAGE_HEADER, page_t, RW_X_LATCH, SYNC_TREE_NODE_NEW, TRUE, and ut_ad.
Referenced by dict_create_index_tree_step(), dict_hdr_create(), dict_truncate_index_tree(), and fsp_header_init().
00661 : page number of the created root, FIL_NULL if 00662 did not succeed */ 00663 ulint type, /* in: type of the index */ 00664 ulint space, /* in: space where created */ 00665 dulint index_id,/* in: index id */ 00666 ulint comp, /* in: nonzero=compact page format */ 00667 mtr_t* mtr) /* in: mini-transaction handle */ 00668 { 00669 ulint page_no; 00670 buf_frame_t* ibuf_hdr_frame; 00671 buf_frame_t* frame; 00672 page_t* page; 00673 00674 /* Create the two new segments (one, in the case of an ibuf tree) for 00675 the index tree; the segment headers are put on the allocated root page 00676 (for an ibuf tree, not in the root, but on a separate ibuf header 00677 page) */ 00678 00679 if (type & DICT_IBUF) { 00680 /* Allocate first the ibuf header page */ 00681 ibuf_hdr_frame = fseg_create(space, 0, 00682 IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr); 00683 00684 #ifdef UNIV_SYNC_DEBUG 00685 buf_page_dbg_add_level(ibuf_hdr_frame, SYNC_TREE_NODE_NEW); 00686 #endif /* UNIV_SYNC_DEBUG */ 00687 ut_ad(buf_frame_get_page_no(ibuf_hdr_frame) 00688 == IBUF_HEADER_PAGE_NO); 00689 /* Allocate then the next page to the segment: it will be the 00690 tree root page */ 00691 00692 page_no = fseg_alloc_free_page( 00693 ibuf_hdr_frame + IBUF_HEADER 00694 + IBUF_TREE_SEG_HEADER, IBUF_TREE_ROOT_PAGE_NO, 00695 FSP_UP, mtr); 00696 ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO); 00697 00698 frame = buf_page_get(space, page_no, RW_X_LATCH, mtr); 00699 } else { 00700 frame = fseg_create(space, 0, PAGE_HEADER + PAGE_BTR_SEG_TOP, 00701 mtr); 00702 } 00703 00704 if (frame == NULL) { 00705 00706 return(FIL_NULL); 00707 } 00708 00709 page_no = buf_frame_get_page_no(frame); 00710 00711 #ifdef UNIV_SYNC_DEBUG 00712 buf_page_dbg_add_level(frame, SYNC_TREE_NODE_NEW); 00713 #endif /* UNIV_SYNC_DEBUG */ 00714 00715 if (type & DICT_IBUF) { 00716 /* It is an insert buffer tree: initialize the free list */ 00717 00718 ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO); 00719 00720 flst_init(frame + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, mtr); 00721 } else { 00722 /* It is a non-ibuf tree: create a file segment for leaf 00723 pages */ 00724 fseg_create(space, page_no, PAGE_HEADER + PAGE_BTR_SEG_LEAF, 00725 mtr); 00726 /* The fseg create acquires a second latch on the page, 00727 therefore we must declare it: */ 00728 #ifdef UNIV_SYNC_DEBUG 00729 buf_page_dbg_add_level(frame, SYNC_TREE_NODE_NEW); 00730 #endif /* UNIV_SYNC_DEBUG */ 00731 } 00732 00733 /* Create a new index page on the the allocated segment page */ 00734 page = page_create(frame, mtr, comp); 00735 buf_block_align(page)->check_index_page_at_flush = TRUE; 00736 00737 /* Set the index id of the page */ 00738 btr_page_set_index_id(page, index_id, mtr); 00739 00740 /* Set the level of the new index page */ 00741 btr_page_set_level(page, 0, mtr); 00742 00743 /* Set the next node and previous node fields */ 00744 btr_page_set_next(page, FIL_NULL, mtr); 00745 btr_page_set_prev(page, FIL_NULL, mtr); 00746 00747 /* We reset the free bits for the page to allow creation of several 00748 trees in the same mtr, otherwise the latch on a bitmap page would 00749 prevent it because of the latching order */ 00750 00751 ibuf_reset_free_bits_with_type(type, page); 00752 00753 /* In the following assertion we test that two records of maximum 00754 allowed size fit on the root page: this fact is needed to ensure 00755 correctness of split algorithms */ 00756 00757 ut_ad(page_get_max_insert_size(page, 2) > 2 * BTR_PAGE_MAX_REC_SIZE); 00758 00759 return(page_no); 00760 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2223 of file btr0btr.c.
References btr_cur_get_page(), btr_cur_get_tree(), btr_discard_only_page_on_level(), btr_level_list_remove(), btr_node_ptr_delete(), btr_page_free(), btr_page_get(), btr_page_get_level(), btr_page_get_next(), btr_page_get_prev(), btr_search_drop_page_hash_index(), btr_set_min_rec_mark(), buf_block_align(), buf_frame_get_page_no(), dict_tree_get_lock(), dict_tree_get_page(), dict_tree_get_space(), FIL_NULL, lock_update_discard(), mtr_memo_contains(), MTR_MEMO_PAGE_X_FIX, MTR_MEMO_X_LOCK, page, page_get_infimum_rec(), page_get_supremum_rec(), page_is_comp(), page_rec_get_next(), page_rec_is_user_rec(), page_t, RW_X_LATCH, ut_a, and ut_ad.
Referenced by btr_cur_pessimistic_delete().
02225 : cursor on the page to discard: not on 02226 the root page */ 02227 mtr_t* mtr) /* in: mtr */ 02228 { 02229 dict_tree_t* tree; 02230 ulint space; 02231 ulint left_page_no; 02232 ulint right_page_no; 02233 page_t* merge_page; 02234 page_t* page; 02235 rec_t* node_ptr; 02236 02237 page = btr_cur_get_page(cursor); 02238 tree = btr_cur_get_tree(cursor); 02239 02240 ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page)); 02241 ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), 02242 MTR_MEMO_X_LOCK)); 02243 ut_ad(mtr_memo_contains(mtr, buf_block_align(page), 02244 MTR_MEMO_PAGE_X_FIX)); 02245 space = dict_tree_get_space(tree); 02246 02247 /* Decide the page which will inherit the locks */ 02248 02249 left_page_no = btr_page_get_prev(page, mtr); 02250 right_page_no = btr_page_get_next(page, mtr); 02251 02252 if (left_page_no != FIL_NULL) { 02253 merge_page = btr_page_get(space, left_page_no, RW_X_LATCH, 02254 mtr); 02255 #ifdef UNIV_BTR_DEBUG 02256 ut_a(btr_page_get_next(merge_page, mtr) 02257 == buf_frame_get_page_no(page)); 02258 #endif /* UNIV_BTR_DEBUG */ 02259 } else if (right_page_no != FIL_NULL) { 02260 merge_page = btr_page_get(space, right_page_no, RW_X_LATCH, 02261 mtr); 02262 #ifdef UNIV_BTR_DEBUG 02263 ut_a(btr_page_get_prev(merge_page, mtr) 02264 == buf_frame_get_page_no(page)); 02265 #endif /* UNIV_BTR_DEBUG */ 02266 } else { 02267 btr_discard_only_page_on_level(tree, page, mtr); 02268 02269 return; 02270 } 02271 02272 ut_a(page_is_comp(merge_page) == page_is_comp(page)); 02273 btr_search_drop_page_hash_index(page); 02274 02275 if (left_page_no == FIL_NULL && btr_page_get_level(page, mtr) > 0) { 02276 02277 /* We have to mark the leftmost node pointer on the right 02278 side page as the predefined minimum record */ 02279 02280 node_ptr = page_rec_get_next(page_get_infimum_rec(merge_page)); 02281 02282 ut_ad(page_rec_is_user_rec(node_ptr)); 02283 02284 btr_set_min_rec_mark(node_ptr, page_is_comp(merge_page), mtr); 02285 } 02286 02287 btr_node_ptr_delete(tree, page, mtr); 02288 02289 /* Remove the page from the level list */ 02290 btr_level_list_remove(tree, page, mtr); 02291 02292 if (left_page_no != FIL_NULL) { 02293 lock_update_discard(page_get_supremum_rec(merge_page), page); 02294 } else { 02295 lock_update_discard(page_rec_get_next( 02296 page_get_infimum_rec(merge_page)), page); 02297 } 02298 02299 /* Free the file page */ 02300 btr_page_free(tree, page, mtr); 02301 02302 ut_ad(btr_check_node_ptr(tree, merge_page, mtr)); 02303 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 767 of file btr0btr.c.
References btr_page_get(), yaSSL::finished, fseg_free_step(), fseg_free_step_not_header(), mtr_commit(), mtr_start(), PAGE_BTR_SEG_LEAF, PAGE_BTR_SEG_TOP, PAGE_HEADER, page_t, and RW_X_LATCH.
Referenced by dict_drop_index_tree(), and dict_truncate_index_tree().
00769 : space where created */ 00770 ulint root_page_no) /* in: root page number */ 00771 { 00772 ibool finished; 00773 page_t* root; 00774 mtr_t mtr; 00775 00776 leaf_loop: 00777 mtr_start(&mtr); 00778 00779 root = btr_page_get(space, root_page_no, RW_X_LATCH, &mtr); 00780 00781 /* NOTE: page hash indexes are dropped when a page is freed inside 00782 fsp0fsp. */ 00783 00784 finished = fseg_free_step( 00785 root + PAGE_HEADER + PAGE_BTR_SEG_LEAF, &mtr); 00786 mtr_commit(&mtr); 00787 00788 if (!finished) { 00789 00790 goto leaf_loop; 00791 } 00792 top_loop: 00793 mtr_start(&mtr); 00794 00795 root = btr_page_get(space, root_page_no, RW_X_LATCH, &mtr); 00796 00797 finished = fseg_free_step_not_header( 00798 root + PAGE_HEADER + PAGE_BTR_SEG_TOP, &mtr); 00799 mtr_commit(&mtr); 00800 00801 if (!finished) { 00802 00803 goto top_loop; 00804 } 00805 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 811 of file btr0btr.c.
References btr_page_get(), btr_search_drop_page_hash_index(), yaSSL::finished, fseg_free_step(), PAGE_BTR_SEG_TOP, PAGE_HEADER, page_t, and RW_X_LATCH.
Referenced by dict_drop_index_tree(), and dict_truncate_index_tree().
00813 : space where created */ 00814 ulint root_page_no, /* in: root page number */ 00815 mtr_t* mtr) /* in: a mini-transaction which has already 00816 been started */ 00817 { 00818 ibool finished; 00819 page_t* root; 00820 00821 root = btr_page_get(space, root_page_no, RW_X_LATCH, mtr); 00822 00823 btr_search_drop_page_hash_index(root); 00824 top_loop: 00825 finished = fseg_free_step( 00826 root + PAGE_HEADER + PAGE_BTR_SEG_TOP, mtr); 00827 if (!finished) { 00828 00829 goto top_loop; 00830 } 00831 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 209 of file btr0btr.c.
References btr_page_get_next(), btr_page_get_prev(), buf_block_align(), buf_frame_align(), buf_frame_get_page_no(), buf_frame_get_space_id(), buf_page_get_with_no_latch, FIL_NULL, mtr_memo_contains(), MTR_MEMO_PAGE_S_FIX, MTR_MEMO_PAGE_X_FIX, NULL, page, page_get_infimum_rec(), page_is_comp(), page_rec_get_next(), page_rec_is_supremum(), page_t, ut_a, and ut_ad.
00211 : next user record, NULL if there is none */ 00212 rec_t* rec, /* in: record on leaf level */ 00213 mtr_t* mtr) /* in: mtr holding a latch on the page, and if 00214 needed, also to the next page */ 00215 { 00216 page_t* page; 00217 page_t* next_page; 00218 ulint next_page_no; 00219 ulint space; 00220 00221 if (!page_rec_is_supremum(rec)) { 00222 00223 rec_t* next_rec = page_rec_get_next(rec); 00224 00225 if (!page_rec_is_supremum(next_rec)) { 00226 00227 return(next_rec); 00228 } 00229 } 00230 00231 page = buf_frame_align(rec); 00232 next_page_no = btr_page_get_next(page, mtr); 00233 space = buf_frame_get_space_id(page); 00234 00235 if (next_page_no != FIL_NULL) { 00236 00237 next_page = buf_page_get_with_no_latch(space, next_page_no, 00238 mtr); 00239 /* The caller must already have a latch to the brother */ 00240 ut_ad((mtr_memo_contains(mtr, buf_block_align(next_page), 00241 MTR_MEMO_PAGE_S_FIX)) 00242 || (mtr_memo_contains(mtr, buf_block_align(next_page), 00243 MTR_MEMO_PAGE_X_FIX))); 00244 #ifdef UNIV_BTR_DEBUG 00245 ut_a(btr_page_get_prev(next_page, mtr) 00246 == buf_frame_get_page_no(page)); 00247 #endif /* UNIV_BTR_DEBUG */ 00248 00249 ut_a(page_is_comp(next_page) == page_is_comp(page)); 00250 return(page_rec_get_next(page_get_infimum_rec(next_page))); 00251 } 00252 00253 return(NULL); 00254 }
Here is the call graph for this function:

Definition at line 157 of file btr0btr.c.
References btr_page_get_next(), btr_page_get_prev(), buf_block_align(), buf_frame_align(), buf_frame_get_page_no(), buf_frame_get_space_id(), buf_page_get_with_no_latch, FIL_NULL, mtr_memo_contains(), MTR_MEMO_PAGE_S_FIX, MTR_MEMO_PAGE_X_FIX, NULL, page, page_get_supremum_rec(), page_is_comp(), page_rec_get_prev(), page_rec_is_infimum(), page_t, ut_a, and ut_ad.
00159 : previous user record, NULL if there is none */ 00160 rec_t* rec, /* in: record on leaf level */ 00161 mtr_t* mtr) /* in: mtr holding a latch on the page, and if 00162 needed, also to the previous page */ 00163 { 00164 page_t* page; 00165 page_t* prev_page; 00166 ulint prev_page_no; 00167 ulint space; 00168 00169 if (!page_rec_is_infimum(rec)) { 00170 00171 rec_t* prev_rec = page_rec_get_prev(rec); 00172 00173 if (!page_rec_is_infimum(prev_rec)) { 00174 00175 return(prev_rec); 00176 } 00177 } 00178 00179 page = buf_frame_align(rec); 00180 prev_page_no = btr_page_get_prev(page, mtr); 00181 space = buf_frame_get_space_id(page); 00182 00183 if (prev_page_no != FIL_NULL) { 00184 00185 prev_page = buf_page_get_with_no_latch(space, prev_page_no, 00186 mtr); 00187 /* The caller must already have a latch to the brother */ 00188 ut_ad((mtr_memo_contains(mtr, buf_block_align(prev_page), 00189 MTR_MEMO_PAGE_S_FIX)) 00190 || (mtr_memo_contains(mtr, buf_block_align(prev_page), 00191 MTR_MEMO_PAGE_X_FIX))); 00192 ut_a(page_is_comp(prev_page) == page_is_comp(page)); 00193 #ifdef UNIV_BTR_DEBUG 00194 ut_a(btr_page_get_next(prev_page, mtr) 00195 == buf_frame_get_page_no(page)); 00196 #endif /* UNIV_BTR_DEBUG */ 00197 00198 return(page_rec_get_prev(page_get_supremum_rec(prev_page))); 00199 } 00200 00201 return(NULL); 00202 }
Here is the call graph for this function:

| ulint btr_get_size | ( | dict_index_t * | index, | |
| ulint | flag | |||
| ) |
Definition at line 370 of file btr0btr.c.
References BTR_N_LEAF_PAGES, btr_root_get(), BTR_TOTAL_SIZE, dict_tree_get_lock(), fseg_n_reserved_pages(), index(), mtr_commit(), mtr_s_lock, mtr_start(), n, PAGE_BTR_SEG_LEAF, PAGE_BTR_SEG_TOP, PAGE_HEADER, page_t, and ut_error.
Referenced by dict_update_statistics_low().
00372 : number of pages */ 00373 dict_index_t* index, /* in: index */ 00374 ulint flag) /* in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */ 00375 { 00376 fseg_header_t* seg_header; 00377 page_t* root; 00378 ulint n; 00379 ulint dummy; 00380 mtr_t mtr; 00381 00382 mtr_start(&mtr); 00383 00384 mtr_s_lock(dict_tree_get_lock(index->tree), &mtr); 00385 00386 root = btr_root_get(index->tree, &mtr); 00387 00388 if (flag == BTR_N_LEAF_PAGES) { 00389 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF; 00390 00391 fseg_n_reserved_pages(seg_header, &n, &mtr); 00392 00393 } else if (flag == BTR_TOTAL_SIZE) { 00394 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP; 00395 00396 n = fseg_n_reserved_pages(seg_header, &dummy, &mtr); 00397 00398 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF; 00399 00400 n += fseg_n_reserved_pages(seg_header, &dummy, &mtr); 00401 } else { 00402 ut_error; 00403 } 00404 00405 mtr_commit(&mtr); 00406 00407 return(n); 00408 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool btr_index_rec_validate | ( | rec_t * | rec, | |
| dict_index_t * | index, | |||
| ibool | dump_on_error | |||
| ) |
Definition at line 2512 of file btr0btr.c.
References btr_index_rec_validate_report(), buf_frame_align(), buf_page_print(), dict_index_get_n_fields(), dict_index_get_nth_field(), dict_index_get_nth_type(), dict_table_is_comp(), DICT_UNIVERSAL, dtype_get_fixed_size(), FALSE, index(), mem_heap_free, n, NULL, page_is_comp(), page_t, rec_get_n_fields_old(), rec_get_nth_field(), rec_get_offsets, REC_OFFS_NORMAL_SIZE, rec_print_new(), rec_print_old(), and TRUE.
Referenced by btr_index_page_validate(), and row_search_for_mysql().
02514 : TRUE if ok */ 02515 rec_t* rec, /* in: index record */ 02516 dict_index_t* index, /* in: index */ 02517 ibool dump_on_error) /* in: TRUE if the function 02518 should print hex dump of record 02519 and page on error */ 02520 { 02521 ulint len; 02522 ulint n; 02523 ulint i; 02524 page_t* page; 02525 mem_heap_t* heap = NULL; 02526 ulint offsets_[REC_OFFS_NORMAL_SIZE]; 02527 ulint* offsets = offsets_; 02528 *offsets_ = (sizeof offsets_) / sizeof *offsets_; 02529 02530 page = buf_frame_align(rec); 02531 02532 if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) { 02533 /* The insert buffer index tree can contain records from any 02534 other index: we cannot check the number of fields or 02535 their length */ 02536 02537 return(TRUE); 02538 } 02539 02540 if (UNIV_UNLIKELY((ibool)!!page_is_comp(page) 02541 != dict_table_is_comp(index->table))) { 02542 btr_index_rec_validate_report(page, rec, index); 02543 fprintf(stderr, "InnoDB: compact flag=%lu, should be %lu\n", 02544 (ulong) !!page_is_comp(page), 02545 (ulong) dict_table_is_comp(index->table)); 02546 02547 return(FALSE); 02548 } 02549 02550 n = dict_index_get_n_fields(index); 02551 02552 if (!page_is_comp(page) 02553 && UNIV_UNLIKELY(rec_get_n_fields_old(rec) != n)) { 02554 btr_index_rec_validate_report(page, rec, index); 02555 fprintf(stderr, "InnoDB: has %lu fields, should have %lu\n", 02556 (ulong) rec_get_n_fields_old(rec), (ulong) n); 02557 02558 if (dump_on_error) { 02559 buf_page_print(page); 02560 02561 fputs("InnoDB: corrupt record ", stderr); 02562 rec_print_old(stderr, rec); 02563 putc('\n', stderr); 02564 } 02565 return(FALSE); 02566 } 02567 02568 offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); 02569 02570 for (i = 0; i < n; i++) { 02571 dtype_t* type = dict_index_get_nth_type(index, i); 02572 ulint fixed_size = dtype_get_fixed_size(type); 02573 02574 rec_get_nth_field(rec, offsets, i, &len); 02575 02576 /* Note that prefix indexes are not fixed size even when 02577 their type is CHAR. */ 02578 02579 if ((dict_index_get_nth_field(index, i)->prefix_len == 0 02580 && len != UNIV_SQL_NULL && fixed_size 02581 && len != fixed_size) 02582 || 02583 (dict_index_get_nth_field(index, i)->prefix_len > 0 02584 && len != UNIV_SQL_NULL 02585 && len > 02586 dict_index_get_nth_field(index, i)->prefix_len)) { 02587 02588 btr_index_rec_validate_report(page, rec, index); 02589 fprintf(stderr, 02590 "InnoDB: field %lu len is %lu, should be %lu\n", 02591 (ulong) i, (ulong) len, (ulong) dtype_get_fixed_size(type)); 02592 02593 if (dump_on_error) { 02594 buf_page_print(page); 02595 02596 fputs("InnoDB: corrupt record ", stderr); 02597 rec_print_new(stderr, rec, offsets); 02598 putc('\n', stderr); 02599 } 02600 if (UNIV_LIKELY_NULL(heap)) { 02601 mem_heap_free(heap); 02602 } 02603 return(FALSE); 02604 } 02605 } 02606 02607 if (UNIV_LIKELY_NULL(heap)) { 02608 mem_heap_free(heap); 02609 } 02610 return(TRUE); 02611 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void btr_insert_on_non_leaf_level | ( | dict_tree_t * | tree, | |
| ulint | level, | |||
| dtuple_t * | tuple, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 1408 of file btr0btr.c.
References BTR_CONT_MODIFY_TREE, btr_cur_pessimistic_insert(), btr_cur_search_to_nth_level(), BTR_KEEP_SYS_FLAG, BTR_NO_LOCKING_FLAG, BTR_NO_UNDO_LOG_FLAG, DB_SUCCESS, err, NULL, PAGE_CUR_LE, dict_tree_struct::tree_index, ut_a, and ut_ad.
Referenced by btr_attach_half_pages(), and btr_cur_pessimistic_delete().
01410 : tree */ 01411 ulint level, /* in: level, must be > 0 */ 01412 dtuple_t* tuple, /* in: the record to be inserted */ 01413 mtr_t* mtr) /* in: mtr */ 01414 { 01415 big_rec_t* dummy_big_rec; 01416 btr_cur_t cursor; 01417 ulint err; 01418 rec_t* rec; 01419 01420 ut_ad(level > 0); 01421 01422 /* In the following, choose just any index from the tree as the 01423 first parameter for btr_cur_search_to_nth_level. */ 01424 01425 btr_cur_search_to_nth_level(tree->tree_index, 01426 level, tuple, PAGE_CUR_LE, BTR_CONT_MODIFY_TREE, 01427 &cursor, 0, mtr); 01428 01429 err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG 01430 | BTR_KEEP_SYS_FLAG | BTR_NO_UNDO_LOG_FLAG, 01431 &cursor, tuple, &rec, &dummy_big_rec, NULL, mtr); 01432 ut_a(err == DB_SUCCESS); 01433 }
Here is the call graph for this function:

Here is the caller graph for this function:

Referenced by btr_pcur_move_backward_from_page(), btr_pcur_move_to_next_page(), btr_pcur_release_leaf(), and btr_search_guess_on_hash().
Here is the caller graph for this function:

| void btr_node_ptr_delete | ( | dict_tree_t * | tree, | |
| page_t * | page, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 1915 of file btr0btr.c.
References btr_cur_compress_if_useful(), btr_cur_pessimistic_delete(), btr_cur_position(), btr_page_get_father_node_ptr(), buf_block_align(), DB_SUCCESS, err, FALSE, mtr_memo_contains(), MTR_MEMO_PAGE_X_FIX, dict_tree_struct::tree_index, TRUE, ut_a, and ut_ad.
Referenced by btr_compress(), btr_cur_pessimistic_delete(), and btr_discard_page().
01917 : index tree */ 01918 page_t* page, /* in: page whose node pointer is deleted */ 01919 mtr_t* mtr) /* in: mtr */ 01920 { 01921 rec_t* node_ptr; 01922 btr_cur_t cursor; 01923 ibool compressed; 01924 ulint err; 01925 01926 ut_ad(mtr_memo_contains(mtr, buf_block_align(page), 01927 MTR_MEMO_PAGE_X_FIX)); 01928 /* Delete node pointer on father page */ 01929 01930 node_ptr = btr_page_get_father_node_ptr(tree, page, mtr); 01931 01932 btr_cur_position(tree->tree_index, node_ptr, &cursor); 01933 compressed = btr_cur_pessimistic_delete(&err, TRUE, &cursor, FALSE, 01934 mtr); 01935 ut_a(err == DB_SUCCESS); 01936 01937 if (!compressed) { 01938 btr_cur_compress_if_useful(&cursor, mtr); 01939 } 01940 }
Here is the call graph for this function:

Here is the caller graph for this function:

Referenced by btr_cur_open_at_index_side(), btr_cur_open_at_rnd_pos(), btr_cur_search_to_nth_level(), btr_node_ptr_get_child(), btr_page_get_father_for_rec(), and btr_validate_level().
Here is the caller graph for this function:

| page_t* btr_page_alloc | ( | dict_tree_t * | tree, | |
| ulint | hint_page_no, | |||
| byte | file_direction, | |||
| ulint | level, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 316 of file btr0btr.c.
References btr_page_alloc_for_ibuf(), btr_root_get(), buf_page_get, DICT_IBUF, dict_tree_get_space(), FIL_NULL, fseg_alloc_free_page_general(), NULL, PAGE_BTR_SEG_LEAF, PAGE_BTR_SEG_TOP, PAGE_HEADER, page_t, RW_X_LATCH, SYNC_TREE_NODE_NEW, TRUE, and dict_tree_struct::type.
Referenced by btr_page_split_and_insert(), btr_root_raise_and_insert(), and btr_store_big_rec_extern_fields().
00318 : new allocated page, x-latched; 00319 NULL if out of space */ 00320 dict_tree_t* tree, /* in: index tree */ 00321 ulint hint_page_no, /* in: hint of a good page */ 00322 byte file_direction, /* in: direction where a possible 00323 page split is made */ 00324 ulint level, /* in: level where the page is placed 00325 in the tree */ 00326 mtr_t* mtr) /* in: mtr */ 00327 { 00328 fseg_header_t* seg_header; 00329 page_t* root; 00330 page_t* new_page; 00331 ulint new_page_no; 00332 00333 if (tree->type & DICT_IBUF) { 00334 00335 return(btr_page_alloc_for_ibuf(tree, mtr)); 00336 } 00337 00338 root = btr_root_get(tree, mtr); 00339 00340 if (level == 0) { 00341 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF; 00342 } else { 00343 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP; 00344 } 00345 00346 /* Parameter TRUE below states that the caller has made the 00347 reservation for free extents, and thus we know that a page can 00348 be allocated: */ 00349 00350 new_page_no = fseg_alloc_free_page_general(seg_header, hint_page_no, 00351 file_direction, TRUE, mtr); 00352 if (new_page_no == FIL_NULL) { 00353 00354 return(NULL); 00355 } 00356 00357 new_page = buf_page_get(dict_tree_get_space(tree), new_page_no, 00358 RW_X_LATCH, mtr); 00359 #ifdef UNIV_SYNC_DEBUG 00360 buf_page_dbg_add_level(new_page, SYNC_TREE_NODE_NEW); 00361 #endif /* UNIV_SYNC_DEBUG */ 00362 00363 return(new_page); 00364 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void btr_page_free | ( | dict_tree_t * | tree, | |
| page_t * | page, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 485 of file btr0btr.c.
References btr_page_free_low(), btr_page_get_level(), buf_block_align(), mtr_memo_contains(), MTR_MEMO_PAGE_X_FIX, and ut_ad.
Referenced by btr_compress(), btr_discard_only_page_on_level(), btr_discard_page(), and btr_lift_page_up().
00487 : index tree */ 00488 page_t* page, /* in: page to be freed, x-latched */ 00489 mtr_t* mtr) /* in: mtr */ 00490 { 00491 ulint level; 00492 00493 ut_ad(mtr_memo_contains(mtr, buf_block_align(page), 00494 MTR_MEMO_PAGE_X_FIX)); 00495 level = btr_page_get_level(page, mtr); 00496 00497 btr_page_free_low(tree, page, level, mtr); 00498 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void btr_page_free_low | ( | dict_tree_t * | tree, | |
| page_t * | page, | |||
| ulint | level, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 440 of file btr0btr.c.
References btr_page_free_for_ibuf(), btr_root_get(), buf_block_align(), buf_frame_get_page_no(), buf_frame_get_space_id(), buf_frame_modify_clock_inc(), DICT_IBUF, fseg_free_page(), mtr_memo_contains(), MTR_MEMO_PAGE_X_FIX, PAGE_BTR_SEG_LEAF, PAGE_BTR_SEG_TOP, PAGE_HEADER, page_t, dict_tree_struct::type, and ut_ad.
Referenced by btr_free_externally_stored_field(), and btr_page_free().
00442 : index tree */ 00443 page_t* page, /* in: page to be freed, x-latched */ 00444 ulint level, /* in: page level */ 00445 mtr_t* mtr) /* in: mtr */ 00446 { 00447 fseg_header_t* seg_header; 00448 page_t* root; 00449 ulint space; 00450 ulint page_no; 00451 00452 ut_ad(mtr_memo_contains(mtr, buf_block_align(page), 00453 MTR_MEMO_PAGE_X_FIX)); 00454 /* The page gets invalid for optimistic searches: increment the frame 00455 modify clock */ 00456 00457 buf_frame_modify_clock_inc(page); 00458 00459 if (tree->type & DICT_IBUF) { 00460 00461 btr_page_free_for_ibuf(tree, page, mtr); 00462 00463 return; 00464 } 00465 00466 root = btr_root_get(tree, mtr); 00467 00468 if (level == 0) { 00469 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF; 00470 } else { 00471 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP; 00472 } 00473 00474 space = buf_frame_get_space_id(page); 00475 page_no = buf_frame_get_page_no(page); 00476 00477 fseg_free_page(seg_header, space, page_no, mtr); 00478 }
Here is the call graph for this function:

Here is the caller graph for this function:

Referenced by btr_attach_half_pages(), btr_compress(), btr_cur_latch_leaves(), btr_cur_search_to_nth_level(), btr_discard_page(), btr_free_but_not_root(), btr_free_root(), btr_level_list_remove(), btr_node_ptr_get_child(), btr_pcur_move_to_next_page(), btr_root_get(), btr_validate_level(), and dict_truncate_index_tree().
Here is the caller graph for this function:

Referenced by btr_cur_open_at_index_side(), btr_cur_open_at_rnd_pos(), btr_cur_search_to_nth_level(), btr_search_build_page_hash_index(), btr_search_drop_page_hash_index(), btr_search_guess_on_hash(), btr_search_validate(), and buf_page_print().
Here is the caller graph for this function:

Referenced by btr_attach_half_pages(), btr_compress(), btr_cur_compress(), btr_cur_open_at_index_side(), btr_cur_open_at_rnd_pos(), btr_cur_optimistic_delete(), btr_cur_optimistic_insert(), btr_cur_pessimistic_delete(), btr_cur_search_to_nth_level(), btr_discard_only_page_on_level(), btr_discard_page(), btr_lift_page_up(), btr_node_ptr_set_child_page_no(), btr_page_free(), btr_page_get_father_for_rec(), btr_page_split_and_insert(), btr_root_raise_and_insert(), btr_validate_level(), btr_validate_tree(), and ibuf_data_sizes_update().
Here is the caller graph for this function:

Referenced by ibuf_set_free_bits(), ibuf_set_free_bits_low(), and page_validate().
Here is the caller graph for this function:

Referenced by btr_attach_half_pages(), btr_compress(), btr_cur_latch_leaves(), btr_cur_pess_upd_restore_supremum(), btr_discard_only_page_on_level(), btr_discard_page(), btr_estimate_number_of_different_key_vals(), btr_get_next_user_rec(), btr_get_prev_user_rec(), btr_level_list_remove(), btr_lift_page_up(), btr_pcur_move_to_next_page(), btr_pcur_store_position(), btr_search_check_guess(), btr_validate_level(), and ibuf_get_volume_buffered().
Here is the caller graph for this function:

Referenced by btr_attach_half_pages(), btr_compress(), btr_cur_latch_leaves(), btr_cur_pess_upd_restore_supremum(), btr_cur_pessimistic_delete(), btr_discard_only_page_on_level(), btr_discard_page(), btr_estimate_number_of_different_key_vals(), btr_get_next_user_rec(), btr_get_prev_user_rec(), btr_level_list_remove(), btr_lift_page_up(), btr_pcur_move_backward_from_page(), btr_pcur_move_to_next_page(), btr_pcur_store_position(), btr_search_check_guess(), btr_validate_level(), and ibuf_get_volume_buffered().
Here is the caller graph for this function:

Definition at line 1098 of file btr0btr.c.
References btr_cur_get_page(), btr_cur_get_rec(), FALSE, page, page_get_infimum_rec(), page_header_get_ptr(), PAGE_LAST_INSERT, page_rec_get_next(), page_t, and TRUE.
Referenced by btr_cur_optimistic_insert(), and btr_page_split_and_insert().
01100 : TRUE if split recommended */ 01101 btr_cur_t* cursor, /* in: cursor at which to insert */ 01102 rec_t** split_rec) /* out: if split recommended, 01103 the first record on upper half page, 01104 or NULL if tuple to be inserted should 01105 be first */ 01106 { 01107 page_t* page; 01108 rec_t* insert_point; 01109 rec_t* infimum; 01110 01111 page = btr_cur_get_page(cursor); 01112 insert_point = btr_cur_get_rec(cursor); 01113 01114 if (page_header_get_ptr(page, PAGE_LAST_INSERT) 01115 == page_rec_get_next(insert_point)) { 01116 01117 infimum = page_get_infimum_rec(page); 01118 01119 /* If the convergence is in the middle of a page, include also 01120 the record immediately before the new insert to the upper 01121 page. Otherwise, we could repeatedly move from page to page 01122 lots of records smaller than the convergence point. */ 01123 01124 if (infimum != insert_point 01125 && page_rec_get_next(infimum) != insert_point) { 01126 01127 *split_rec = insert_point; 01128 } else { 01129 *split_rec = page_rec_get_next(insert_point); 01130 } 01131 01132 return(TRUE); 01133 } 01134 01135 return(FALSE); 01136 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1143 of file btr0btr.c.
References btr_cur_get_page(), btr_cur_get_rec(), FALSE, NULL, page, page_header_get_ptr(), PAGE_LAST_INSERT, page_rec_get_next(), page_rec_is_supremum(), page_t, and TRUE.
Referenced by btr_cur_optimistic_insert(), and btr_page_split_and_insert().
01145 : TRUE if split recommended */ 01146 btr_cur_t* cursor, /* in: cursor at which to insert */ 01147 rec_t** split_rec) /* out: if split recommended, 01148 the first record on upper half page, 01149 or NULL if tuple to be inserted should 01150 be first */ 01151 { 01152 page_t* page; 01153 rec_t* insert_point; 01154 01155 page = btr_cur_get_page(cursor); 01156 insert_point = btr_cur_get_rec(cursor); 01157 01158 /* We use eager heuristics: if the new insert would be right after 01159 the previous insert on the same page, we assume that there is a 01160 pattern of sequential inserts here. */ 01161 01162 if (UNIV_LIKELY(page_header_get_ptr(page, PAGE_LAST_INSERT) 01163 == insert_point)) { 01164 01165 rec_t* next_rec; 01166 01167 next_rec = page_rec_get_next(insert_point); 01168 01169 if (page_rec_is_supremum(next_rec)) { 01170 split_at_new: 01171 /* Split at the new record to insert */ 01172 *split_rec = NULL; 01173 } else { 01174 rec_t* next_next_rec = page_rec_get_next(next_rec); 01175 if (page_rec_is_supremum(next_next_rec)) { 01176 01177 goto split_at_new; 01178 } 01179 01180 /* If there are >= 2 user records up from the insert 01181 point, split all but 1 off. We want to keep one because 01182 then sequential inserts can use the adaptive hash 01183 index, as they can do the necessary checks of the right 01184 search position just by looking at the records on this 01185 page. */ 01186 01187 *split_rec = next_next_rec; 01188 } 01189 01190 return(TRUE); 01191 } 01192 01193 return(FALSE); 01194 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void btr_page_reorganize | ( | page_t * | page, | |
| dict_index_t * | index, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 922 of file btr0btr.c.
References btr_page_reorganize_low(), FALSE, and index().
Referenced by btr_compress(), btr_cur_insert_if_possible(), btr_cur_optimistic_insert(), btr_page_split_and_insert(), btr_root_raise_and_insert(), and ibuf_insert_to_index_page().
00924 : page to be reorganized */ 00925 dict_index_t* index, /* in: record descriptor */ 00926 mtr_t* mtr) /* in: mtr */ 00927 { 00928 btr_page_reorganize_low(FALSE, page, index, mtr); 00929 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1563 of file btr0btr.c.
References btr_attach_half_pages(), btr_cur_get_page(), btr_cur_get_page_cur(), btr_cur_get_rec(), btr_cur_get_tree(), btr_page_alloc(), btr_page_create(), btr_page_get_level(), btr_page_get_split_rec_to_left(), btr_page_get_split_rec_to_right(), btr_page_get_sure_split_rec(), btr_page_insert_fits(), btr_page_reorganize(), buf, buf_block_align(), buf_frame_get_page_no(), cmp_dtuple_rec(), dict_index_get_n_unique_in_tree(), dict_tree_get_lock(), FSP_DOWN, FSP_UP, ibuf_reset_free_bits(), ibuf_update_free_bits_for_two_pages_low(), btr_cur_struct::index, lock_update_split_left(), lock_update_split_right(), mem_alloc, mem_free, mem_heap_create, mem_heap_empty(), mem_heap_free, mtr_memo_contains(), MTR_MEMO_PAGE_X_FIX, mtr_memo_release(), MTR_MEMO_X_LOCK, NULL, page, PAGE_CUR_LE, page_cur_search(), page_cur_tuple_insert(), page_get_middle_rec(), page_get_n_recs(), page_move_rec_list_end(), page_move_rec_list_start(), page_rec_get_next(), page_t, page_validate(), rec_convert_dtuple_to_rec(), rec_get_converted_size(), rec_get_offsets, RW_LOCK_EX, dict_tree_struct::tree_index, and ut_ad.
Referenced by btr_cur_pessimistic_insert(), and btr_root_raise_and_insert().
01565 : inserted record; NOTE: the tree 01566 x-latch is released! NOTE: 2 free disk 01567 pages must be available! */ 01568 btr_cur_t* cursor, /* in: cursor at which to insert; when the 01569 function returns, the cursor is positioned 01570 on the predecessor of the inserted record */ 01571 dtuple_t* tuple, /* in: tuple to insert */ 01572 mtr_t* mtr) /* in: mtr */ 01573 { 01574 dict_tree_t* tree; 01575 page_t* page; 01576 ulint page_no; 01577 byte direction; 01578 ulint hint_page_no; 01579 page_t* new_page; 01580 rec_t* split_rec; 01581 page_t* left_page; 01582 page_t* right_page; 01583 page_t* insert_page; 01584 page_cur_t* page_cursor; 01585 rec_t* first_rec; 01586 byte* buf = 0; /* remove warning */ 01587 rec_t* move_limit; 01588 ibool insert_will_fit; 01589 ulint n_iterations = 0; 01590 rec_t* rec; 01591 mem_heap_t* heap; 01592 ulint n_uniq; 01593 ulint* offsets; 01594 01595 heap = mem_heap_create(1024); 01596 n_uniq = dict_index_get_n_unique_in_tree(cursor->index); 01597 func_start: 01598 mem_heap_empty(heap); 01599 offsets = NULL; 01600 tree = btr_cur_get_tree(cursor); 01601 01602 ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), 01603 MTR_MEMO_X_LOCK)); 01604 #ifdef UNIV_SYNC_DEBUG 01605 ut_ad(rw_lock_own(dict_tree_get_lock(tree), RW_LOCK_EX)); 01606 #endif /* UNIV_SYNC_DEBUG */ 01607 01608 page = btr_cur_get_page(cursor); 01609 01610 ut_ad(mtr_memo_contains(mtr, buf_block_align(page), 01611 MTR_MEMO_PAGE_X_FIX)); 01612 ut_ad(page_get_n_recs(page) >= 2); 01613 01614 page_no = buf_frame_get_page_no(page); 01615 01616 /* 1. Decide the split record; split_rec == NULL means that the 01617 tuple to be inserted should be the first record on the upper 01618 half-page */ 01619 01620 if (n_iterations > 0) { 01621 direction = FSP_UP; 01622 hint_page_no = page_no + 1; 01623 split_rec = btr_page_get_sure_split_rec(cursor, tuple); 01624 01625 } else if (btr_page_get_split_rec_to_right(cursor, &split_rec)) { 01626 direction = FSP_UP; 01627 hint_page_no = page_no + 1; 01628 01629 } else if (btr_page_get_split_rec_to_left(cursor, &split_rec)) { 01630 direction = FSP_DOWN; 01631 hint_page_no = page_no - 1; 01632 } else { 01633 direction = FSP_UP; 01634 hint_page_no = page_no + 1; 01635 split_rec = page_get_middle_rec(page); 01636 } 01637 01638 /* 2. Allocate a new page to the tree */ 01639 new_page = btr_page_alloc(tree, hint_page_no, direction, 01640 btr_page_get_level(page, mtr), mtr); 01641 btr_page_create(new_page, tree, mtr); 01642 01643 /* 3. Calculate the first record on the upper half-page, and the 01644 first record (move_limit) on original page which ends up on the 01645 upper half */ 01646 01647 if (split_rec != NULL) { 01648 first_rec = split_rec; 01649 move_limit = split_rec; 01650 } else { 01651 buf = mem_alloc(rec_get_converted_size(cursor->index, tuple)); 01652 01653 first_rec = rec_convert_dtuple_to_rec(buf, 01654 cursor->index, tuple); 01655 move_limit = page_rec_get_next(btr_cur_get_rec(cursor)); 01656 } 01657 01658 /* 4. Do first the modifications in the tree structure */ 01659 01660 btr_attach_half_pages(tree, page, first_rec, new_page, direction, mtr); 01661 01662 if (split_rec == NULL) { 01663 mem_free(buf); 01664 } 01665 01666 /* If the split is made on the leaf level and the insert will fit 01667 on the appropriate half-page, we may release the tree x-latch. 01668 We can then move the records after releasing the tree latch, 01669 thus reducing the tree latch contention. */ 01670 01671 if (split_rec) { 01672 offsets = rec_get_offsets(split_rec, cursor->index, offsets, 01673 n_uniq, &heap); 01674 01675 insert_will_fit = btr_page_insert_fits(cursor, 01676 split_rec, offsets, tuple, heap); 01677 } else { 01678 insert_will_fit = btr_page_insert_fits(cursor, 01679 NULL, NULL, tuple, heap); 01680 } 01681 01682 if (insert_will_fit && (btr_page_get_level(page, mtr) == 0)) { 01683 01684 mtr_memo_release(mtr, dict_tree_get_lock(tree), 01685 MTR_MEMO_X_LOCK); 01686 } 01687 01688 /* 5. Move then the records to the new page */ 01689 if (direction == FSP_DOWN) { 01690 /* fputs("Split left\n", stderr); */ 01691 01692 page_move_rec_list_start(new_page, page, move_limit, 01693 cursor->index, mtr); 01694 left_page = new_page; 01695 right_page = page; 01696 01697 lock_update_split_left(right_page, left_page); 01698 } else { 01699 /* fputs("Split right\n", stderr); */ 01700 01701 page_move_rec_list_end(new_page, page, move_limit, 01702 cursor->index, mtr); 01703 left_page = page; 01704 right_page = new_page; 01705 01706 lock_update_split_right(right_page, left_page); 01707 } 01708 01709 /* 6. The split and the tree modification is now completed. Decide the 01710 page where the tuple should be inserted */ 01711 01712 if (split_rec == NULL) { 01713 insert_page = right_page; 01714 01715 } else { 01716 offsets = rec_get_offsets(first_rec, cursor->index, 01717 offsets, n_uniq, &heap); 01718 01719 if (cmp_dtuple_rec(tuple, first_rec, offsets) >= 0) { 01720 01721 insert_page = right_page; 01722 } else { 01723 insert_page = left_page; 01724 } 01725 } 01726 01727 /* 7. Reposition the cursor for insert and try insertion */ 01728 page_cursor = btr_cur_get_page_cur(cursor); 01729 01730 page_cur_search(insert_page, cursor->index, tuple, 01731 PAGE_CUR_LE, page_cursor); 01732 01733 rec = page_cur_tuple_insert(page_cursor, tuple, cursor->index, mtr); 01734 01735 if (rec != NULL) { 01736 /* Insert fit on the page: update the free bits for the 01737 left and right pages in the same mtr */ 01738 01739 ibuf_update_free_bits_for_two_pages_low(cursor->index, 01740 left_page, 01741 right_page, mtr); 01742 /* fprintf(stderr, "Split and insert done %lu %lu\n", 01743 buf_frame_get_page_no(left_page), 01744 buf_frame_get_page_no(right_page)); */ 01745 mem_heap_free(heap); 01746 return(rec); 01747 } 01748 01749 /* 8. If insert did not fit, try page reorganization */ 01750 01751 btr_page_reorganize(insert_page, cursor->index, mtr); 01752 01753 page_cur_search(insert_page, cursor->index, tuple, 01754 PAGE_CUR_LE, page_cursor); 01755 rec = page_cur_tuple_insert(page_cursor, tuple, cursor->index, mtr); 01756 01757 if (rec == NULL) { 01758 /* The insert did not fit on the page: loop back to the 01759 start of the function for a new split */ 01760 01761 /* We play safe and reset the free bits for new_page */ 01762 ibuf_reset_free_bits(cursor->index, new_page); 01763 01764 /* fprintf(stderr, "Split second round %lu\n", 01765 buf_frame_get_page_no(page)); */ 01766 n_iterations++; 01767 ut_ad(n_iterations < 2); 01768 ut_ad(!insert_will_fit); 01769 01770 goto func_start; 01771 } 01772 01773 /* Insert fit on the page: update the free bits for the 01774 left and right pages in the same mtr */ 01775 01776 ibuf_update_free_bits_for_two_pages_low(cursor->index, left_page, 01777 right_page, mtr); 01778 /* fprintf(stderr, "Split and insert done %lu %lu\n", 01779 buf_frame_get_page_no(left_page), 01780 buf_frame_get_page_no(right_page)); */ 01781 01782 ut_ad(page_validate(left_page, tree->tree_index)); 01783 ut_ad(page_validate(right_page, tree->tree_index)); 01784 01785 mem_heap_free(heap); 01786 return(rec); 01787 }
Here is the call graph for this function:

Here is the caller graph for this function:

| byte* btr_parse_page_reorganize | ( | byte * | ptr, | |
| byte * | end_ptr, | |||
| dict_index_t * | index, | |||
| page_t * | page, | |||
| mtr_t * | mtr | |||
| ) |
| byte* btr_parse_set_min_rec_mark | ( | byte * | ptr, | |
| byte * | end_ptr, | |||
| ulint | comp, | |||
| page_t * | page, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 1865 of file btr0btr.c.
References btr_set_min_rec_mark(), mach_read_from_2(), NULL, page_is_comp(), and ut_a.
Referenced by recv_parse_or_apply_log_rec_body().
01867 : end of log record or NULL */ 01868 byte* ptr, /* in: buffer */ 01869 byte* end_ptr,/* in: buffer end */ 01870 ulint comp, /* in: nonzero=compact page format */ 01871 page_t* page, /* in: page or NULL */ 01872 mtr_t* mtr) /* in: mtr or NULL */ 01873 { 01874 rec_t* rec; 01875 01876 if (end_ptr < ptr + 2) { 01877 01878 return(NULL); 01879 } 01880 01881 if (page) { 01882 ut_a(!page_is_comp(page) == !comp); 01883 01884 rec = page + mach_read_from_2(ptr); 01885 01886 btr_set_min_rec_mark(rec, comp, mtr); 01887 } 01888 01889 return(ptr + 2); 01890 }
Here is the call graph for this function:

Here is the caller graph for this function:

| page_t* btr_root_get | ( | dict_tree_t * | tree, | |
| mtr_t * | mtr | |||
| ) |
Definition at line 132 of file btr0btr.c.
References btr_page_get(), dict_table_is_comp(), dict_tree_get_page(), dict_tree_get_space(), page_is_comp(), page_t, RW_X_LATCH, dict_index_struct::table, dict_tree_struct::tree_index, and ut_a.
Referenced by btr_get_size(), btr_page_alloc(), btr_page_alloc_for_ibuf(), btr_page_free_for_ibuf(), btr_page_free_low(), btr_validate_level(), btr_validate_tree(), and row_purge_upd_exist_or_extern().
00134 : root page, x-latched */ 00135 dict_tree_t* tree, /* in: index tree */ 00136 mtr_t* mtr) /* in: mtr */ 00137 { 00138 ulint space; 00139 ulint root_page_no; 00140 page_t* root; 00141 00142 space = dict_tree_get_space(tree); 00143 root_page_no = dict_tree_get_page(tree); 00144 00145 root = btr_page_get(space, root_page_no, RW_X_LATCH, mtr); 00146 ut_a((ibool)!!page_is_comp(root) == 00147 dict_table_is_comp(tree->tree_index->table)); 00148 00149 return(root); 00150 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 984 of file btr0btr.c.
References btr_cur_get_page(), btr_cur_get_page_cur(), btr_cur_get_tree(), btr_page_alloc(), btr_page_create(), btr_page_get_level(), btr_page_reorganize(), btr_page_split_and_insert(), btr_search_drop_page_hash_index(), btr_set_min_rec_mark(), buf_block_align(), buf_frame_get_page_no(), dict_tree_build_node_ptr(), dict_tree_get_lock(), dict_tree_get_page(), FIL_NULL, FSP_NO_DIR, ibuf_reset_free_bits(), btr_cur_struct::index, lock_update_root_raise(), mem_heap_create, mem_heap_free, mtr_memo_contains(), MTR_MEMO_PAGE_X_FIX, MTR_MEMO_X_LOCK, PAGE_CUR_LE, page_cur_search(), page_cur_set_before_first(), page_cur_tuple_insert(), page_get_infimum_rec(), page_is_comp(), page_move_rec_list_end(), page_rec_get_next(), page_t, dict_tree_struct::tree_index, and ut_ad.
Referenced by btr_cur_pessimistic_insert().
00986 : inserted record */ 00987 btr_cur_t* cursor, /* in: cursor at which to insert: must be 00988 on the root page; when the function returns, 00989 the cursor is positioned on the predecessor 00990 of the inserted record */ 00991 dtuple_t* tuple, /* in: tuple to insert */ 00992 mtr_t* mtr) /* in: mtr */ 00993 { 00994 dict_tree_t* tree; 00995 page_t* root; 00996 page_t* new_page; 00997 ulint new_page_no; 00998 rec_t* rec; 00999 mem_heap_t* heap; 01000 dtuple_t* node_ptr; 01001 ulint level; 01002 rec_t* node_ptr_rec; 01003 page_cur_t* page_cursor; 01004 01005 root = btr_cur_get_page(cursor); 01006 tree = btr_cur_get_tree(cursor); 01007 01008 ut_ad(dict_tree_get_page(tree) == buf_frame_get_page_no(root)); 01009 ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), 01010 MTR_MEMO_X_LOCK)); 01011 ut_ad(mtr_memo_contains(mtr, buf_block_align(root), 01012 MTR_MEMO_PAGE_X_FIX)); 01013 btr_search_drop_page_hash_index(root); 01014 01015 /* Allocate a new page to the tree. Root splitting is done by first 01016 moving the root records to the new page, emptying the root, putting 01017 a node pointer to the new page, and then splitting the new page. */ 01018 01019 new_page = btr_page_alloc(tree, 0, FSP_NO_DIR, 01020 btr_page_get_level(root, mtr), mtr); 01021 01022 btr_page_create(new_page, tree, mtr); 01023 01024 level = btr_page_get_level(root, mtr); 01025 01026 /* Set the levels of the new index page and root page */ 01027 btr_page_set_level(new_page, level, mtr); 01028 btr_page_set_level(root, level + 1, mtr); 01029 01030 /* Set the next node and previous node fields of new page */ 01031 btr_page_set_next(new_page, FIL_NULL, mtr); 01032 btr_page_set_prev(new_page, FIL_NULL, mtr); 01033 01034 /* Move the records from root to the new page */ 01035 01036 page_move_rec_list_end(new_page, root, page_get_infimum_rec(root), 01037 cursor->index, mtr); 01038 /* If this is a pessimistic insert which is actually done to 01039 perform a pessimistic update then we have stored the lock 01040 information of the record to be inserted on the infimum of the 01041 root page: we cannot discard the lock structs on the root page */ 01042 01043 lock_update_root_raise(new_page, root); 01044 01045 /* Create a memory heap where the node pointer is stored */ 01046 heap = mem_heap_create(100); 01047 01048 rec = page_rec_get_next(page_get_infimum_rec(new_page)); 01049 new_page_no = buf_frame_get_page_no(new_page); 01050 01051 /* Build the node pointer (= node key and page address) for the 01052 child */ 01053 01054 node_ptr = dict_tree_build_node_ptr(tree, rec, new_page_no, heap, 01055 level); 01056 /* Reorganize the root to get free space */ 01057 btr_page_reorganize(root, cursor->index, mtr); 01058 01059 page_cursor = btr_cur_get_page_cur(cursor); 01060 01061 /* Insert node pointer to the root */ 01062 01063 page_cur_set_before_first(root, page_cursor); 01064 01065 node_ptr_rec = page_cur_tuple_insert(page_cursor, node_ptr, 01066 cursor->index, mtr); 01067 01068 ut_ad(node_ptr_rec); 01069 01070 /* The node pointer must be marked as the predefined minimum record, 01071 as there is no lower alphabetical limit to records in the leftmost 01072 node of a level: */ 01073 01074 btr_set_min_rec_mark(node_ptr_rec, page_is_comp(root), mtr); 01075 01076 /* Free the memory heap */ 01077 mem_heap_free(heap); 01078 01079 /* We play safe and reset the free bits for the new page */ 01080 01081 /* fprintf(stderr, "Root raise new page no %lu\n", 01082 buf_frame_get_page_no(new_page)); */ 01083 01084 ibuf_reset_free_bits(tree->tree_index, new_page); 01085 /* Reposition the cursor to the child node */ 01086 page_cur_search(new_page, cursor->index, tuple, 01087 PAGE_CUR_LE, page_cursor); 01088 01089 /* Split the child and insert tuple */ 01090 return(btr_page_split_and_insert(cursor, tuple, mtr)); 01091 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1896 of file btr0btr.c.
References btr_set_min_rec_mark_log(), rec_get_info_bits(), REC_INFO_MIN_REC_FLAG, and rec_set_info_bits().
Referenced by btr_cur_pessimistic_delete(), btr_discard_page(), btr_parse_set_min_rec_mark(), and btr_root_raise_and_insert().
01898 : record */ 01899 ulint comp, /* in: nonzero=compact page format */ 01900 mtr_t* mtr) /* in: mtr */ 01901 { 01902 ulint info_bits; 01903 01904 info_bits = rec_get_info_bits(rec, comp); 01905 01906 rec_set_info_bits(rec, comp, info_bits | REC_INFO_MIN_REC_FLAG); 01907 01908 btr_set_min_rec_mark_log(rec, comp, mtr); 01909 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool btr_validate_tree | ( | dict_tree_t * | tree, | |
| trx_t * | trx | |||
| ) |
Definition at line 3010 of file btr0btr.c.
References btr_page_get_level(), btr_root_get(), btr_validate_level(), dict_tree_get_lock(), FALSE, mtr_commit(), mtr_start(), mtr_x_lock, n, page_t, TRUE, and trx_is_interrupted().
Referenced by ibuf_delete_rec(), and row_check_table_for_mysql().
03012 : TRUE if ok */ 03013 dict_tree_t* tree, /* in: tree */ 03014 trx_t* trx) /* in: transaction or NULL */ 03015 { 03016 mtr_t mtr; 03017 page_t* root; 03018 ulint i; 03019 ulint n; 03020 03021 mtr_start(&mtr); 03022 mtr_x_lock(dict_tree_get_lock(tree), &mtr); 03023 03024 root = btr_root_get(tree, &mtr); 03025 n = btr_page_get_level(root, &mtr); 03026 03027 for (i = 0; i <= n && !trx_is_interrupted(trx); i++) { 03028 if (!btr_validate_level(tree, trx, n - i)) { 03029 03030 mtr_commit(&mtr); 03031 03032 return(FALSE); 03033 } 03034 } 03035 03036 mtr_commit(&mtr); 03037 03038 return(TRUE); 03039 }
Here is the call graph for this function:

Here is the caller graph for this function:

1.4.7

