diff options
41 files changed, 414 insertions, 3479 deletions
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 255788229e4..e5284ee802a 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -242,8 +242,7 @@ btr_height_get( || mtr_memo_contains_flagged(mtr, dict_index_get_lock(index), MTR_MEMO_S_LOCK | MTR_MEMO_X_LOCK - | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(index->table)); + | MTR_MEMO_SX_LOCK)); /* S latches the page */ root_block = btr_root_block_get(index, RW_S_LATCH, mtr); @@ -560,8 +559,7 @@ btr_get_size( ut_ad(srv_read_only_mode || mtr_memo_contains(mtr, dict_index_get_lock(index), - MTR_MEMO_S_LOCK) - || dict_table_is_intrinsic(index->table)); + MTR_MEMO_S_LOCK)); if (index->page == FIL_NULL || dict_index_is_online_ddl(index) @@ -917,8 +915,7 @@ btr_page_get_father_node_ptr_func( ut_ad(srv_read_only_mode || mtr_memo_contains_flagged(mtr, dict_index_get_lock(index), MTR_MEMO_X_LOCK - | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(index->table)); + | MTR_MEMO_SX_LOCK)); ut_ad(dict_index_get_page(index) != page_no); @@ -929,17 +926,11 @@ btr_page_get_father_node_ptr_func( tuple = dict_index_build_node_ptr(index, user_rec, 0, heap, level); dberr_t err = DB_SUCCESS; - - if (dict_table_is_intrinsic(index->table)) { - err = btr_cur_search_to_nth_level_with_no_latch( - index, level + 1, tuple, PAGE_CUR_LE, cursor, - file, line, mtr); - } else { - err = btr_cur_search_to_nth_level( - index, level + 1, tuple, - PAGE_CUR_LE, latch_mode, cursor, 0, - file, line, mtr); - } + + err = btr_cur_search_to_nth_level( + index, level + 1, tuple, + PAGE_CUR_LE, latch_mode, cursor, 0, + file, line, mtr); if (err != DB_SUCCESS) { ib::warn() << " Error code: " << err @@ -1560,7 +1551,6 @@ btr_page_reorganize_low( } #ifndef UNIV_HOTBACKUP - /* No locks are acquried for intrinsic tables. */ if (!recovery && !dict_table_is_locking_disabled(index->table)) { /* Update the record lock bitmaps */ lock_move_reorganize_page(block, temp_block); @@ -1824,8 +1814,7 @@ btr_root_raise_and_insert( #endif /* UNIV_BTR_DEBUG */ ut_ad(mtr_memo_contains_flagged(mtr, dict_index_get_lock(index), MTR_MEMO_X_LOCK - | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(index->table)); + | MTR_MEMO_SX_LOCK)); ut_ad(mtr_is_block_fix( mtr, root_block, MTR_MEMO_PAGE_X_FIX, index->table)); @@ -2311,17 +2300,10 @@ btr_insert_on_non_leaf_level_func( ut_ad(level > 0); if (!dict_index_is_spatial(index)) { - dberr_t err = DB_SUCCESS; - if (dict_table_is_intrinsic(index->table)) { - err = btr_cur_search_to_nth_level_with_no_latch( - index, level, tuple, PAGE_CUR_LE, &cursor, - __FILE__, __LINE__, mtr); - } else { - err = btr_cur_search_to_nth_level( - index, level, tuple, PAGE_CUR_LE, - BTR_CONT_MODIFY_TREE, - &cursor, 0, file, line, mtr); - } + dberr_t err = btr_cur_search_to_nth_level( + index, level, tuple, PAGE_CUR_LE, + BTR_CONT_MODIFY_TREE, + &cursor, 0, file, line, mtr); if (err != DB_SUCCESS) { ib::warn() << " Error code: " << err @@ -2593,10 +2575,9 @@ btr_insert_into_right_sibling( page_t* page = buf_block_get_frame(block); ulint next_page_no = btr_page_get_next(page, mtr); - ut_ad(dict_table_is_intrinsic(cursor->index->table) - || mtr_memo_contains_flagged( - mtr, dict_index_get_lock(cursor->index), - MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); + ut_ad(mtr_memo_contains_flagged( + mtr, dict_index_get_lock(cursor->index), + MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); ut_ad(mtr_is_block_fix( mtr, block, MTR_MEMO_PAGE_X_FIX, cursor->index->table)); ut_ad(heap); @@ -2769,14 +2750,12 @@ func_start: ut_ad(mtr_memo_contains_flagged(mtr, dict_index_get_lock(cursor->index), - MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(cursor->index->table)); + MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); ut_ad(!dict_index_is_online_ddl(cursor->index) || (flags & BTR_CREATE_FLAG) || dict_index_is_clust(cursor->index)); ut_ad(rw_lock_own_flagged(dict_index_get_lock(cursor->index), - RW_LOCK_FLAG_X | RW_LOCK_FLAG_SX) - || dict_table_is_intrinsic(cursor->index->table)); + RW_LOCK_FLAG_X | RW_LOCK_FLAG_SX)); block = btr_cur_get_block(cursor); page = buf_block_get_frame(block); @@ -2930,7 +2909,6 @@ insert_empty: } if (!srv_read_only_mode - && !dict_table_is_intrinsic(cursor->index->table) && insert_will_fit && page_is_leaf(page) && !dict_index_is_online_ddl(cursor->index)) { @@ -3559,8 +3537,7 @@ btr_compress( } else { ut_ad(mtr_memo_contains_flagged(mtr, dict_index_get_lock(index), MTR_MEMO_X_LOCK - | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(index->table)); + | MTR_MEMO_SX_LOCK)); } #endif /* UNIV_DEBUG */ @@ -4152,8 +4129,7 @@ btr_discard_page( ut_ad(dict_index_get_page(index) != block->page.id.page_no()); ut_ad(mtr_memo_contains_flagged(mtr, dict_index_get_lock(index), - MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(index->table)); + MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); ut_ad(mtr_is_block_fix(mtr, block, MTR_MEMO_PAGE_X_FIX, index->table)); diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 7daec068f78..0d72b9d2b92 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -280,10 +280,10 @@ btr_cur_latch_leaves( case BTR_MODIFY_TREE: /* It is exclusive for other operations which calls btr_page_set_prev() */ - ut_ad(mtr_memo_contains_flagged(mtr, - dict_index_get_lock(cursor->index), - MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(cursor->index->table)); + ut_ad(mtr_memo_contains_flagged( + mtr, + dict_index_get_lock(cursor->index), + MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); /* x-latch also siblings from left to right */ left_page_no = btr_page_get_prev(page, mtr); mode = latch_mode; @@ -583,9 +583,7 @@ btr_cur_will_modify_tree( { ut_ad(!page_is_leaf(page)); ut_ad(mtr_memo_contains_flagged(mtr, dict_index_get_lock(index), - MTR_MEMO_X_LOCK - | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(index->table)); + MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); /* Pessimistic delete of the first record causes delete & insert of node_ptr at upper level. And a subsequent page shrink is @@ -909,13 +907,13 @@ btr_cur_search_to_nth_level( # ifdef UNIV_SEARCH_PERF_STAT info->n_searches++; # endif - /* Use of AHI is disabled for intrinsic table as these tables re-use - the index-id and AHI validation is based on index-id. */ if (rw_lock_get_writer(btr_get_search_latch(index)) == RW_LOCK_NOT_LOCKED && latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ +# ifdef MYSQL_INDEX_DISABLE_AHI && !index->disable_ahi +# endif && !estimate # ifdef PAGE_CUR_LE_OR_EXTENDS && mode != PAGE_CUR_LE_OR_EXTENDS @@ -1958,7 +1956,11 @@ need_opposite_intention: will properly check btr_search_enabled again in btr_search_build_page_hash_index() before building a page hash index, while holding search latch. */ - if (btr_search_enabled && !index->disable_ahi) { + if (btr_search_enabled +# ifdef MYSQL_INDEX_DISABLE_AHI + && !index->disable_ahi +# endif + ) { btr_search_info_update(index, cursor); } #endif @@ -2009,179 +2011,6 @@ func_exit: DBUG_RETURN(err); } -/** Searches an index tree and positions a tree cursor on a given level. -This function will avoid latching the traversal path and so should be -used only for cases where-in latching is not needed. - -@param[in,out] index index -@param[in] level the tree level of search -@param[in] tuple data tuple; Note: n_fields_cmp in compared - to the node ptr page node field -@param[in] mode PAGE_CUR_L, .... - Insert should always be made using PAGE_CUR_LE - to search the position. -@param[in,out] cursor tree cursor; points to record of interest. -@param[in] file file name -@param[in[ line line where called from -@param[in,out] mtr mtr -@param[in] mark_dirty - if true then mark the block as dirty */ -dberr_t -btr_cur_search_to_nth_level_with_no_latch( - dict_index_t* index, - ulint level, - const dtuple_t* tuple, - page_cur_mode_t mode, - btr_cur_t* cursor, - const char* file, - ulint line, - mtr_t* mtr, - bool mark_dirty) -{ - page_t* page = NULL; /* remove warning */ - buf_block_t* block; - ulint height; - ulint up_match; - ulint low_match; - ulint rw_latch; - page_cur_mode_t page_mode; - ulint buf_mode; - page_cur_t* page_cursor; - ulint root_height = 0; /* remove warning */ - ulint n_blocks = 0; - dberr_t err = DB_SUCCESS; - mem_heap_t* heap = NULL; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets = offsets_; - rec_offs_init(offsets_); - - DBUG_ENTER("btr_cur_search_to_nth_level_with_no_latch"); - - ut_ad(dict_table_is_intrinsic(index->table)); - ut_ad(level == 0 || mode == PAGE_CUR_LE); - ut_ad(dict_index_check_search_tuple(index, tuple)); - ut_ad(dtuple_check_typed(tuple)); - ut_ad(index->page != FIL_NULL); - - UNIV_MEM_INVALID(&cursor->up_match, sizeof cursor->up_match); - UNIV_MEM_INVALID(&cursor->low_match, sizeof cursor->low_match); -#ifdef UNIV_DEBUG - cursor->up_match = ULINT_UNDEFINED; - cursor->low_match = ULINT_UNDEFINED; -#endif /* UNIV_DEBUG */ - - cursor->flag = BTR_CUR_BINARY; - cursor->index = index; - - page_cursor = btr_cur_get_page_cur(cursor); - - const ulint space = dict_index_get_space(index); - const page_size_t page_size(dict_table_page_size(index->table)); - /* Start with the root page. */ - page_id_t page_id(space, dict_index_get_page(index)); - - up_match = 0; - low_match = 0; - - height = ULINT_UNDEFINED; - - /* We use these modified search modes on non-leaf levels of the - B-tree. These let us end up in the right B-tree leaf. In that leaf - we use the original search mode. */ - - switch (mode) { - case PAGE_CUR_GE: - page_mode = PAGE_CUR_L; - break; - case PAGE_CUR_G: - page_mode = PAGE_CUR_LE; - break; - default: - page_mode = mode; - break; - } - - /* Loop and search until we arrive at the desired level */ - bool at_desired_level = false; - while (!at_desired_level) { - buf_mode = BUF_GET; - rw_latch = RW_NO_LATCH; - - ut_ad(n_blocks < BTR_MAX_LEVELS); - - block = buf_page_get_gen(page_id, page_size, rw_latch, NULL, - buf_mode, file, line, mtr, &err, mark_dirty); - - if (err != DB_SUCCESS) { - if (err == DB_DECRYPTION_FAILED) { - ib_push_warning((void *)NULL, - DB_DECRYPTION_FAILED, - "Table %s is encrypted but encryption service or" - " used key_id is not available. " - " Can't continue reading table.", - index->table->name); - index->table->is_encrypted = true; - } - - DBUG_RETURN(err); - } - - page = buf_block_get_frame(block); - - if (height == ULINT_UNDEFINED) { - /* We are in the root node */ - - height = btr_page_get_level(page, mtr); - root_height = height; - cursor->tree_height = root_height + 1; - } - - if (height == 0) { - /* On leaf level. Switch back to original search mode.*/ - page_mode = mode; - } - - page_cur_search_with_match( - block, index, tuple, page_mode, &up_match, - &low_match, page_cursor, NULL); - - ut_ad(height == btr_page_get_level( - page_cur_get_page(page_cursor), mtr)); - - if (level != height) { - - const rec_t* node_ptr; - ut_ad(height > 0); - - height--; - - node_ptr = page_cur_get_rec(page_cursor); - - offsets = rec_get_offsets( - node_ptr, index, offsets, - ULINT_UNDEFINED, &heap); - - /* Go to the child node */ - page_id.reset(space, btr_node_ptr_get_child_page_no( - node_ptr, offsets)); - - n_blocks++; - } else { - /* If this is the desired level, leave the loop */ - at_desired_level = true; - } - } - - cursor->low_match = low_match; - cursor->up_match = up_match; - - if (heap != NULL) { - mem_heap_free(heap); - } - - DBUG_RETURN(err); -} - /*****************************************************************//** Opens a cursor at either end of an index. */ dberr_t @@ -2556,125 +2385,6 @@ btr_cur_open_at_index_side_func( return err; } -/** Opens a cursor at either end of an index. -Avoid taking latches on buffer, just pin (by incrementing fix_count) -to keep them in buffer pool. This mode is used by intrinsic table -as they are not shared and so there is no need of latching. -@param[in] from_left true if open to low end, false if open - to high end. -@param[in] index index -@param[in,out] cursor cursor -@param[in] file file name -@param[in] line line where called -@param[in,out] mtr mini transaction -*/ -dberr_t -btr_cur_open_at_index_side_with_no_latch_func( - bool from_left, - dict_index_t* index, - btr_cur_t* cursor, - ulint level, - const char* file, - ulint line, - mtr_t* mtr) -{ - page_cur_t* page_cursor; - ulint height; - rec_t* node_ptr; - ulint n_blocks = 0; - mem_heap_t* heap = NULL; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets = offsets_; - dberr_t err = DB_SUCCESS; - rec_offs_init(offsets_); - - ut_ad(level != ULINT_UNDEFINED); - - page_cursor = btr_cur_get_page_cur(cursor); - cursor->index = index; - page_id_t page_id(dict_index_get_space(index), - dict_index_get_page(index)); - const page_size_t& page_size = dict_table_page_size(index->table); - - height = ULINT_UNDEFINED; - - for (;;) { - buf_block_t* block; - page_t* page; - ulint rw_latch = RW_NO_LATCH; - - ut_ad(n_blocks < BTR_MAX_LEVELS); - - block = buf_page_get_gen(page_id, page_size, rw_latch, NULL, - BUF_GET, file, line, mtr, &err); - - if (err != DB_SUCCESS) { - if (err == DB_DECRYPTION_FAILED) { - ib_push_warning((void *)NULL, - DB_DECRYPTION_FAILED, - "Table %s is encrypted but encryption service or" - " used key_id is not available. " - " Can't continue reading table.", - index->table->name); - index->table->is_encrypted = true; - } - - return (err); - } - - page = buf_block_get_frame(block); - - ut_ad(fil_page_index_page_check(page)); - ut_ad(index->id == btr_page_get_index_id(page)); - - if (height == ULINT_UNDEFINED) { - /* We are in the root node */ - - height = btr_page_get_level(page, mtr); - ut_a(height >= level); - } else { - /* TODO: flag the index corrupted if this fails */ - ut_ad(height == btr_page_get_level(page, mtr)); - } - - if (from_left) { - page_cur_set_before_first(block, page_cursor); - } else { - page_cur_set_after_last(block, page_cursor); - } - - if (height == level) { - break; - } - - ut_ad(height > 0); - - if (from_left) { - page_cur_move_to_next(page_cursor); - } else { - page_cur_move_to_prev(page_cursor); - } - - height--; - - node_ptr = page_cur_get_rec(page_cursor); - offsets = rec_get_offsets(node_ptr, cursor->index, offsets, - ULINT_UNDEFINED, &heap); - - /* Go to the child node */ - page_id.set_page_no( - btr_node_ptr_get_child_page_no(node_ptr, offsets)); - - n_blocks++; - } - - if (heap != NULL) { - mem_heap_free(heap); - } - - return(err); -} - /**********************************************************************//** Positions a cursor at a randomly chosen position within a B-tree. @return true if the index is available and we have put the cursor, false @@ -3097,11 +2807,8 @@ btr_cur_ins_lock_and_undo( return(err); } - /* Now we can fill in the roll ptr field in entry - (except if table is intrinsic) */ - - if (!(flags & BTR_KEEP_SYS_FLAG) - && !dict_table_is_intrinsic(index->table)) { + /* Now we can fill in the roll ptr field in entry */ + if (!(flags & BTR_KEEP_SYS_FLAG)) { row_upd_index_entry_sys_field(entry, index, DATA_ROLL_PTR, roll_ptr); @@ -3191,8 +2898,6 @@ btr_cur_optimistic_insert( page = buf_block_get_frame(block); index = cursor->index; - /* Block are not latched for insert if table is intrinsic - and index is auto-generated clustered index. */ ut_ad(mtr_is_block_fix(mtr, block, MTR_MEMO_PAGE_X_FIX, index->table)); ut_ad(!dict_index_is_online_ddl(index) || dict_index_is_clust(index) @@ -3311,26 +3016,18 @@ fail_err: { const rec_t* page_cursor_rec = page_cur_get_rec(page_cursor); - if (dict_table_is_intrinsic(index->table)) { - - index->rec_cache.rec_size = rec_size; - - *rec = page_cur_tuple_direct_insert( - page_cursor, entry, index, n_ext, mtr); - } else { - /* Check locks and write to the undo log, - if specified */ - err = btr_cur_ins_lock_and_undo(flags, cursor, entry, - thr, mtr, &inherit); - if (err != DB_SUCCESS) { - goto fail_err; - } - - *rec = page_cur_tuple_insert( - page_cursor, entry, index, offsets, heap, - n_ext, mtr); + /* Check locks and write to the undo log, + if specified */ + err = btr_cur_ins_lock_and_undo(flags, cursor, entry, + thr, mtr, &inherit); + if (err != DB_SUCCESS) { + goto fail_err; } + *rec = page_cur_tuple_insert( + page_cursor, entry, index, offsets, heap, + n_ext, mtr); + reorg = page_cursor_rec != page_cur_get_rec(page_cursor); } @@ -3347,13 +3044,6 @@ fail_err: goto fail; } else { - - /* For intrinsic table we take a consistent path - to re-organize using pessimistic path. */ - if (dict_table_is_intrinsic(index->table)) { - goto fail; - } - ut_ad(!reorg); /* If the record did not fit, reorganize */ @@ -3378,12 +3068,13 @@ fail_err: } #ifdef BTR_CUR_HASH_ADAPT - if (!index->disable_ahi) { - if (!reorg && leaf && (cursor->flag == BTR_CUR_HASH)) { - btr_search_update_hash_node_on_insert(cursor); - } else { - btr_search_update_hash_on_insert(cursor); - } +# ifdef MYSQL_INDEX_DISABLE_AHI + if (index->disable_ahi); else +# endif + if (!reorg && leaf && (cursor->flag == BTR_CUR_HASH)) { + btr_search_update_hash_node_on_insert(cursor); + } else { + btr_search_update_hash_on_insert(cursor); } #endif /* BTR_CUR_HASH_ADAPT */ @@ -3467,9 +3158,8 @@ btr_cur_pessimistic_insert( *big_rec = NULL; ut_ad(mtr_memo_contains_flagged( - mtr, dict_index_get_lock(btr_cur_get_index(cursor)), - MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(cursor->index->table)); + mtr, dict_index_get_lock(btr_cur_get_index(cursor)), + MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); ut_ad(mtr_is_block_fix( mtr, btr_cur_get_block(cursor), MTR_MEMO_PAGE_X_FIX, cursor->index->table)); @@ -3489,8 +3179,7 @@ btr_cur_pessimistic_insert( return(err); } - if (!(flags & BTR_NO_UNDO_LOG_FLAG) - || dict_table_is_intrinsic(index->table)) { + if (!(flags & BTR_NO_UNDO_LOG_FLAG)) { /* First reserve enough free space for the file segments of the index tree, so that the insert will not fail because of lack of space */ @@ -3577,9 +3266,10 @@ btr_cur_pessimistic_insert( } #ifdef BTR_CUR_ADAPT - if (!index->disable_ahi) { - btr_search_update_hash_on_insert(cursor); - } +# ifdef MYSQL_INDEX_DISABLE_AHI + if (index->disable_ahi); else +# endif + btr_search_update_hash_on_insert(cursor); #endif if (inherit && !(flags & BTR_NO_LOCKING_FLAG)) { @@ -3921,9 +3611,7 @@ btr_cur_update_in_place( index = cursor->index; ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); - ut_ad(trx_id > 0 - || (flags & BTR_KEEP_SYS_FLAG) - || dict_table_is_intrinsic(index->table)); + ut_ad(trx_id > 0 || (flags & BTR_KEEP_SYS_FLAG)); /* The insert buffer tree should never be updated in place. */ ut_ad(!dict_index_is_ibuf(index)); ut_ad(dict_index_is_online_ddl(index) == !!(flags & BTR_CREATE_FLAG) @@ -3970,8 +3658,7 @@ btr_cur_update_in_place( goto func_exit; } - if (!(flags & BTR_KEEP_SYS_FLAG) - && !dict_table_is_intrinsic(index->table)) { + if (!(flags & BTR_KEEP_SYS_FLAG)) { row_upd_rec_sys_fields(rec, NULL, index, offsets, thr_get_trx(thr), roll_ptr); } @@ -4087,9 +3774,7 @@ btr_cur_optimistic_update( page = buf_block_get_frame(block); rec = btr_cur_get_rec(cursor); index = cursor->index; - ut_ad(trx_id > 0 - || (flags & BTR_KEEP_SYS_FLAG) - || dict_table_is_intrinsic(index->table)); + ut_ad(trx_id > 0 || (flags & BTR_KEEP_SYS_FLAG)); ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); ut_ad(mtr_is_block_fix(mtr, block, MTR_MEMO_PAGE_X_FIX, index->table)); /* This is intended only for leaf page updates */ @@ -4275,8 +3960,7 @@ any_extern: page_cur_move_to_prev(page_cursor); - if (!(flags & BTR_KEEP_SYS_FLAG) - && !dict_table_is_intrinsic(index->table)) { + if (!(flags & BTR_KEEP_SYS_FLAG)) { row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR, roll_ptr); row_upd_index_entry_sys_field(new_entry, index, DATA_TRX_ID, @@ -4422,8 +4106,7 @@ btr_cur_pessimistic_update( ut_ad(mtr_memo_contains_flagged(mtr, dict_index_get_lock(index), MTR_MEMO_X_LOCK | - MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(index->table)); + MTR_MEMO_SX_LOCK)); ut_ad(mtr_is_block_fix(mtr, block, MTR_MEMO_PAGE_X_FIX, index->table)); #ifdef UNIV_ZIP_DEBUG ut_a(!page_zip || page_zip_validate(page_zip, page, index)); @@ -4431,8 +4114,7 @@ btr_cur_pessimistic_update( /* The insert buffer tree should never be updated in place. */ ut_ad(!dict_index_is_ibuf(index)); ut_ad(trx_id > 0 - || (flags & BTR_KEEP_SYS_FLAG) - || dict_table_is_intrinsic(index->table)); + || (flags & BTR_KEEP_SYS_FLAG)); ut_ad(dict_index_is_online_ddl(index) == !!(flags & BTR_CREATE_FLAG) || dict_index_is_clust(index)); ut_ad(thr_get_trx(thr)->id == trx_id @@ -4495,11 +4177,8 @@ btr_cur_pessimistic_update( ut_ad(rec_offs_validate(rec, index, *offsets)); n_ext += btr_push_update_extern_fields(new_entry, update, entry_heap); - /* UNDO logging is also turned-off during normal operation on intrinsic - table so condition needs to ensure that table is not intrinsic. */ if ((flags & BTR_NO_UNDO_LOG_FLAG) - && rec_offs_any_extern(*offsets) - && !dict_table_is_intrinsic(index->table)) { + && rec_offs_any_extern(*offsets)) { /* We are in a transaction rollback undoing a row update: we must free possible externally stored fields which got new values in the update, if they are not @@ -4575,8 +4254,7 @@ btr_cur_pessimistic_update( } } - if (!(flags & BTR_KEEP_SYS_FLAG) - && !dict_table_is_intrinsic(index->table)) { + if (!(flags & BTR_KEEP_SYS_FLAG)) { row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR, roll_ptr); row_upd_index_entry_sys_field(new_entry, index, DATA_TRX_ID, @@ -4682,7 +4360,7 @@ btr_cur_pessimistic_update( } } - if (big_rec_vec != NULL && !dict_table_is_intrinsic(index->table)) { + if (big_rec_vec != NULL) { ut_ad(page_is_leaf(page)); ut_ad(dict_index_is_clust(index)); ut_ad(flags & BTR_KEEP_POS_FLAG); @@ -4971,12 +4649,6 @@ btr_cur_del_mark_set_clust_rec( btr_rec_set_deleted_flag(rec, page_zip, TRUE); - /* For intrinsic table, roll-ptr is not maintained as there is no UNDO - logging. Skip updating it. */ - if (dict_table_is_intrinsic(index->table)) { - return(err); - } - trx = thr_get_trx(thr); /* This function must not be invoked during rollback (of a TRX_STATE_PREPARE transaction or otherwise). */ @@ -5175,16 +4847,9 @@ btr_cur_compress_if_useful( cursor position even if compression occurs */ mtr_t* mtr) /*!< in/out: mini-transaction */ { - /* Avoid applying compression as we don't accept lot of page garbage - given the workload of intrinsic table. */ - if (dict_table_is_intrinsic(cursor->index->table)) { - return(FALSE); - } - ut_ad(mtr_memo_contains_flagged( mtr, dict_index_get_lock(btr_cur_get_index(cursor)), - MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(cursor->index->table)); + MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); ut_ad(mtr_is_block_fix( mtr, btr_cur_get_block(cursor), MTR_MEMO_PAGE_X_FIX, cursor->index->table)); @@ -5368,8 +5033,7 @@ btr_cur_pessimistic_delete( || (flags & BTR_CREATE_FLAG)); ut_ad(mtr_memo_contains_flagged(mtr, dict_index_get_lock(index), MTR_MEMO_X_LOCK - | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(index->table)); + | MTR_MEMO_SX_LOCK)); ut_ad(mtr_is_block_fix(mtr, block, MTR_MEMO_PAGE_X_FIX, index->table)); ut_ad(mtr->is_named_space(index->space)); @@ -6914,13 +6578,11 @@ struct btr_blob_log_check_t { ut_ad(m_mtr->memo_contains_page_flagged( *m_rec, - MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX) - || dict_table_is_intrinsic(index->table)); + MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX)); ut_ad(mtr_memo_contains_flagged(m_mtr, dict_index_get_lock(index), - MTR_MEMO_SX_LOCK | MTR_MEMO_X_LOCK) - || dict_table_is_intrinsic(index->table)); + MTR_MEMO_SX_LOCK | MTR_MEMO_X_LOCK)); } }; @@ -6978,9 +6640,7 @@ btr_store_big_rec_extern_fields( ut_ad(rec_offs_any_extern(offsets)); ut_ad(btr_mtr); ut_ad(mtr_memo_contains_flagged(btr_mtr, dict_index_get_lock(index), - MTR_MEMO_X_LOCK - | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(index->table)); + MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); ut_ad(mtr_is_block_fix( btr_mtr, rec_block, MTR_MEMO_PAGE_X_FIX, index->table)); ut_ad(buf_block_get_frame(rec_block) == page_align(rec)); @@ -7479,9 +7139,7 @@ btr_free_externally_stored_field( ut_ad(dict_index_is_clust(index)); ut_ad(mtr_memo_contains_flagged(local_mtr, dict_index_get_lock(index), - MTR_MEMO_X_LOCK - | MTR_MEMO_SX_LOCK) - || dict_table_is_intrinsic(index->table)); + MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK)); ut_ad(mtr_is_page_fix( local_mtr, field_ref, MTR_MEMO_PAGE_X_FIX, index->table)); ut_ad(!rec || rec_offs_validate(rec, index, offsets)); diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc index a5da1b9fb0c..73399f14081 100644 --- a/storage/innobase/btr/btr0pcur.cc +++ b/storage/innobase/btr/btr0pcur.cc @@ -127,13 +127,14 @@ btr_pcur_store_position( ut_ad((mtr_memo_contains_flagged( mtr, dict_index_get_lock(index), MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK) - || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_S_FIX) - || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)) + || mtr_memo_contains_flagged(mtr, block, + MTR_MEMO_PAGE_S_FIX + | MTR_MEMO_PAGE_X_FIX)) && (block->page.buf_fix_count > 0)); } else { - ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_S_FIX) - || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX) - || dict_table_is_intrinsic(index->table)); + ut_ad(mtr_memo_contains_flagged(mtr, block, + MTR_MEMO_PAGE_S_FIX + | MTR_MEMO_PAGE_X_FIX)); } #endif /* UNIV_DEBUG */ @@ -283,13 +284,11 @@ btr_pcur_restore_position_func( ut_a(cursor->old_rec); ut_a(cursor->old_n_fields); - /* Optimistic latching involves S/X latch not required for - intrinsic table instead we would prefer to search fresh. */ - if ((latch_mode == BTR_SEARCH_LEAF - || latch_mode == BTR_MODIFY_LEAF - || latch_mode == BTR_SEARCH_PREV - || latch_mode == BTR_MODIFY_PREV) - && !dict_table_is_intrinsic(cursor->btr_cur.index->table)) { + switch (latch_mode) { + case BTR_SEARCH_LEAF: + case BTR_MODIFY_LEAF: + case BTR_SEARCH_PREV: + case BTR_MODIFY_PREV: /* Try optimistic restoration. */ if (!buf_pool_is_obsolete(cursor->withdraw_clock) @@ -422,7 +421,6 @@ btr_pcur_move_to_next_page( buf_block_t* next_block; page_t* next_page; ulint mode; - dict_table_t* table = btr_pcur_get_btr_cur(cursor)->index->table; ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->latch_mode != BTR_NO_LATCHES); @@ -444,12 +442,6 @@ btr_pcur_move_to_next_page( mode = BTR_MODIFY_LEAF; } - /* For intrinsic tables we avoid taking any latches as table is - accessed by only one thread at any given time. */ - if (dict_table_is_intrinsic(table)) { - mode = BTR_NO_LATCHES; - } - buf_block_t* block = btr_pcur_get_block(cursor); next_block = btr_block_get( @@ -523,32 +515,26 @@ btr_pcur_move_backward_from_page( prev_page_no = btr_page_get_prev(page, mtr); - /* For intrinsic table we don't do optimistic restore and so there is - no left block that is pinned that needs to be released. */ - if (!dict_table_is_intrinsic( - btr_cur_get_index(btr_pcur_get_btr_cur(cursor))->table)) { - - if (prev_page_no == FIL_NULL) { - } else if (btr_pcur_is_before_first_on_page(cursor)) { + if (prev_page_no == FIL_NULL) { + } else if (btr_pcur_is_before_first_on_page(cursor)) { - prev_block = btr_pcur_get_btr_cur(cursor)->left_block; + prev_block = btr_pcur_get_btr_cur(cursor)->left_block; - btr_leaf_page_release(btr_pcur_get_block(cursor), - latch_mode, mtr); + btr_leaf_page_release(btr_pcur_get_block(cursor), + latch_mode, mtr); - page_cur_set_after_last(prev_block, + page_cur_set_after_last(prev_block, btr_pcur_get_page_cur(cursor)); - } else { + } else { - /* The repositioned cursor did not end on an infimum - record on a page. Cursor repositioning acquired a latch - also on the previous page, but we do not need the latch: - release it. */ + /* The repositioned cursor did not end on an infimum + record on a page. Cursor repositioning acquired a latch + also on the previous page, but we do not need the latch: + release it. */ - prev_block = btr_pcur_get_btr_cur(cursor)->left_block; + prev_block = btr_pcur_get_btr_cur(cursor)->left_block; - btr_leaf_page_release(prev_block, latch_mode, mtr); - } + btr_leaf_page_release(prev_block, latch_mode, mtr); } cursor->latch_mode = latch_mode; diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index 4489775d46c..0af2a8b637c 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -1214,7 +1214,9 @@ retry: (buf_fix_count == 0 when DROP TABLE or similar is executing buf_LRU_drop_page_hash_for_tablespace()). */ ut_a(index == block->index); +#ifdef MYSQL_INDEX_DISABLE_AHI ut_ad(!index->disable_ahi); +#endif ut_ad(block->page.id.space() == index->space); ut_a(index_id == index->id); @@ -1437,7 +1439,10 @@ btr_search_build_page_hash_index( ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; - if (index->disable_ahi || !btr_search_enabled) { +#ifdef MYSQL_INDEX_DISABLE_AHI + if (index->disable_ahi) return; +#endif + if (!btr_search_enabled) { return; } @@ -1614,15 +1619,13 @@ btr_search_move_or_delete_hash_entries( buf_block_t* block, dict_index_t* index) { - /* AHI is disabled for intrinsic table as it depends on index-id - which is dynamically assigned for intrinsic table indexes and not - through a centralized index generator. */ - if (index->disable_ahi || !btr_search_enabled) { +#ifdef MYSQL_INDEX_DISABLE_AHI + if (index->disable_ahi) return; +#endif + if (!btr_search_enabled) { return; } - ut_ad(!dict_table_is_intrinsic(index->table)); - ut_ad(rw_lock_own(&(block->lock), RW_LOCK_X)); ut_ad(rw_lock_own(&(new_block->lock), RW_LOCK_X)); @@ -1681,7 +1684,10 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor) mem_heap_t* heap = NULL; rec_offs_init(offsets_); - if (cursor->index->disable_ahi || !btr_search_enabled) { +#ifdef MYSQL_INDEX_DISABLE_AHI + if (cursor->index->disable_ahi) return; +#endif + if (!btr_search_enabled) { return; } @@ -1740,7 +1746,10 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor) dict_index_t* index; rec_t* rec; - if (cursor->index->disable_ahi || !btr_search_enabled) { +#ifdef MYSQL_INDEX_DISABLE_AHI + if (cursor->index->disable_ahi) return; +#endif + if (!btr_search_enabled) { return; } @@ -1817,7 +1826,10 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor) ulint* offsets = offsets_; rec_offs_init(offsets_); - if (cursor->index->disable_ahi || !btr_search_enabled) { +#ifdef MYSQL_INDEX_DISABLE_AHI + if (cursor->index->disable_ahi) return; +#endif + if (!btr_search_enabled) { return; } @@ -1839,7 +1851,9 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor) rec = btr_cur_get_rec(cursor); +#ifdef MYSQL_INDEX_DISABLE_AHI ut_a(!index->disable_ahi); +#endif ut_a(index == cursor->index); ut_a(!dict_index_is_ibuf(index)); diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index f86f3bdef40..d3b4f12e69b 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1476,7 +1476,6 @@ buf_block_init( ut_d(block->page.file_page_was_freed = FALSE); block->index = NULL; - block->made_dirty_with_no_latch = false; block->skip_flush_check = false; ut_d(block->page.in_page_hash = FALSE); @@ -1714,12 +1713,25 @@ buf_chunk_not_freed( file pages. */ break; case BUF_BLOCK_FILE_PAGE: + if (srv_read_only_mode) { + /* The page cleaner is disabled in + read-only mode. No pages can be + dirtied, so all of them must be clean. */ + ut_ad(block->page.oldest_modification + == block->page.newest_modification); + ut_ad(block->page.oldest_modification == 0 + || block->page.oldest_modification + == recv_sys->recovered_lsn); + ut_ad(block->page.buf_fix_count == 0); + ut_ad(block->page.io_fix == BUF_IO_NONE); + break; + } + buf_page_mutex_enter(block); ready = buf_flush_ready_for_replace(&block->page); buf_page_mutex_exit(block); if (!ready) { - return(block); } @@ -3848,7 +3860,6 @@ buf_block_init_low( buf_block_t* block) /*!< in: block to init */ { block->index = NULL; - block->made_dirty_with_no_latch = false; block->skip_flush_check = false; block->n_hash_helps = 0; @@ -4117,9 +4128,6 @@ BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH, or BUF_GET_IF_IN_POOL_OR_WATCH @param[in] file file name @param[in] line line where called @param[in] mtr mini-transaction -@param[in] dirty_with_no_latch - mark page as dirty even if page - is being pinned without any latch @return pointer to the block or NULL */ buf_block_t* buf_page_get_gen( @@ -4131,8 +4139,7 @@ buf_page_get_gen( const char* file, ulint line, mtr_t* mtr, - dberr_t* err, - bool dirty_with_no_latch) + dberr_t* err) { buf_block_t* block; unsigned access_time; @@ -4415,11 +4422,9 @@ got_block: bpage = &block->page; if (fsp_is_system_temporary(page_id.space()) && buf_page_get_io_fix(bpage) != BUF_IO_NONE) { - /* This suggest that page is being flushed. + /* This suggests that the page is being flushed. Avoid returning reference to this page. - Instead wait for flush action to complete. - For normal page this sync is done using SX - lock but for intrinsic there is no latching. */ + Instead wait for the flush action to complete. */ buf_block_unfix(fix_block); os_thread_sleep(WAIT_FOR_WRITE); goto loop; @@ -4744,17 +4749,6 @@ got_block: and block->lock. */ buf_wait_for_read(fix_block); - /* Mark block as dirty if requested by caller. If not requested (false) - then we avoid updating the dirty state of the block and retain the - original one. This is reason why ? - Same block can be shared/pinned by 2 different mtrs. If first mtr - set the dirty state to true and second mtr mark it as false the last - updated dirty state is retained. Which means we can loose flushing of - a modified block. */ - if (dirty_with_no_latch) { - fix_block->made_dirty_with_no_latch = dirty_with_no_latch; - } - mtr_memo_type_t fix_type; switch (rw_latch) { diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index 31952424119..a34daede626 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -461,7 +461,7 @@ dict_build_tablespace_for_table( bool needs_file_per_table; char* filepath; - ut_ad(mutex_own(&dict_sys->mutex) || dict_table_is_intrinsic(table)); + ut_ad(mutex_own(&dict_sys->mutex)); needs_file_per_table = DICT_TF2_FLAG_IS_SET(table, DICT_TF2_USE_FILE_PER_TABLE); @@ -920,7 +920,7 @@ dict_build_index_def( dict_index_t* index, /*!< in/out: index */ trx_t* trx) /*!< in/out: InnoDB transaction handle */ { - ut_ad(mutex_own(&dict_sys->mutex) || dict_table_is_intrinsic(table)); + ut_ad(mutex_own(&dict_sys->mutex)); if (trx->table_id == 0) { /* Record only the first table id. */ @@ -930,18 +930,7 @@ dict_build_index_def( ut_ad((UT_LIST_GET_LEN(table->indexes) > 0) || dict_index_is_clust(index)); - if (!dict_table_is_intrinsic(table)) { - dict_hdr_get_new_id(NULL, &index->id, NULL, table, false); - } else { - /* Index are re-loaded in process of creation using id. - If same-id is used for all indexes only first index will always - be retrieved when expected is iterative return of all indexes*/ - if (UT_LIST_GET_LEN(table->indexes) > 0) { - index->id = UT_LIST_GET_LAST(table->indexes)->id + 1; - } else { - index->id = 1; - } - } + dict_hdr_get_new_id(NULL, &index->id, NULL, table, false); /* Inherit the space id from the table; we store all indexes of a table in the same tablespace */ @@ -1061,8 +1050,7 @@ dict_create_index_tree_in_mem( mtr_t mtr; ulint page_no = FIL_NULL; - ut_ad(mutex_own(&dict_sys->mutex) - || dict_table_is_intrinsic(index->table)); + ut_ad(mutex_own(&dict_sys->mutex)); if (index->type == DICT_FTS) { /* FTS index does not need an index tree */ @@ -1175,8 +1163,7 @@ dict_drop_index_tree_in_mem( const dict_index_t* index, /*!< in: index */ ulint page_no) /*!< in: index page-no */ { - ut_ad(mutex_own(&dict_sys->mutex) - || dict_table_is_intrinsic(index->table)); + ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(dict_table_is_temporary(index->table)); ulint root_page_no = page_no; @@ -1295,8 +1282,7 @@ dict_truncate_index_tree_in_mem( bool truncate; ulint space = index->space; - ut_ad(mutex_own(&dict_sys->mutex) - || dict_table_is_intrinsic(index->table)); + ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(dict_table_is_temporary(index->table)); ulint type = index->type; @@ -2509,12 +2495,7 @@ dict_create_add_foreigns_to_dictionary( dict_foreign_t* foreign; dberr_t error; - ut_ad(mutex_own(&dict_sys->mutex) - || dict_table_is_intrinsic(table)); - - if (dict_table_is_intrinsic(table)) { - goto exit_loop; - } + ut_ad(mutex_own(&dict_sys->mutex)); if (NULL == dict_table_get_low("SYS_FOREIGN")) { @@ -2540,7 +2521,6 @@ dict_create_add_foreigns_to_dictionary( } } -exit_loop: trx->op_info = "committing foreign key definitions"; if (trx_is_started(trx)) { @@ -2796,14 +2776,6 @@ dict_table_assign_new_id( dict_table_t* table, trx_t* trx) { - if (dict_table_is_intrinsic(table)) { - /* There is no significance of this table->id (if table is - intrinsic) so assign it default instead of something meaningful - to avoid confusion.*/ - table->id = ULINT_UNDEFINED; - } else { - dict_hdr_get_new_id(&table->id, NULL, NULL, table, false); - } - + dict_hdr_get_new_id(&table->id, NULL, NULL, table, false); trx->table_id = table->id; } diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 3d527c6b017..ddb96bf252c 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -502,21 +502,15 @@ dict_table_close( indexes after an aborted online index creation */ { - if (!dict_locked && !dict_table_is_intrinsic(table)) { + if (!dict_locked) { mutex_enter(&dict_sys->mutex); } - ut_ad(mutex_own(&dict_sys->mutex) || dict_table_is_intrinsic(table)); + ut_ad(mutex_own(&dict_sys->mutex)); ut_a(table->get_ref_count() > 0); table->release(); - /* Intrinsic table is not added to dictionary cache so skip other - cache specific actions. */ - if (dict_table_is_intrinsic(table)) { - return; - } - /* Force persistent stats re-read upon next open of the table so that FLUSH TABLE can be used to forcibly fetch stats from disk if they have been manually modified. We reset table->stat_initialized @@ -1388,18 +1382,12 @@ dict_table_add_system_columns( (so that they can be indexed by the numerical value of DATA_ROW_ID, etc.) and as the last columns of the table memory object. The clustered index will not always physically contain all system - columns. - Intrinsic table don't need DB_ROLL_PTR as UNDO logging is turned off - for these tables. */ + columns. */ dict_mem_table_add_col(table, heap, "DB_ROW_ID", DATA_SYS, DATA_ROW_ID | DATA_NOT_NULL, DATA_ROW_ID_LEN); -#if (DATA_ITT_N_SYS_COLS != 2) -#error "DATA_ITT_N_SYS_COLS != 2" -#endif - #if DATA_ROW_ID != 0 #error "DATA_ROW_ID != 0" #endif @@ -1410,20 +1398,18 @@ dict_table_add_system_columns( #error "DATA_TRX_ID != 1" #endif - if (!dict_table_is_intrinsic(table)) { - dict_mem_table_add_col(table, heap, "DB_ROLL_PTR", DATA_SYS, - DATA_ROLL_PTR | DATA_NOT_NULL, - DATA_ROLL_PTR_LEN); + dict_mem_table_add_col(table, heap, "DB_ROLL_PTR", DATA_SYS, + DATA_ROLL_PTR | DATA_NOT_NULL, + DATA_ROLL_PTR_LEN); #if DATA_ROLL_PTR != 2 #error "DATA_ROLL_PTR != 2" #endif - /* This check reminds that if a new system column is added to - the program, it should be dealt with here */ + /* This check reminds that if a new system column is added to + the program, it should be dealt with here */ #if DATA_N_SYS_COLS != 3 #error "DATA_N_SYS_COLS != 3" #endif - } } #ifndef UNIV_HOTBACKUP @@ -2654,7 +2640,7 @@ dict_index_add_to_cache_w_vcol( ulint i; ut_ad(index); - ut_ad(mutex_own(&dict_sys->mutex) || dict_table_is_intrinsic(table)); + ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(index->n_def == index->n_fields); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); ut_ad(!dict_index_is_online_ddl(index)); @@ -2687,9 +2673,10 @@ dict_index_add_to_cache_w_vcol( new_index->n_fields = new_index->n_def; new_index->trx_id = index->trx_id; new_index->set_committed(index->is_committed()); - new_index->allow_duplicates = index->allow_duplicates; new_index->nulls_equal = index->nulls_equal; +#ifdef MYSQL_INDEX_DISABLE_AHI new_index->disable_ahi = index->disable_ahi; +#endif if (dict_index_too_big_for_tree(table, new_index, strict)) { @@ -2771,39 +2758,7 @@ dict_index_add_to_cache_w_vcol( rw_lock_create(index_tree_rw_lock_key, &new_index->lock, SYNC_INDEX_TREE); - /* Intrinsic table are not added to dictionary cache instead are - cached to session specific thread cache. */ - if (!dict_table_is_intrinsic(table)) { - dict_sys->size += mem_heap_get_size(new_index->heap); - } - - /* Check if key part of the index is unique. */ - if (dict_table_is_intrinsic(table)) { - - new_index->rec_cache.fixed_len_key = true; - for (i = 0; i < new_index->n_uniq; i++) { - - const dict_field_t* field; - field = dict_index_get_nth_field(new_index, i); - - if (!field->fixed_len) { - new_index->rec_cache.fixed_len_key = false; - break; - } - } - - new_index->rec_cache.key_has_null_cols = false; - for (i = 0; i < new_index->n_uniq; i++) { - - const dict_field_t* field; - field = dict_index_get_nth_field(new_index, i); - - if (!(field->col->prtype & DATA_NOT_NULL)) { - new_index->rec_cache.key_has_null_cols = true; - break; - } - } - } + dict_sys->size += mem_heap_get_size(new_index->heap); dict_mem_index_free(index); @@ -2926,7 +2881,6 @@ dict_index_remove_from_cache_low( size = mem_heap_get_size(index->heap); - ut_ad(!dict_table_is_intrinsic(table)); ut_ad(dict_sys->size >= size); dict_sys->size -= size; @@ -2963,7 +2917,7 @@ dict_index_find_cols( ut_ad(table != NULL && index != NULL); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - ut_ad(mutex_own(&dict_sys->mutex) || dict_table_is_intrinsic(table)); + ut_ad(mutex_own(&dict_sys->mutex)); for (ulint i = 0; i < index->n_fields; i++) { ulint j; @@ -3285,7 +3239,7 @@ dict_index_build_internal_clust( ut_ad(dict_index_is_clust(index)); ut_ad(!dict_index_is_ibuf(index)); - ut_ad(mutex_own(&dict_sys->mutex) || dict_table_is_intrinsic(table)); + ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); /* Create a new index object with certainly enough fields */ @@ -3379,16 +3333,9 @@ dict_index_build_internal_clust( } } - /* UNDO logging is turned-off for intrinsic table and so - DATA_ROLL_PTR system columns are not added as default system - columns to such tables. */ - if (!dict_table_is_intrinsic(table)) { - - dict_index_add_col( - new_index, table, - dict_table_get_sys_col(table, DATA_ROLL_PTR), - 0); - } + dict_index_add_col( + new_index, table, + dict_table_get_sys_col(table, DATA_ROLL_PTR), 0); /* Remember the table columns already contained in new_index */ indexed = static_cast<ibool*>( @@ -3451,7 +3398,7 @@ dict_index_build_internal_non_clust( ut_ad(table && index); ut_ad(!dict_index_is_clust(index)); ut_ad(!dict_index_is_ibuf(index)); - ut_ad(mutex_own(&dict_sys->mutex) || dict_table_is_intrinsic(table)); + ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); /* The clustered index should be the first in the list of indexes */ diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index f38ad85e903..946919097c1 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -3179,7 +3179,7 @@ err_exit: ib::error() << "Table " << table->name << " in InnoDB" " data dictionary contains invalid flags." " SYS_TABLES.MIX_LEN=" << table->flags2; - table->flags2 &= ~(DICT_TF2_TEMPORARY|DICT_TF2_INTRINSIC); + table->flags2 &= ~DICT_TF2_TEMPORARY; dict_table_remove_from_cache(table); table = NULL; err = DB_FAIL; diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index a8f8e345728..e73c6196386 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -160,8 +160,6 @@ dict_mem_table_create( dict_table_autoinc_create_lazy(table); table->autoinc = 0; - table->sess_row_id = 0; - table->sess_trx_id = 0; /* The number of transactions that are either waiting on the AUTOINC lock or have been granted the lock. */ diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index cfb4903bb7a..596c6bdfdb0 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -4934,8 +4934,7 @@ fil_space_extend( fil_space_t* space, ulint size) { - /* In read-only mode we allow write to shared temporary tablespace - as intrinsic table created by Optimizer reside in this tablespace. */ + /* In read-only mode we allow writes to temporary tables. */ ut_ad(!srv_read_only_mode || fsp_is_system_temporary(space->id)); retry: diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 7d538dbd13a..d74f8cfa5bf 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1858,7 +1858,7 @@ fts_create_one_common_table( TRX_DICT_OP_TABLE. */ trx_dict_op_t op = trx_get_dict_operation(trx); - error = row_create_index_for_mysql(index, trx, NULL, NULL); + error = row_create_index_for_mysql(index, trx, NULL); trx->dict_operation = op; } @@ -1975,7 +1975,7 @@ fts_create_common_tables( op = trx_get_dict_operation(trx); - error = row_create_index_for_mysql(index, trx, NULL, NULL); + error = row_create_index_for_mysql(index, trx, NULL); trx->dict_operation = op; @@ -2067,7 +2067,7 @@ fts_create_one_index_table( trx_dict_op_t op = trx_get_dict_operation(trx); - error = row_create_index_for_mysql(index, trx, NULL, NULL); + error = row_create_index_for_mysql(index, trx, NULL); trx->dict_operation = op; } diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc index 2c0c5b453a3..39ad4fe7d7d 100644 --- a/storage/innobase/gis/gis0sea.cc +++ b/storage/innobase/gis/gis0sea.cc @@ -1569,8 +1569,6 @@ rtr_copy_buf( matches->block.curr_n_fields = block->curr_n_fields; matches->block.curr_left_side = block->curr_left_side; matches->block.index = block->index; - matches->block.made_dirty_with_no_latch - = block->made_dirty_with_no_latch; ut_d(matches->block.debug_latch = block->debug_latch); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index eb817b295af..4787dae9e72 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1790,13 +1790,6 @@ innobase_srv_conc_enter_innodb( } #endif /* WITH_WSREP */ - /* We rely on server to do external_lock(F_UNLCK) to reset the - srv_conc.n_active counter. Since there are no locks on instrinsic - tables, we should skip this for intrinsic temporary tables. */ - if (dict_table_is_intrinsic(prebuilt->table)) { - return; - } - trx_t* trx = prebuilt->trx; if (srv_thread_concurrency) { if (trx->n_tickets_to_enter_innodb > 0) { @@ -1835,13 +1828,6 @@ innobase_srv_conc_exit_innodb( } #endif /* WITH_WSREP */ - /* We rely on server to do external_lock(F_UNLCK) to reset the - srv_conc.n_active counter. Since there are no locks on instrinsic - tables, we should skip this for intrinsic temporary tab */ - if (dict_table_is_intrinsic(prebuilt->table)) { - return; - } - trx_t* trx = prebuilt->trx; #ifdef UNIV_DEBUG btrsea_sync_check check(trx->has_search_latch); @@ -1963,29 +1949,6 @@ thd_innodb_tmpdir( return(tmp_dir); } -/** Obtain the private handler of InnoDB session specific data. -@param[in,out] thd MySQL thread handler. -@return reference to private handler */ -MY_ATTRIBUTE((warn_unused_result)) -static -innodb_session_t*& -thd_to_innodb_session( - THD* thd) -{ - innodb_session_t*& innodb_session = - *(innodb_session_t**) thd_ha_data(thd, innodb_hton_ptr); - - if (innodb_session != NULL) { - return(innodb_session); - } - - innodb_session = UT_NEW_NOKEY(innodb_session_t()); - - thd_set_ha_data(thd, innodb_hton_ptr, innodb_session); - - return(innodb_session); -} - /** Obtain the InnoDB transaction of a MySQL thread. @param[in,out] thd MySQL thread handler. @return reference to transaction pointer */ @@ -1994,10 +1957,7 @@ trx_t*& thd_to_trx( THD* thd) { - innodb_session_t*& innodb_session = thd_to_innodb_session(thd); - ut_ad(innodb_session != NULL); - - return(innodb_session->m_trx); + return(*(trx_t**) thd_ha_data(thd, innodb_hton_ptr)); } #ifdef WITH_WSREP @@ -2013,47 +1973,6 @@ thd_to_trx_id( } #endif /* WITH_WSREP */ -/** Check if statement is of type INSERT .... SELECT that involves -use of intrinsic tables. -@param[in] thd thread handler -@return true if INSERT .... SELECT statement. */ -static inline -bool -thd_is_ins_sel_stmt(THD* user_thd) -{ - /* If the session involves use of intrinsic table - and it is trying to fetch the result from non-temporary tables - it indicates "insert .... select" statement. For non-temporary - table this is verifed using the locked tables count but for - intrinsic table as external_lock is not invoked this count is - not updated. - - Why is this needed ? - Use of AHI is blocked if statement is insert .... select statement. */ - innodb_session_t* innodb_priv = thd_to_innodb_session(user_thd); - return(innodb_priv->count_register_table_handler() > 0 ? true : false); -} - -/** Add the table handler to thread cache. -Obtain the InnoDB transaction of a MySQL thread. -@param[in,out] table table handler -@param[in,out] heap heap for allocating system columns. -@param[in,out] thd MySQL thread handler */ -static inline -void -add_table_to_thread_cache( - dict_table_t* table, - mem_heap_t* heap, - THD* thd) -{ - dict_table_add_system_columns(table, heap); - - dict_table_set_big_rows(table); - - innodb_session_t*& priv = thd_to_innodb_session(thd); - priv->register_table_handler(table->name.m_name, table); -} - /********************************************************************//** Call this function when mysqld passes control to the client. That is to avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more @@ -3110,16 +3029,12 @@ check_trx_exists( if (trx == NULL) { trx = innobase_trx_allocate(thd); - innodb_session_t* innodb_session = thd_to_innodb_session(thd); - innodb_session->m_trx = trx; - /* User trx can be forced to rollback, so we unset the disable flag. */ ut_ad(trx->in_innodb & TRX_FORCE_ROLLBACK_DISABLE); trx->in_innodb &= TRX_FORCE_ROLLBACK_MASK; } else { ut_a(trx->magic_n == TRX_MAGIC_N); - innobase_trx_init(thd, trx); } @@ -3362,8 +3277,7 @@ ha_innobase::update_thd( TrxInInnoDB trx_in_innodb(trx); - ut_ad(dict_table_is_intrinsic(m_prebuilt->table) - || trx_in_innodb.is_aborted() + ut_ad(trx_in_innodb.is_aborted() || (trx->dict_operation_lock_mode == 0 && trx->dict_operation == TRX_DICT_OP_NONE)); @@ -5620,10 +5534,6 @@ innobase_close_connection( trx_free_for_mysql(trx); } - UT_DELETE(thd_to_innodb_session(thd)); - - thd_to_innodb_session(thd) = NULL; - DBUG_RETURN(0); } @@ -6751,18 +6661,6 @@ ha_innobase::innobase_initialize_autoinc() col_name = field->field_name; - /* For intrinsic table, name of field has to be prefixed with - table name to maintain column-name uniqueness. */ - if (m_prebuilt->table != NULL - && dict_table_is_intrinsic(m_prebuilt->table)) { - - ulint col_no = dict_col_get_no(dict_table_get_nth_col( - m_prebuilt->table, field->field_index)); - - col_name = dict_table_get_col_name( - m_prebuilt->table, col_no); - } - index = innobase_get_index(table->s->next_number_index); /* Execute SELECT MAX(col_name) FROM TABLE; */ @@ -6874,18 +6772,7 @@ ha_innobase::open( ignore_err = DICT_ERR_IGNORE_FK_NOKEY; } - /* Get pointer to a table object in InnoDB dictionary cache. - For intrinsic table, get it from session private data */ - ib_table = thd_to_innodb_session(thd)->lookup_table_handler(norm_name); - - if (ib_table == NULL) { - - ib_table = open_dict_table(name, norm_name, is_part, - ignore_err); - } else { - ib_table->acquire(); - ut_ad(dict_table_is_intrinsic(ib_table)); - } + ib_table = open_dict_table(name, norm_name, is_part, ignore_err); if (ib_table != NULL && ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) @@ -8763,18 +8650,10 @@ ha_innobase::innobase_lock_autoinc(void) { DBUG_ENTER("ha_innobase::innobase_lock_autoinc"); dberr_t error = DB_SUCCESS; - long lock_mode = innobase_autoinc_lock_mode; - - ut_ad(!srv_read_only_mode - || dict_table_is_intrinsic(m_prebuilt->table)); - if (dict_table_is_intrinsic(m_prebuilt->table)) { - /* Intrinsic table are not shared accorss connection - so there is no need to AUTOINC lock the table. */ - lock_mode = AUTOINC_NO_LOCKING; - } + ut_ad(!srv_read_only_mode); - switch (lock_mode) { + switch (innobase_autoinc_lock_mode) { case AUTOINC_NO_LOCKING: /* Acquire only the AUTOINC mutex. */ dict_table_autoinc_lock(m_prebuilt->table); @@ -8850,30 +8729,6 @@ ha_innobase::innobase_set_max_autoinc( return(error); } -/** Write Row interface optimized for intrinisc table. -@param[in] record a row in MySQL format. -@return 0 on success or error code */ -int -ha_innobase::intrinsic_table_write_row(uchar* record) -{ - dberr_t err; - - /* No auto-increment support for intrinsic table. */ - ut_ad(!(table->next_number_field && record == table->record[0])); - - if (m_prebuilt->mysql_template == NULL - || m_prebuilt->template_type != ROW_MYSQL_WHOLE_ROW) { - /* Build the template used in converting quickly between - the two database formats */ - build_template(true); - } - - err = row_insert_for_mysql((byte*) record, m_prebuilt); - - return(convert_error_code_to_mysql( - err, m_prebuilt->table->flags, m_user_thd)); -} - /********************************************************************//** Stores a row in an InnoDB database, to the table specified in this handle. @@ -8894,15 +8749,10 @@ ha_innobase::write_row( DBUG_ENTER("ha_innobase::write_row"); - if (dict_table_is_intrinsic(m_prebuilt->table)) { - DBUG_RETURN(intrinsic_table_write_row(record)); - } - trx_t* trx = thd_to_trx(m_user_thd); TrxInInnoDB trx_in_innodb(trx); - if (!dict_table_is_intrinsic(m_prebuilt->table) - && trx_in_innodb.is_aborted()) { + if (trx_in_innodb.is_aborted()) { innobase_rollback(ht, m_user_thd, false); @@ -9349,7 +9199,7 @@ calc_row_difference( doc_id_t doc_id = FTS_NULL_DOC_ID; ulint num_v = 0; - ut_ad(!srv_read_only_mode || dict_table_is_intrinsic(prebuilt->table)); + ut_ad(!srv_read_only_mode); n_fields = table->s->fields; clust_index = dict_table_get_first_index(prebuilt->table); @@ -9823,7 +9673,7 @@ ha_innobase::update_row( ut_a(m_prebuilt->trx == trx); - if (high_level_read_only && !dict_table_is_intrinsic(m_prebuilt->table)) { + if (high_level_read_only) { ib_senderrf(ha_thd(), IB_LOG_LEVEL_WARN, ER_READ_ONLY_MODE); DBUG_RETURN(HA_ERR_TABLE_READONLY); } else if (!trx_is_started(trx)) { @@ -9873,8 +9723,7 @@ ha_innobase::update_row( goto func_exit; } - if (!dict_table_is_intrinsic(m_prebuilt->table) - && TrxInInnoDB::is_aborted(trx)) { + if (TrxInInnoDB::is_aborted(trx)) { innobase_rollback(ht, m_user_thd, false); @@ -9988,8 +9837,7 @@ ha_innobase::delete_row( DBUG_ENTER("ha_innobase::delete_row"); - if (!dict_table_is_intrinsic(m_prebuilt->table) - && trx_in_innodb.is_aborted()) { + if (trx_in_innodb.is_aborted()) { innobase_rollback(ht, m_user_thd, false); @@ -9999,7 +9847,7 @@ ha_innobase::delete_row( ut_a(m_prebuilt->trx == trx); - if (high_level_read_only && !dict_table_is_intrinsic(m_prebuilt->table)) { + if (high_level_read_only) { ib_senderrf(ha_thd(), IB_LOG_LEVEL_WARN, ER_READ_ONLY_MODE); DBUG_RETURN(HA_ERR_TABLE_READONLY); } else if (!trx_is_started(trx)) { @@ -10049,28 +9897,7 @@ int ha_innobase::delete_all_rows() { DBUG_ENTER("ha_innobase::delete_all_rows"); - - /* Currently enabled only for intrinsic tables. */ - if (!dict_table_is_intrinsic(m_prebuilt->table)) { - DBUG_RETURN(HA_ERR_WRONG_COMMAND); - } - - TrxInInnoDB trx_in_innodb(m_prebuilt->trx); - - if (!dict_table_is_intrinsic(m_prebuilt->table) - && trx_in_innodb.is_aborted()) { - - DBUG_RETURN(innobase_rollback(ht, m_user_thd, false)); - } - - dberr_t error = row_delete_all_rows(m_prebuilt->table); - - if (error == DB_SUCCESS) { - dict_stats_update(m_prebuilt->table, DICT_STATS_EMPTY_TABLE); - } - - DBUG_RETURN(convert_error_code_to_mysql( - error, m_prebuilt->table->flags, m_user_thd)); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); } /**********************************************************************//** @@ -10084,11 +9911,7 @@ ha_innobase::unlock_row(void) { DBUG_ENTER("ha_innobase::unlock_row"); - /* Consistent read does not take any locks, thus there is - nothing to unlock. There is no locking for intrinsic table. */ - - if (m_prebuilt->select_lock_type == LOCK_NONE - || dict_table_is_intrinsic(m_prebuilt->table)) { + if (m_prebuilt->select_lock_type == LOCK_NONE) { DBUG_VOID_RETURN; } @@ -10098,8 +9921,6 @@ ha_innobase::unlock_row(void) DBUG_VOID_RETURN; } - ut_ad(!dict_table_is_intrinsic(m_prebuilt->table)); - /* Ideally, this assert must be in the beginning of the function. But there are some calls to this function from the SQL layer when the transaction is in state TRX_STATE_NOT_STARTED. The check on @@ -10187,8 +10008,6 @@ ha_innobase::index_end(void) { DBUG_ENTER("index_end"); - m_prebuilt->index->last_sel_cur->release(); - active_index = MAX_KEY; in_range_check_pushed_down = FALSE; @@ -10390,29 +10209,17 @@ ha_innobase::index_read( innobase_srv_conc_enter_innodb(m_prebuilt); - if (!dict_table_is_intrinsic(m_prebuilt->table)) { - - if (TrxInInnoDB::is_aborted(m_prebuilt->trx)) { - - innobase_rollback(ht, m_user_thd, false); - - DBUG_RETURN(convert_error_code_to_mysql( - DB_FORCED_ABORT, 0, m_user_thd)); - } - - m_prebuilt->ins_sel_stmt = thd_is_ins_sel_stmt( - m_user_thd); + if (TrxInInnoDB::is_aborted(m_prebuilt->trx)) { - ret = row_search_mvcc( - buf, mode, m_prebuilt, match_mode, 0); + innobase_rollback(ht, m_user_thd, false); - } else { - m_prebuilt->session = thd_to_innodb_session(m_user_thd); - - ret = row_search_no_mvcc( - buf, mode, m_prebuilt, match_mode, 0); + DBUG_RETURN(convert_error_code_to_mysql( + DB_FORCED_ABORT, 0, m_user_thd)); } + ret = row_search_mvcc( + buf, mode, m_prebuilt, match_mode, 0); + innobase_srv_conc_exit_innodb(m_prebuilt); } else { @@ -10592,8 +10399,7 @@ ha_innobase::change_active_index( TrxInInnoDB trx_in_innodb(m_prebuilt->trx); - if (!dict_table_is_intrinsic(m_prebuilt->table) - && trx_in_innodb.is_aborted()) { + if (trx_in_innodb.is_aborted()) { innobase_rollback(ht, m_user_thd, false); @@ -10720,9 +10526,7 @@ ha_innobase::general_fetch( ut_ad(trx == thd_to_trx(m_user_thd)); - bool intrinsic = dict_table_is_intrinsic(m_prebuilt->table); - - if (!intrinsic && TrxInInnoDB::is_aborted(trx)) { + if (TrxInInnoDB::is_aborted(trx)) { innobase_rollback(ht, m_user_thd, false); @@ -10732,17 +10536,8 @@ ha_innobase::general_fetch( innobase_srv_conc_enter_innodb(m_prebuilt); - if (!intrinsic) { - - ret = row_search_mvcc( - buf, PAGE_CUR_UNSUPP, m_prebuilt, match_mode, - direction); - - } else { - ret = row_search_no_mvcc( - buf, PAGE_CUR_UNSUPP, m_prebuilt, match_mode, - direction); - } + ret = row_search_mvcc( + buf, PAGE_CUR_UNSUPP, m_prebuilt, match_mode, direction); innobase_srv_conc_exit_innodb(m_prebuilt); @@ -10896,8 +10691,7 @@ ha_innobase::rnd_init( { TrxInInnoDB trx_in_innodb(m_prebuilt->trx); - if (!dict_table_is_intrinsic(m_prebuilt->table) - && trx_in_innodb.is_aborted()) { + if (trx_in_innodb.is_aborted()) { return(innobase_rollback(ht, m_user_thd, false)); } @@ -12147,25 +11941,6 @@ create_table_info_t::create_table_def() continue; } - /* Generate a unique column name by pre-pending table-name for - intrinsic tables. For other tables (including normal - temporary) column names are unique. If not, MySQL layer will - block such statement. - This is work-around fix till Optimizer can handle this issue - (probably 5.7.4+). */ - char field_name[MAX_FULL_NAME_LEN + 2 + 10]; - - if (dict_table_is_intrinsic(table) && field->orig_table) { - - ut_snprintf(field_name, sizeof(field_name), - "%s_%s_%lu", field->orig_table->alias.c_ptr(), - field->field_name, i); - - } else { - ut_snprintf(field_name, sizeof(field_name), - "%s", field->field_name); - } - col_type = get_innobase_type_from_mysql_type( &unsigned_type, field); @@ -12241,9 +12016,9 @@ create_table_info_t::create_table_def() /* First check whether the column to be added has a system reserved name. */ - if (dict_col_name_is_reserved(field_name)){ + if (dict_col_name_is_reserved(field->field_name)){ my_error(ER_WRONG_COLUMN_NAME, MYF(0), - field_name); + field->field_name); err_col: dict_mem_table_free(table); mem_heap_free(heap); @@ -12255,7 +12030,7 @@ err_col: if (!is_virtual) { dict_mem_table_add_col(table, heap, - field_name, col_type, + field->field_name, col_type, dtype_form_prtype( (ulint) field->type() | nulls_allowed | unsigned_type @@ -12265,7 +12040,7 @@ err_col: } else { #ifdef MYSQL_VIRTUAL_COLUMNS dict_mem_table_add_v_col(table, heap, - field_name, col_type, + field->field_name, col_type, dtype_form_prtype( (ulint) field->type() | nulls_allowed | unsigned_type @@ -12381,18 +12156,8 @@ err_col: temp_table_heap = mem_heap_create(256); - /* For intrinsic table (given that they are - not shared beyond session scope), add - it to session specific THD structure - instead of adding it to dictionary cache. */ - if (dict_table_is_intrinsic(table)) { - add_table_to_thread_cache( - table, temp_table_heap, m_thd); - - } else { - dict_table_add_to_cache( - table, FALSE, temp_table_heap); - } + dict_table_add_to_cache( + table, FALSE, temp_table_heap); DBUG_EXECUTE_IF("ib_ddl_crash_during_create2", DBUG_SUICIDE();); @@ -12575,7 +12340,7 @@ create_index( DBUG_RETURN(convert_error_code_to_mysql( row_create_index_for_mysql( - index, trx, NULL, NULL), + index, trx, NULL), flags, NULL)); } @@ -12606,26 +12371,6 @@ create_index( index = dict_mem_index_create(table_name, key->name, 0, ind_type, key->user_defined_key_parts); - innodb_session_t*& priv = thd_to_innodb_session(trx->mysql_thd); - dict_table_t* handler = priv->lookup_table_handler(table_name); - - if (handler != NULL) { - /* This setting will enforce SQL NULL == SQL NULL. - For now this is turned-on for intrinsic tables - only but can be turned on for other tables if needed arises. */ - index->nulls_equal = - (key->flags & HA_NULL_ARE_EQUAL) ? true : false; - - /* Disable use of AHI for intrinsic table indexes as AHI - validates the predicated entry using index-id which has to be - system-wide unique that is not the case with indexes of - intrinsic table for performance reason. - Also given the lifetime of these tables and frequent delete - and update AHI would not help on performance front as it does - with normal tables. */ - index->disable_ahi = true; - } - for (ulint i = 0; i < key->user_defined_key_parts; i++) { KEY_PART_INFO* key_part = key->key_part + i; ulint prefix_len; @@ -12649,13 +12394,6 @@ create_index( ut_error; const char* field_name = key_part->field->field_name; - if (handler != NULL && dict_table_is_intrinsic(handler)) { - - ut_ad(!innobase_is_v_fld(key_part->field)); - ulint col_no = dict_col_get_no(dict_table_get_nth_col( - handler, key_part->field->field_index)); - field_name = dict_table_get_col_name(handler, col_no); - } col_type = get_innobase_type_from_mysql_type( &is_unsigned, key_part->field); @@ -12705,13 +12443,9 @@ create_index( sure we don't create too long indexes. */ error = convert_error_code_to_mysql( - row_create_index_for_mysql(index, trx, field_lengths, handler), + row_create_index_for_mysql(index, trx, field_lengths), flags, NULL); - if (error && handler != NULL) { - priv->unregister_table_handler(table_name); - } - my_free(field_lengths); DBUG_RETURN(error); @@ -12737,26 +12471,7 @@ create_clustered_index_when_no_primary( innobase_index_reserve_name, 0, DICT_CLUSTERED, 0); - innodb_session_t*& priv = thd_to_innodb_session(trx->mysql_thd); - - dict_table_t* handler = priv->lookup_table_handler(table_name); - - if (handler != NULL) { - /* Disable use of AHI for intrinsic table indexes as AHI - validates the predicated entry using index-id which has to be - system-wide unique that is not the case with indexes of - intrinsic table for performance reason. - Also given the lifetime of these tables and frequent delete - and update AHI would not help on performance front as it does - with normal tables. */ - index->disable_ahi = true; - } - - error = row_create_index_for_mysql(index, trx, NULL, handler); - - if (error != DB_SUCCESS && handler != NULL) { - priv->unregister_table_handler(table_name); - } + error = row_create_index_for_mysql(index, trx, NULL); return(convert_error_code_to_mysql(error, flags, NULL)); } @@ -13873,22 +13588,6 @@ index_bad: if (m_create_info->options & HA_LEX_CREATE_TMP_TABLE) { m_flags2 |= DICT_TF2_TEMPORARY; - /* Intrinsic tables reside only in the shared temporary - tablespace and we will always use ROW_FORMAT=DYNAMIC. */ - -#ifdef MYSQL_COMPRESSION - if ((m_create_info->options & HA_LEX_CREATE_INTERNAL_TMP_TABLE) - && !m_use_file_per_table) { - - /* We do not allow compressed instrinsic - temporary tables. */ - - ut_ad(zip_ssize == 0); - m_flags2 |= DICT_TF2_INTRINSIC; - innodb_row_format = REC_FORMAT_DYNAMIC; - } -#endif - } /* Set the table flags */ @@ -14199,7 +13898,7 @@ create_table_info_t::prepare_create_table( DBUG_RETURN(HA_WRONG_CREATE_OPTION); } - if (high_level_read_only && !is_intrinsic_temp_table()) { + if (high_level_read_only) { DBUG_RETURN(HA_ERR_TABLE_READONLY); } @@ -14343,17 +14042,7 @@ create_table_info_t::create_table() stmt = innobase_get_stmt_unsafe(m_thd, &stmt_len); - innodb_session_t*& priv = - thd_to_innodb_session(m_trx->mysql_thd); - dict_table_t* handler = - priv->lookup_table_handler(m_table_name); - - ut_ad(handler == NULL - || (handler != NULL && dict_table_is_intrinsic(handler))); - - /* There is no concept of foreign key for intrinsic tables. */ - if (stmt && (handler == NULL)) { - + if (stmt) { dberr_t err = row_table_add_foreign_constraints( m_trx, stmt, stmt_len, m_table_name, m_create_info->options & HA_LEX_CREATE_TMP_TABLE); @@ -14399,23 +14088,15 @@ create_table_info_t::create_table() error = convert_error_code_to_mysql(err, m_flags, NULL); if (error) { - if (handler != NULL) { - priv->unregister_table_handler(m_table_name); - } DBUG_RETURN(error); } } - if (!is_intrinsic_temp_table()) { - innobase_table = dict_table_open_on_name( - m_table_name, TRUE, FALSE, DICT_ERR_IGNORE_NONE); - - if (innobase_table != NULL) { - dict_table_close(innobase_table, TRUE, FALSE); - } + innobase_table = dict_table_open_on_name( + m_table_name, TRUE, FALSE, DICT_ERR_IGNORE_NONE); - } else { - innobase_table = NULL; + if (innobase_table != NULL) { + dict_table_close(innobase_table, TRUE, FALSE); } DBUG_RETURN(0); @@ -14430,17 +14111,8 @@ create_table_info_t::create_table_update_dict() DBUG_ENTER("create_table_update_dict"); - innobase_table = thd_to_innodb_session(m_thd)->lookup_table_handler( - m_table_name); - - - if (innobase_table == NULL) { - innobase_table = dict_table_open_on_name( - m_table_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); - } else { - innobase_table->acquire(); - ut_ad(dict_table_is_intrinsic(innobase_table)); - } + innobase_table = dict_table_open_on_name( + m_table_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); DBUG_ASSERT(innobase_table != 0); if (innobase_table->fts != NULL) { @@ -14574,13 +14246,8 @@ ha_innobase::create( /* Latch the InnoDB data dictionary exclusively so that no deadlocks or lock waits can happen in it during a table create operation. - Drop table etc. do this latching in row0mysql.cc. - Avoid locking dictionary if table is intrinsic. - Table Object for such table is cached in THD instead of storing it - to dictionary. */ - if (!info.is_intrinsic_temp_table()) { - row_mysql_lock_data_dictionary(trx); - } + Drop table etc. do this latching in row0mysql.cc. */ + row_mysql_lock_data_dictionary(trx); if ((error = info.create_table())) { goto cleanup; @@ -14588,14 +14255,12 @@ ha_innobase::create( innobase_commit_low(trx); - if (!info.is_intrinsic_temp_table()) { - ut_ad(!srv_read_only_mode); - row_mysql_unlock_data_dictionary(trx); - /* Flush the log to reduce probability that the .frm files and - the InnoDB data dictionary get out-of-sync if the user runs - with innodb_flush_log_at_trx_commit = 0 */ - log_buffer_flush_to_disk(); - } + ut_ad(!srv_read_only_mode); + row_mysql_unlock_data_dictionary(trx); + /* Flush the log to reduce probability that the .frm files and + the InnoDB data dictionary get out-of-sync if the user runs + with innodb_flush_log_at_trx_commit = 0 */ + log_buffer_flush_to_disk(); error = info.create_table_update_dict(); @@ -14610,38 +14275,7 @@ ha_innobase::create( cleanup: trx_rollback_for_mysql(trx); - - if (!info.is_intrinsic_temp_table()) { - row_mysql_unlock_data_dictionary(trx); - } else { - THD* thd = info.thd(); - - dict_table_t* intrinsic_table = - thd_to_innodb_session(thd)->lookup_table_handler( - info.table_name()); - - if (intrinsic_table != NULL) { - thd_to_innodb_session(thd)->unregister_table_handler( - info.table_name()); - - for (;;) { - dict_index_t* index; - index = UT_LIST_GET_FIRST( - intrinsic_table->indexes); - if (index == NULL) { - break; - } - rw_lock_free(&index->lock); - UT_LIST_REMOVE(intrinsic_table->indexes, index); - dict_mem_index_free(index); - index = NULL; - } - - dict_mem_table_free(intrinsic_table); - intrinsic_table = NULL; - } - } - + row_mysql_unlock_data_dictionary(trx); trx_free_for_mysql(trx); DBUG_RETURN(error); @@ -14796,11 +14430,6 @@ ha_innobase::truncate() { DBUG_ENTER("ha_innobase::truncate"); - /* Truncate of intrinsic table is not allowed truncate for now. */ - if (dict_table_is_intrinsic(m_prebuilt->table)) { - DBUG_RETURN(HA_ERR_WRONG_COMMAND); - } - if (high_level_read_only) { DBUG_RETURN(HA_ERR_TABLE_READONLY); } @@ -14879,17 +14508,7 @@ ha_innobase::delete_table( extension, in contrast to ::create */ normalize_table_name(norm_name, name); - innodb_session_t*& priv = thd_to_innodb_session(thd); - dict_table_t* handler = priv->lookup_table_handler(norm_name); - - if (handler != NULL) { - for (dict_index_t* index = UT_LIST_GET_FIRST(handler->indexes); - index != NULL; - index = UT_LIST_GET_NEXT(indexes, index)) { - index->last_ins_cur->release(); - index->last_sel_cur->release(); - } - } else if (srv_read_only_mode) { + if (srv_read_only_mode) { DBUG_RETURN(HA_ERR_TABLE_READONLY); } @@ -14935,7 +14554,7 @@ ha_innobase::delete_table( err = row_drop_table_for_mysql( norm_name, trx, thd_sql_command(thd) == SQLCOM_DROP_DB, - false, handler); + false); if (err == DB_TABLE_NOT_FOUND && innobase_get_lower_case_table_names() == 1) { @@ -15035,20 +14654,16 @@ ha_innobase::delete_table( err = row_drop_table_for_mysql( par_case_name, trx, thd_sql_command(thd) == SQLCOM_DROP_DB, - true, handler); + true); } } - if (handler == NULL) { - ut_ad(!srv_read_only_mode); - /* Flush the log to reduce probability that the .frm files and - the InnoDB data dictionary get out-of-sync if the user runs - with innodb_flush_log_at_trx_commit = 0 */ + ut_ad(!srv_read_only_mode); + /* Flush the log to reduce probability that the .frm files and + the InnoDB data dictionary get out-of-sync if the user runs + with innodb_flush_log_at_trx_commit = 0 */ - log_buffer_flush_to_disk(); - } else if (err == DB_SUCCESS) { - priv->unregister_table_handler(norm_name); - } + log_buffer_flush_to_disk(); innobase_commit_low(trx); @@ -16667,9 +16282,8 @@ ha_innobase::info_low( nor the CHECK TABLE time, nor the UPDATE or INSERT time. */ if (os_file_get_status( - path, &stat_info, false, - (dict_table_is_intrinsic(ib_table) - ? false : srv_read_only_mode)) == DB_SUCCESS) { + path, &stat_info, false, + srv_read_only_mode) == DB_SUCCESS) { stats.create_time = (ulong) stat_info.ctime; } } @@ -16732,72 +16346,6 @@ ha_innobase::info( return(info_low(flag, false /* not ANALYZE */)); } -/** Enable indexes. -@param[in] mode enable index mode. -@return HA_ERR_* error code or 0 */ -int -ha_innobase::enable_indexes( - uint mode) -{ - int error = HA_ERR_WRONG_COMMAND; - - /* Enable index only for intrinsic table. Behavior for all other - table continue to remain same. */ - - if (dict_table_is_intrinsic(m_prebuilt->table)) { - ut_ad(mode == HA_KEY_SWITCH_ALL); - for (dict_index_t* index - = UT_LIST_GET_FIRST(m_prebuilt->table->indexes); - index != NULL; - index = UT_LIST_GET_NEXT(indexes, index)) { - - /* InnoDB being clustered index we can't disable/enable - clustered index itself. */ - if (dict_index_is_clust(index)) { - continue; - } - - index->allow_duplicates = false; - } - error = 0; - } - - return(error); -} - -/** Disable indexes. -@param[in] mode disable index mode. -@return HA_ERR_* error code or 0 */ -int -ha_innobase::disable_indexes( - uint mode) -{ - int error = HA_ERR_WRONG_COMMAND; - - /* Disable index only for intrinsic table. Behavior for all other - table continue to remain same. */ - - if (dict_table_is_intrinsic(m_prebuilt->table)) { - ut_ad(mode == HA_KEY_SWITCH_ALL); - for (dict_index_t* index - = UT_LIST_GET_FIRST(m_prebuilt->table->indexes); - index != NULL; - index = UT_LIST_GET_NEXT(indexes, index)) { - - /* InnoDB being clustered index we can't disable/enable - clustered index itself. */ - if (dict_index_is_clust(index)) { - continue; - } - - index->allow_duplicates = true; - } - error = 0; - } - - return(error); -} - /* Updates index cardinalities of the table, based on random dives into each index tree. This does NOT calculate exact statistics on the table. @@ -17921,16 +17469,6 @@ ha_innobase::start_stmt( TrxInInnoDB trx_in_innodb(trx); - if (dict_table_is_intrinsic(m_prebuilt->table)) { - - if (thd_sql_command(thd) == SQLCOM_ALTER_TABLE) { - - DBUG_RETURN(HA_ERR_WRONG_COMMAND); - } - - DBUG_RETURN(0); - } - trx = m_prebuilt->trx; innobase_srv_conc_force_exit_innodb(trx); @@ -18060,18 +17598,6 @@ ha_innobase::external_lock( ut_ad(m_prebuilt->table); - if (dict_table_is_intrinsic(m_prebuilt->table)) { - - if (thd_sql_command(thd) == SQLCOM_ALTER_TABLE) { - - DBUG_RETURN(HA_ERR_WRONG_COMMAND); - } - - TrxInInnoDB::begin_stmt(trx); - - DBUG_RETURN(0); - } - /* Statement based binlogging does not work in isolation level READ UNCOMMITTED and READ COMMITTED since the necessary locks cannot be taken. In this case, we print an @@ -18994,7 +18520,6 @@ ha_innobase::store_lock( const uint sql_command = thd_sql_command(thd); if (srv_read_only_mode - && !dict_table_is_intrinsic(m_prebuilt->table) && (sql_command == SQLCOM_UPDATE || sql_command == SQLCOM_INSERT || sql_command == SQLCOM_REPLACE diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 84feea119c1..1c71735d716 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -203,9 +203,6 @@ public: int ft_read(uchar* buf); - int enable_indexes(uint mode); - int disable_indexes(uint mode); - void position(const uchar *record); int info(uint); @@ -468,9 +465,6 @@ protected: @see build_template() */ void reset_template(); - /** Write Row Interface optimized for Intrinsic table. */ - int intrinsic_table_write_row(uchar* record); - protected: inline void update_thd(THD* thd); void update_thd(); @@ -833,14 +827,6 @@ public: THD* thd() const { return(m_thd); } - inline bool is_intrinsic_temp_table() const - { - /* DICT_TF2_INTRINSIC implies DICT_TF2_TEMPORARY */ - ut_ad(!(m_flags2 & DICT_TF2_INTRINSIC) - || (m_flags2 & DICT_TF2_TEMPORARY)); - return((m_flags2 & DICT_TF2_INTRINSIC) != 0); - } - /** Normalizes a table name string. A normalized name consists of the database name catenated to '/' and table name. An example: test/mytable. On Windows normalization puts diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h index f582f04733c..e445331b60c 100644 --- a/storage/innobase/include/btr0cur.h +++ b/storage/innobase/include/btr0cur.h @@ -192,37 +192,6 @@ btr_cur_search_to_nth_level( ulint line, /*!< in: line where called */ mtr_t* mtr); /*!< in: mtr */ -/** Searches an index tree and positions a tree cursor on a given level. -This function will avoid placing latches the travesal path and so -should be used only for cases where-in latching is not needed. - -@param[in] index index -@param[in] level the tree level of search -@param[in] tuple data tuple; Note: n_fields_cmp in compared - to the node ptr page node field -@param[in] mode PAGE_CUR_L, .... - Insert should always be made using PAGE_CUR_LE - to search the position. -@param[in,out] cursor tree cursor; points to record of interest. -@param[in] file file name -@param[in[ line line where called from -@param[in,out] mtr mtr -@param[in] mark_dirty - if true then mark the block as dirty -@return DB_SUCCESS or error code */ -dberr_t -btr_cur_search_to_nth_level_with_no_latch( - dict_index_t* index, - ulint level, - const dtuple_t* tuple, - page_cur_mode_t mode, - btr_cur_t* cursor, - const char* file, - ulint line, - mtr_t* mtr, - bool mark_dirty = true) - __attribute__((warn_unused_result)); - /*****************************************************************//** Opens a cursor at either end of an index. @return DB_SUCCESS or error code */ @@ -244,35 +213,6 @@ btr_cur_open_at_index_side_func( #define btr_cur_open_at_index_side(f,i,l,c,lv,m) \ btr_cur_open_at_index_side_func(f,i,l,c,lv,__FILE__,__LINE__,m) -/** Opens a cursor at either end of an index. -Avoid taking latches on buffer, just pin (by incrementing fix_count) -to keep them in buffer pool. This mode is used by intrinsic table -as they are not shared and so there is no need of latching. -@param[in] from_left true if open to low end, false if open - to high end. -@param[in] index index -@param[in] latch_mode latch mode -@param[in,out] cursor cursor -@param[in] file file name -@param[in] line line where called -@param[in,out] mtr mini transaction -@return DB_SUCCESS or error code -*/ -dberr_t -btr_cur_open_at_index_side_with_no_latch_func( - bool from_left, - dict_index_t* index, - btr_cur_t* cursor, - ulint level, - const char* file, - ulint line, - mtr_t* mtr) - __attribute__((warn_unused_result)); - -#define btr_cur_open_at_index_side_with_no_latch(f,i,c,lv,m) \ - btr_cur_open_at_index_side_with_no_latch_func( \ - f,i,c,lv,__FILE__,__LINE__,m) - /**********************************************************************//** Positions a cursor at a randomly chosen position within a B-tree. @return true if the index is available and we have put the cursor, false diff --git a/storage/innobase/include/btr0pcur.ic b/storage/innobase/include/btr0pcur.ic index 6cd968b4682..e7ae85dd730 100644 --- a/storage/innobase/include/btr0pcur.ic +++ b/storage/innobase/include/btr0pcur.ic @@ -452,20 +452,9 @@ btr_pcur_open_low( ut_ad(!dict_index_is_spatial(index)); - if (dict_table_is_intrinsic(index->table)) { - ut_ad((latch_mode & BTR_MODIFY_LEAF) - || (latch_mode & BTR_SEARCH_LEAF) - || (latch_mode & BTR_MODIFY_TREE)); - err = btr_cur_search_to_nth_level_with_no_latch( - index, level, tuple, mode, btr_cursor, - file, line, mtr, - (((latch_mode & BTR_MODIFY_LEAF) - || (latch_mode & BTR_MODIFY_TREE)) ? true : false)); - } else { - err = btr_cur_search_to_nth_level( - index, level, tuple, mode, latch_mode, - btr_cursor, 0, file, line, mtr); - } + err = btr_cur_search_to_nth_level( + index, level, tuple, mode, latch_mode, + btr_cursor, 0, file, line, mtr); if (err != DB_SUCCESS) { ib::warn() << " Error code: " << err @@ -521,18 +510,9 @@ btr_pcur_open_with_no_init_func( btr_cursor = btr_pcur_get_btr_cur(cursor); - if (dict_table_is_intrinsic(index->table)) { - ut_ad((latch_mode & BTR_MODIFY_LEAF) - || (latch_mode & BTR_SEARCH_LEAF)); - err = btr_cur_search_to_nth_level_with_no_latch( - index, 0, tuple, mode, btr_cursor, - file, line, mtr, - ((latch_mode & BTR_MODIFY_LEAF) ? true : false)); - } else { - err = btr_cur_search_to_nth_level( - index, 0, tuple, mode, latch_mode, btr_cursor, - has_search_latch, file, line, mtr); - } + err = btr_cur_search_to_nth_level( + index, 0, tuple, mode, latch_mode, btr_cursor, + has_search_latch, file, line, mtr); cursor->pos_state = BTR_PCUR_IS_POSITIONED; @@ -568,15 +548,9 @@ btr_pcur_open_at_index_side( btr_pcur_init(pcur); } - if (dict_table_is_intrinsic(index->table)) { - err = btr_cur_open_at_index_side_with_no_latch( - from_left, index, - btr_pcur_get_btr_cur(pcur), level, mtr); - } else { - err = btr_cur_open_at_index_side( - from_left, index, latch_mode, - btr_pcur_get_btr_cur(pcur), level, mtr); - } + err = btr_cur_open_at_index_side( + from_left, index, latch_mode, + btr_pcur_get_btr_cur(pcur), level, mtr); pcur->pos_state = BTR_PCUR_IS_POSITIONED; pcur->old_stored = false; diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index c4bc107044d..617bb2b9b5d 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -570,9 +570,6 @@ BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH, or BUF_GET_IF_IN_POOL_OR_WATCH @param[in] line line where called @param[in] mtr mini-transaction @param[out] err DB_SUCCESS or error code -@param[in] dirty_with_no_latch - mark page as dirty even if page - is being pinned without any latch @return pointer to the block or NULL */ buf_block_t* buf_page_get_gen( @@ -584,8 +581,7 @@ buf_page_get_gen( const char* file, ulint line, mtr_t* mtr, - dberr_t* err, - bool dirty_with_no_latch = false); + dberr_t* err); /** Initializes a page to the buffer buf_pool. The page is usually not read from a file even if it cannot be found in the buffer buf_pool. This is one @@ -1901,12 +1897,6 @@ struct buf_block_t{ complete, though: there may have been hash collisions, record deletions, etc. */ - bool made_dirty_with_no_latch; - /*!< true if block has been made dirty - without acquiring X/SX latch as the - block belongs to temporary tablespace - and block is always accessed by a - single thread. */ bool skip_flush_check; /*!< Skip check in buf_dblwr_check_block during bulk load, protected by lock.*/ diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index a912f3eb127..9c28432d551 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -926,7 +926,7 @@ buf_block_modify_clock_inc( #ifdef UNIV_DEBUG buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*) block); - /* No latch is acquired if block belongs to intrinsic table. */ + /* No latch is acquired for the shared temporary tablespace. */ if (!fsp_is_system_temporary(block->page.id.space())) { ut_ad((buf_pool_mutex_own(buf_pool) && (block->page.buf_fix_count == 0)) @@ -949,7 +949,7 @@ buf_block_get_modify_clock( buf_block_t* block) /*!< in: block */ { #ifdef UNIV_DEBUG - /* No latch is acquired if block belongs to intrinsic table. */ + /* No latch is acquired for the shared temporary tablespace. */ if (!fsp_is_system_temporary(block->page.id.space())) { ut_ad(rw_lock_own(&(block->lock), RW_LOCK_S) || rw_lock_own(&(block->lock), RW_LOCK_X) diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h index 00073dfca2c..27310963ec5 100644 --- a/storage/innobase/include/data0type.h +++ b/storage/innobase/include/data0type.h @@ -166,10 +166,6 @@ be less than 256 */ #define DATA_N_SYS_COLS 3 /* number of system columns defined above */ -#define DATA_ITT_N_SYS_COLS 2 - /* number of system columns for intrinsic - temporary table */ - #define DATA_FTS_DOC_ID 3 /* Used as FTS DOC ID column */ #define DATA_SYS_PRTYPE_MASK 0xF /* mask to extract the above from prtype */ @@ -196,6 +192,11 @@ be less than 256 */ for shorter VARCHARs MySQL uses only 1 byte */ #define DATA_VIRTUAL 8192 /* Virtual column */ +/** Get the number of system columns in a table. */ +#define dict_table_get_n_sys_cols(table) DATA_N_SYS_COLS +/** Check whether locking is disabled (never). */ +#define dict_table_is_locking_disabled(table) false + /*-------------------------------------------*/ /* This many bytes we need to store the type information affecting the diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index ccef08ff73f..e7eb558d6fd 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -843,17 +843,6 @@ ulint dict_table_get_n_tot_u_cols( const dict_table_t* table); /********************************************************************//** -Gets the number of system columns in a table. -For intrinsic table on ROW_ID column is added for all other -tables TRX_ID and ROLL_PTR are all also appeneded. -@return number of system (e.g., ROW_ID) columns of a table */ -UNIV_INLINE -ulint -dict_table_get_n_sys_cols( -/*======================*/ - const dict_table_t* table) /*!< in: table */ - MY_ATTRIBUTE((warn_unused_result)); -/********************************************************************//** Gets the number of all non-virtual columns (also system) in a table in the dictionary cache. @return number of columns of a table */ @@ -2016,24 +2005,6 @@ dict_table_is_encrypted( const dict_table_t* table) /*!< in: table to check */ MY_ATTRIBUTE((warn_unused_result)); -/** Check whether the table is intrinsic. -An intrinsic table is a special kind of temporary table that -is invisible to the end user. It is created internally by the MySQL server -layer or other module connected to InnoDB in order to gather and use data -as part of a larger task. Since access to it must be as fast as possible, -it does not need UNDO semantics, system fields DB_TRX_ID & DB_ROLL_PTR, -doublewrite, checksum, insert buffer, use of the shared data dictionary, -locking, or even a transaction. In short, these are not ACID tables at all, -just temporary - -@param[in] table table to check -@return true if intrinsic table flag is set. */ -UNIV_INLINE -bool -dict_table_is_intrinsic( - const dict_table_t* table) - MY_ATTRIBUTE((warn_unused_result)); - /** Check if the table is in a shared tablespace (System or General). @param[in] id Space ID to check @return true if id is a shared tablespace, false if not. */ @@ -2043,18 +2014,6 @@ dict_table_in_shared_tablespace( const dict_table_t* table) MY_ATTRIBUTE((warn_unused_result)); -/** Check whether locking is disabled for this table. -Currently this is done for intrinsic table as their visibility is limited -to the connection only. - -@param[in] table table to check -@return true if locking is disabled. */ -UNIV_INLINE -bool -dict_table_is_locking_disabled( - const dict_table_t* table) - MY_ATTRIBUTE((warn_unused_result)); - /********************************************************************//** Turn-off redo-logging if temporary table. */ UNIV_INLINE @@ -2064,30 +2023,6 @@ dict_disable_redo_if_temporary( const dict_table_t* table, /*!< in: table to check */ mtr_t* mtr); /*!< out: mini-transaction */ -/** Get table session row-id and increment the row-id counter for next use. -@param[in,out] table table handler -@return next table local row-id. */ -UNIV_INLINE -row_id_t -dict_table_get_next_table_sess_row_id( - dict_table_t* table); - -/** Get table session trx-id and increment the trx-id counter for next use. -@param[in,out] table table handler -@return next table local trx-id. */ -UNIV_INLINE -trx_id_t -dict_table_get_next_table_sess_trx_id( - dict_table_t* table); - -/** Get current session trx-id. -@param[in] table table handler -@return table local trx-id. */ -UNIV_INLINE -trx_id_t -dict_table_get_curr_table_sess_trx_id( - const dict_table_t* table); - #ifndef UNIV_HOTBACKUP /*********************************************************************//** This function should be called whenever a page is successfully diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 8165263c95c..5e5fbae9081 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -447,23 +447,6 @@ dict_table_get_n_tot_u_cols( return(dict_table_get_n_user_cols(table) + dict_table_get_n_v_cols(table)); } -/********************************************************************//** -Gets the number of system columns in a table. -For intrinsic table on ROW_ID column is added for all other -tables TRX_ID and ROLL_PTR are all also appeneded. -@return number of system (e.g., ROW_ID) columns of a table */ -UNIV_INLINE -ulint -dict_table_get_n_sys_cols( -/*======================*/ - const dict_table_t* table MY_ATTRIBUTE((unused))) /*!< in: table */ -{ - ut_ad(table); - ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - - return(dict_table_is_intrinsic(table) - ? DATA_ITT_N_SYS_COLS : DATA_N_SYS_COLS); -} /********************************************************************//** Gets the number of all non-virtual columns (also system) in a table @@ -1816,26 +1799,6 @@ dict_table_is_encrypted( return(DICT_TF2_FLAG_IS_SET(table, DICT_TF2_ENCRYPTION)); } -/** Check whether the table is intrinsic. -An intrinsic table is a special kind of temporary table that -is invisible to the end user. It can be created internally by InnoDB, the MySQL -server layer or other modules connected to InnoDB in order to gather and use -data as part of a larger task. Since access to it must be as fast as possible, -it does not need UNDO semantics, system fields DB_TRX_ID & DB_ROLL_PTR, -doublewrite, checksum, insert buffer, use of the shared data dictionary, -locking, or even a transaction. In short, these are not ACID tables at all, -just temporary data stored and manipulated during a larger process. - -@param[in] table table to check -@return true if intrinsic table flag is set. */ -UNIV_INLINE -bool -dict_table_is_intrinsic( - const dict_table_t* table) -{ - return(DICT_TF2_FLAG_IS_SET(table, DICT_TF2_INTRINSIC)); -} - /** Check if the table is in a shared tablespace (System or General). @param[in] id Space ID to check @return true if id is a shared tablespace, false if not. */ @@ -1848,20 +1811,6 @@ dict_table_in_shared_tablespace( || DICT_TF_HAS_SHARED_SPACE(table->flags)); } -/** Check whether locking is disabled for this table. -Currently this is done for intrinsic table as their visibility is limited -to the connection only. - -@param[in] table table to check -@return true if locking is disabled. */ -UNIV_INLINE -bool -dict_table_is_locking_disabled( - const dict_table_t* table) -{ - return(dict_table_is_intrinsic(table)); -} - /********************************************************************//** Turn-off redo-logging if temporary table. */ UNIV_INLINE @@ -1946,46 +1895,13 @@ dict_table_get_index_on_first_col( return(0); } -/** Get table session row-id and increment the row-id counter for next use. -@param[in,out] table table handler -@return next table session row-id. */ -UNIV_INLINE -row_id_t -dict_table_get_next_table_sess_row_id( - dict_table_t* table) -{ - return(++table->sess_row_id); -} - -/** Get table session trx-id and increment the trx-id counter for next use. -@param[in,out] table table handler -@return next table session trx-id. */ -UNIV_INLINE -trx_id_t -dict_table_get_next_table_sess_trx_id( - dict_table_t* table) -{ - return(++table->sess_trx_id); -} - -/** Get current session trx-id. -@param[in] table table handler -@return table session trx-id. */ -UNIV_INLINE -trx_id_t -dict_table_get_curr_table_sess_trx_id( - const dict_table_t* table) -{ - return(table->sess_trx_id); -} - /** Get reference count. @return current value of n_ref_count */ inline ulint dict_table_t::get_ref_count() const { - ut_ad(mutex_own(&dict_sys->mutex) || dict_table_is_intrinsic(this)); + ut_ad(mutex_own(&dict_sys->mutex)); return(n_ref_count); } @@ -1994,7 +1910,7 @@ inline void dict_table_t::acquire() { - ut_ad(mutex_own(&dict_sys->mutex) || dict_table_is_intrinsic(this)); + ut_ad(mutex_own(&dict_sys->mutex)); ++n_ref_count; } @@ -2003,7 +1919,7 @@ inline void dict_table_t::release() { - ut_ad(mutex_own(&dict_sys->mutex) || dict_table_is_intrinsic(this)); + ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(n_ref_count > 0); --n_ref_count; } diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 4ee19f96008..019e20680e5 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -337,12 +337,6 @@ use its own tablespace instead of the system tablespace. */ index tables) of a FTS table are in HEX format. */ #define DICT_TF2_FTS_AUX_HEX_NAME 64 -/** Intrinsic table bit -Intrinsic table is table created internally by MySQL modules viz. Optimizer, -FTS, etc.... Intrinsic table has all the properties of the normal table except -it is not created by user and so not visible to end-user. */ -#define DICT_TF2_INTRINSIC 128 - /** Encryption table bit. */ #define DICT_TF2_ENCRYPTION 256 @@ -859,95 +853,6 @@ struct zip_pad_info_t { a certain index.*/ #define STAT_DEFRAG_DATA_SIZE_N_SAMPLE 10 -/** If key is fixed length key then cache the record offsets on first -computation. This will help save computation cycle that generate same -redundant data. */ -class rec_cache_t -{ -public: - /** Constructor */ - rec_cache_t() - : - rec_size(), - offsets(), - sz_of_offsets(), - fixed_len_key(), - offsets_cached(), - key_has_null_cols() - { - /* Do Nothing. */ - } - -public: - /** Record size. (for fixed length key record size is constant) */ - ulint rec_size; - - /** Holds reference to cached offsets for record. */ - ulint* offsets; - - /** Size of offset array */ - uint32_t sz_of_offsets; - - /** If true, then key is fixed length key. */ - bool fixed_len_key; - - /** If true, then offset has been cached for re-use. */ - bool offsets_cached; - - /** If true, then key part can have columns that can take - NULL values. */ - bool key_has_null_cols; -}; - -/** Cache position of last inserted or selected record by caching record -and holding reference to the block where record resides. -Note: We don't commit mtr and hold it beyond a transaction lifetime as this is -a special case (intrinsic table) that are not shared accross connection. */ -class last_ops_cur_t -{ -public: - /** Constructor */ - last_ops_cur_t() - : - rec(), - block(), - mtr(), - disable_caching(), - invalid() - { - /* Do Nothing. */ - } - - /* Commit mtr and re-initialize cache record and block to NULL. */ - void release() - { - if (mtr.is_active()) { - mtr_commit(&mtr); - } - rec = NULL; - block = NULL; - invalid = false; - } - -public: - /** last inserted/selected record. */ - rec_t* rec; - - /** block where record reside. */ - buf_block_t* block; - - /** active mtr that will be re-used for next insert/select. */ - mtr_t mtr; - - /** disable caching. (disabled when table involves blob/text.) */ - bool disable_caching; - - /** If index structure is undergoing structural change viz. - split then invalidate the cached position as it would be no more - remain valid. Will be re-cached on post-split insert. */ - bool invalid; -}; - /** "GEN_CLUST_INDEX" is the name reserved for InnoDB default system clustered index when there is no primary key. */ const char innobase_index_reserve_name[] = "GEN_CLUST_INDEX"; @@ -990,18 +895,15 @@ struct dict_index_t{ /*!< number of columns the user defined to be in the index: in the internal representation we add more columns */ - unsigned allow_duplicates:1; - /*!< if true, allow duplicate values - even if index is created with unique - constraint */ unsigned nulls_equal:1; /*!< if true, SQL NULL == SQL NULL */ - unsigned disable_ahi:1; - /*!< in true, then disable AHI. - Currently limited to intrinsic - temporary table as index id is not - unqiue for such table which is one of the - validation criterion for ahi. */ +#ifdef MYSQL_INDEX_DISABLE_AHI + unsigned disable_ahi:1; + /*!< whether to disable the + adaptive hash index. + Maybe this could be disabled for + temporary tables? */ +#endif unsigned n_uniq:10;/*!< number of fields from the beginning which are enough to determine an index entry uniquely */ @@ -1098,19 +1000,6 @@ struct dict_index_t{ /* in which slot the next sample should be saved. */ /* @} */ - last_ops_cur_t* last_ins_cur; - /*!< cache the last insert position. - Currently limited to auto-generated - clustered index on intrinsic table only. */ - last_ops_cur_t* last_sel_cur; - /*!< cache the last selected position - Currently limited to intrinsic table only. */ - rec_cache_t rec_cache; - /*!< cache the field that needs to be - re-computed on each insert. - Limited to intrinsic table as this is common - share and can't be used without protection - if table is accessible to multiple-threads. */ rtr_ssn_t rtr_ssn;/*!< Node sequence number for RTree */ rtr_info_track_t* rtr_track;/*!< tracking all R-Tree search cursors */ @@ -1874,18 +1763,6 @@ public: /** Timestamp of the last modification of this table. */ time_t update_time; - /** row-id counter for use by intrinsic table for getting row-id. - Given intrinsic table semantics, row-id can be locally maintained - instead of getting it from central generator which involves mutex - locking. */ - ib_uint64_t sess_row_id; - - /** trx_id counter for use by intrinsic table for getting trx-id. - Intrinsic table are not shared so don't need a central trx-id - but just need a increased counter to track consistent view while - proceeding SELECT as part of UPDATE. */ - ib_uint64_t sess_trx_id; - #endif /* !UNIV_HOTBACKUP */ bool is_encrypted; diff --git a/storage/innobase/include/dict0mem.ic b/storage/innobase/include/dict0mem.ic index 3269596feb7..a50fb615a09 100644 --- a/storage/innobase/include/dict0mem.ic +++ b/storage/innobase/include/dict0mem.ic @@ -69,35 +69,10 @@ dict_mem_fill_index_struct( index->n_fields = (unsigned int) n_fields; /* The '1 +' above prevents allocation of an empty mem block */ - index->allow_duplicates = false; index->nulls_equal = false; +#ifdef MYSQL_INDEX_DISABLE_AHI index->disable_ahi = false; - - new (&index->rec_cache) rec_cache_t(); - - if (heap != NULL) { - index->last_ins_cur = - static_cast<last_ops_cur_t*>(mem_heap_alloc( - heap, sizeof(last_ops_cur_t))); - - new (index->last_ins_cur) last_ops_cur_t(); - - index->last_sel_cur = - static_cast<last_ops_cur_t*>(mem_heap_alloc( - heap, sizeof(last_ops_cur_t))); - - new (index->last_sel_cur) last_ops_cur_t(); - - index->rec_cache.offsets = - static_cast<ulint*>(mem_heap_alloc( - heap, sizeof(ulint) * OFFS_IN_REC_NORMAL_SIZE)); - - index->rec_cache.sz_of_offsets = OFFS_IN_REC_NORMAL_SIZE; - } else { - index->last_ins_cur = NULL; - index->last_sel_cur = NULL; - index->rec_cache.offsets = NULL; - } +#endif #ifdef UNIV_DEBUG index->magic_n = DICT_INDEX_MAGIC_N; diff --git a/storage/innobase/include/dict0stats.ic b/storage/innobase/include/dict0stats.ic index 80709091734..61c88773912 100644 --- a/storage/innobase/include/dict0stats.ic +++ b/storage/innobase/include/dict0stats.ic @@ -182,7 +182,7 @@ dict_stats_deinit( /*==============*/ dict_table_t* table) /*!< in/out: table */ { - ut_ad(mutex_own(&dict_sys->mutex) || dict_table_is_intrinsic(table)); + ut_ad(mutex_own(&dict_sys->mutex)); ut_a(table->get_ref_count() == 0); diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index 4a1d867015d..3526436f042 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -84,17 +84,11 @@ savepoint. */ #ifdef UNIV_DEBUG -/** Check if memo contains the given item ignore if table is intrinsic -@return TRUE if contains or table is intrinsic. */ -#define mtr_is_block_fix(m, o, t, table) \ - (mtr_memo_contains(m, o, t) \ - || dict_table_is_intrinsic(table)) - -/** Check if memo contains the given page ignore if table is intrinsic -@return TRUE if contains or table is intrinsic. */ -#define mtr_is_page_fix(m, p, t, table) \ - (mtr_memo_contains_page(m, p, t) \ - || dict_table_is_intrinsic(table)) +/** Check if memo contains the given item. */ +#define mtr_is_block_fix(m, o, t, table) mtr_memo_contains(m, o, t) + +/** Check if memo contains the given page. */ +#define mtr_is_page_fix(m, p, t, table) mtr_memo_contains_page(m, p, t) /** Check if memo contains the given item. @return TRUE if contains */ diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic index b3d9b052d52..f0354756b23 100644 --- a/storage/innobase/include/mtr0mtr.ic +++ b/storage/innobase/include/mtr0mtr.ic @@ -47,13 +47,6 @@ mtr_t::memo_push(void* object, mtr_memo_type_t type) m_impl.m_made_dirty = is_block_dirtied( reinterpret_cast<const buf_block_t*>(object)); - } else if (type == MTR_MEMO_BUF_FIX && !m_impl.m_made_dirty) { - - if (reinterpret_cast<const buf_block_t*>( - object)->made_dirty_with_no_latch) { - - m_impl.m_made_dirty = true; - } } mtr_memo_slot_t* slot; diff --git a/storage/innobase/include/page0cur.h b/storage/innobase/include/page0cur.h index c111717d868..94b5896d3ad 100644 --- a/storage/innobase/include/page0cur.h +++ b/storage/innobase/include/page0cur.h @@ -201,23 +201,6 @@ page_cur_insert_rec_low( mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */ MY_ATTRIBUTE((nonnull(1,2,3,4), warn_unused_result)); -/** Inserts a record next to page cursor on an uncompressed page. -@param[in] current_rec pointer to current record after which - the new record is inserted. -@param[in] index record descriptor -@param[in] tuple pointer to a data tuple -@param[in] n_ext number of externally stored columns -@param[in] mtr mini-transaction handle, or NULL - -@return pointer to record if succeed, NULL otherwise */ -rec_t* -page_cur_direct_insert_rec_low( - rec_t* current_rec, - dict_index_t* index, - const dtuple_t* tuple, - ulint n_ext, - mtr_t* mtr); - /***********************************************************//** Inserts a record next to page cursor on a compressed and uncompressed page. Returns pointer to inserted record if succeed, i.e., diff --git a/storage/innobase/include/page0cur.ic b/storage/innobase/include/page0cur.ic index 8f580ef2d43..bfd9da47803 100644 --- a/storage/innobase/include/page0cur.ic +++ b/storage/innobase/include/page0cur.ic @@ -294,35 +294,6 @@ page_cur_tuple_insert( ut_ad(!rec || !cmp_dtuple_rec(tuple, rec, *offsets)); return(rec); } - -/** Insert a record next to page cursor. Record is directly copied to -the page from tuple without creating intermediate copy of the record. - -@param[in,out] cursor a page cursor -@param[in] tuple pointer to a data tuple -@param[in] index record descriptor -@param[in] n_ext number of externally stored columns -@param[in] mtr mini-transaction handle, or NULL - -@return pointer to record if succeed, NULL otherwise */ -UNIV_INLINE -rec_t* -page_cur_tuple_direct_insert( - page_cur_t* cursor, - const dtuple_t* tuple, - dict_index_t* index, - ulint n_ext, - mtr_t* mtr) -{ - rec_t* rec; - - ut_ad(dict_table_is_intrinsic(index->table)); - - rec = page_cur_direct_insert_rec_low( - cursor->rec, index, tuple, n_ext, mtr); - - return(rec); -} #endif /* !UNIV_HOTBACKUP */ /***********************************************************//** diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 2d508c1a7df..f010e717103 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -37,7 +37,6 @@ Created 9/17/2000 Heikki Tuuri #include "btr0pcur.h" #include "trx0types.h" #include "fil0crypt.h" -#include "sess0sess.h" // Forward declaration struct SysIndexCallback; @@ -292,14 +291,6 @@ row_update_for_mysql( row_prebuilt_t* prebuilt) MY_ATTRIBUTE((warn_unused_result)); -/** Delete all rows for the given table by freeing/truncating indexes. -@param[in,out] table table handler -@return error code or DB_SUCCESS */ -dberr_t -row_delete_all_rows( - dict_table_t* table) - MY_ATTRIBUTE((warn_unused_result)); - /** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this session is using a READ COMMITTED or READ UNCOMMITTED isolation level. Before calling this function row_search_for_mysql() must have @@ -402,13 +393,12 @@ row_create_index_for_mysql( dict_index_t* index, /*!< in, own: index definition (will be freed) */ trx_t* trx, /*!< in: transaction handle */ - const ulint* field_lengths, /*!< in: if not NULL, must contain + const ulint* field_lengths) /*!< in: if not NULL, must contain dict_index_get_n_fields(index) actual field lengths for the index columns, which are then checked for not being too large. */ - dict_table_t* handler) /* ! in/out: table handler. */ MY_ATTRIBUTE((warn_unused_result)); /*********************************************************************//** Scans a table create SQL string and adds to the data dictionary @@ -427,8 +417,6 @@ fields than mentioned in the constraint. database id the database of parameter name @param[in] sql_length length of sql_string @param[in] name table full name in normalized form -@param[in] is_temp_table true if table is temporary -@param[in,out] handler table handler if table is intrinsic @param[in] reject_fks if TRUE, fail with error code DB_CANNOT_ADD_CONSTRAINT if any foreign keys are found. @@ -493,11 +481,9 @@ row_drop_table_for_mysql( ibool create_failed,/*!<in: TRUE=create table failed because e.g. foreign key column type mismatch. */ - bool nonatomic = true, + bool nonatomic = true); /*!< in: whether it is permitted to release and reacquire dict_operation_lock */ - dict_table_t* handler = NULL); - /*!< in/out: table handler. */ /*********************************************************************//** Drop all temporary tables during crash recovery. */ void @@ -898,10 +884,6 @@ struct row_prebuilt_t { ulint magic_n2; /*!< this should be the same as magic_n */ - bool ins_sel_stmt; /*!< if true then ins_sel_statement. */ - - innodb_session_t* - session; /*!< InnoDB session handler. */ byte* srch_key_val1; /*!< buffer used in converting search key values from MySQL format to InnoDB format.*/ diff --git a/storage/innobase/include/row0sel.h b/storage/innobase/include/row0sel.h index 3e6863208af..1186aa6f26e 100644 --- a/storage/innobase/include/row0sel.h +++ b/storage/innobase/include/row0sel.h @@ -177,34 +177,7 @@ row_search_for_mysql( MY_ATTRIBUTE((warn_unused_result)); /** Searches for rows in the database using cursor. -function is meant for temporary table that are not shared accross connection -and so lot of complexity is reduced especially locking and transaction related. -The cursor is an iterator over the table/index. - -@param[out] buf buffer for the fetched row in MySQL format -@param[in] mode search mode PAGE_CUR_L -@param[in,out] prebuilt prebuilt struct for the table handler; - this contains the info to search_tuple, - index; if search tuple contains 0 field then - we position the cursor at start or the end of - index, depending on 'mode' -@param[in] match_mode 0 or ROW_SEL_EXACT or ROW_SEL_EXACT_PREFIX -@param[in] direction 0 or ROW_SEL_NEXT or ROW_SEL_PREV; - Note: if this is != 0, then prebuilt must has a - pcur with stored position! In opening of a - cursor 'direction' should be 0. -@return DB_SUCCESS or error code */ -dberr_t -row_search_no_mvcc( - byte* buf, - page_cur_mode_t mode, - row_prebuilt_t* prebuilt, - ulint match_mode, - ulint direction) - MY_ATTRIBUTE((warn_unused_result)); - -/** Searches for rows in the database using cursor. -Function is mainly used for tables that are shared accorss connection and +Function is mainly used for tables that are shared across connections and so it employs technique that can help re-construct the rows that transaction is suppose to see. It also has optimization such as pre-caching the rows, using AHI, etc. @@ -221,15 +194,6 @@ It also has optimization such as pre-caching the rows, using AHI, etc. Note: if this is != 0, then prebuilt must has a pcur with stored position! In opening of a cursor 'direction' should be 0. -@param[in] ins_sel_stmt if true, then this statement is - insert .... select statement. For normal table - this can be detected by checking out locked - tables using trx->mysql_n_tables_locked > 0 - condition. For intrinsic table - external_lock is not invoked and so condition - above will not stand valid instead this is - traced using alternative condition - at caller level. @return DB_SUCCESS or error code */ dberr_t row_search_mvcc( diff --git a/storage/innobase/include/row0sel.ic b/storage/innobase/include/row0sel.ic index a816e4440e2..d14b41e3f5f 100644 --- a/storage/innobase/include/row0sel.ic +++ b/storage/innobase/include/row0sel.ic @@ -134,12 +134,5 @@ row_search_for_mysql( ulint match_mode, ulint direction) { - if (!dict_table_is_intrinsic(prebuilt->table)) { - return(row_search_mvcc( - buf, mode, prebuilt, match_mode, direction)); - } else { - return(row_search_no_mvcc( - buf, mode, prebuilt, match_mode, direction)); - } + return(row_search_mvcc(buf, mode, prebuilt, match_mode, direction)); } - diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h index 5fdb916c54c..bd49e034384 100644 --- a/storage/innobase/include/sync0types.h +++ b/storage/innobase/include/sync0types.h @@ -1033,10 +1033,10 @@ struct latch_t { return(m_temp_fsp); } - /** Set the temporary tablespace flag. The latch order constraints - are different for intrinsic tables. We don't always acquire the - index->lock. We need to figure out the context and add some special - rules during the checks. */ + /** Set the temporary tablespace flag. (For internal temporary + tables, MySQL 5.7 does not always acquire the index->lock. We + need to figure out the context and add some special rules + during the checks.) */ void set_temp_fsp() UNIV_NOTHROW { @@ -1090,26 +1090,11 @@ struct btrsea_sync_check : public sync_check_functor_t { virtual bool operator()(const latch_level_t level) { /* If calling thread doesn't hold search latch then - check if there are latch level exception provided. - - Note: Optimizer has added InnoDB intrinsic table as an - alternative to MyISAM intrinsic table. With this a new - control flow comes into existence, it is: - - Server -> Plugin -> SE - - Plugin in this case is I_S which is sharing the latch vector - of InnoDB and so there could be lock conflicts. Ideally - the Plugin should use a difference namespace latch vector - as it doesn't have any depedency with SE latching protocol. - - Added check that will allow thread to hold I_S latches */ + check if there are latch level exception provided. */ if (!m_has_search_latch && (level != SYNC_SEARCH_SYS - && level != SYNC_FTS_CACHE - && level != SYNC_TRX_I_S_RWLOCK - && level != SYNC_TRX_I_S_LAST_READ)) { + && level != SYNC_FTS_CACHE)) { m_result = true; diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index e8ed8adb483..736933bdaed 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -358,16 +358,6 @@ struct ReleaseBlocks { || slot->type == MTR_MEMO_PAGE_SX_FIX) { add_dirty_page_to_flush_list(slot); - - } else if (slot->type == MTR_MEMO_BUF_FIX) { - - buf_block_t* block; - block = reinterpret_cast<buf_block_t*>( - slot->object); - if (block->made_dirty_with_no_latch) { - add_dirty_page_to_flush_list(slot); - block->made_dirty_with_no_latch = false; - } } } diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc index b0412009b80..87c28872462 100644 --- a/storage/innobase/page/page0cur.cc +++ b/storage/innobase/page/page0cur.cc @@ -301,96 +301,6 @@ page_cur_rec_field_extends( } #endif /* PAGE_CUR_LE_OR_EXTENDS */ -/** If key is fixed length then populate offset directly from -cached version. -@param[in] rec B-Tree record for which offset needs to be - populated. -@param[in,out] index index handler -@param[in] tuple data tuple -@param[in,out] offsets default offsets array -@param[in,out] heap heap -@return reference to populate offsets. */ -static -ulint* -populate_offsets( - const rec_t* rec, - const dtuple_t* tuple, - dict_index_t* index, - ulint* offsets, - mem_heap_t** heap) -{ - ut_ad(dict_table_is_intrinsic(index->table)); - - bool rec_has_null_values = false; - - if (index->rec_cache.key_has_null_cols) { - /* Check if record has null value. */ - const byte* nulls = rec - (1 + REC_N_NEW_EXTRA_BYTES); - ulint n_bytes_to_scan - = UT_BITS_IN_BYTES(index->n_nullable); - byte null_mask = 0xff; - ulint bits_examined = 0; - - for (ulint i = 0; i < n_bytes_to_scan - 1; i++) { - if (*nulls & null_mask) { - rec_has_null_values = true; - break; - } - --nulls; - bits_examined += 8; - } - - if (!rec_has_null_values) { - null_mask >>= (8 - (index->n_nullable - bits_examined)); - rec_has_null_values = *nulls & null_mask; - } - - if (rec_has_null_values) { - - offsets = rec_get_offsets( - rec, index, offsets, - dtuple_get_n_fields_cmp(tuple), heap); - - return(offsets); - } - } - - /* Check if offsets are cached else cache them first. - There are queries that will first verify if key is present using index - search and then initiate insert. If offsets are cached during index - search it would be based on key part only but during insert that looks - out for exact location to insert key + db_row_id both columns would - be used and so re-compute offsets in such case. */ - if (!index->rec_cache.offsets_cached - || (rec_offs_n_fields(index->rec_cache.offsets) - < dtuple_get_n_fields_cmp(tuple))) { - - offsets = rec_get_offsets( - rec, index, offsets, - dtuple_get_n_fields_cmp(tuple), heap); - - /* Reallocate if our offset array is not big - enough to hold the needed size. */ - ulint sz1 = index->rec_cache.sz_of_offsets; - ulint sz2 = offsets[0]; - if (sz1 < sz2) { - index->rec_cache.offsets = static_cast<ulint*>( - mem_heap_alloc( - index->heap, sizeof(ulint) * sz2)); - index->rec_cache.sz_of_offsets = - static_cast<uint32_t>(sz2); - } - - memcpy(index->rec_cache.offsets, - offsets, (sizeof(ulint) * sz2)); - index->rec_cache.offsets_cached = true; - } - - ut_ad(index->rec_cache.offsets[2] = (ulint) rec); - - return(index->rec_cache.offsets); -} - /****************************************************************//** Searches the right position for a page cursor. */ void @@ -522,17 +432,9 @@ page_cur_search_with_match( up_matched_fields); offsets = offsets_; - if (index->rec_cache.fixed_len_key) { - offsets = populate_offsets( - mid_rec, tuple, - const_cast<dict_index_t*>(index), - offsets, &heap); - } else { - offsets = rec_get_offsets( - mid_rec, index, offsets, - dtuple_get_n_fields_cmp(tuple), &heap); - - } + offsets = rec_get_offsets( + mid_rec, index, offsets, + dtuple_get_n_fields_cmp(tuple), &heap); cmp = cmp_dtuple_rec_with_match( tuple, mid_rec, offsets, &cur_matched_fields); @@ -584,17 +486,9 @@ up_slot_match: up_matched_fields); offsets = offsets_; - if (index->rec_cache.fixed_len_key) { - offsets = populate_offsets( - mid_rec, tuple, - const_cast<dict_index_t*>(index), - offsets, &heap); - } else { - offsets = rec_get_offsets( - mid_rec, index, offsets, - dtuple_get_n_fields_cmp(tuple), &heap); - - } + offsets = rec_get_offsets( + mid_rec, index, offsets, + dtuple_get_n_fields_cmp(tuple), &heap); cmp = cmp_dtuple_rec_with_match( tuple, mid_rec, offsets, &cur_matched_fields); @@ -1554,214 +1448,6 @@ use_heap: return(insert_rec); } -/** Inserts a record next to page cursor on an uncompressed page. -@param[in] current_rec pointer to current record after which - the new record is inserted. -@param[in] index record descriptor -@param[in] tuple pointer to a data tuple -@param[in] n_ext number of externally stored columns -@param[in] mtr mini-transaction handle, or NULL - -@return pointer to record if succeed, NULL otherwise */ -rec_t* -page_cur_direct_insert_rec_low( - rec_t* current_rec, - dict_index_t* index, - const dtuple_t* tuple, - ulint n_ext, - mtr_t* mtr) -{ - byte* insert_buf; - ulint rec_size; - page_t* page; /*!< the relevant page */ - rec_t* last_insert; /*!< cursor position at previous - insert */ - rec_t* free_rec; /*!< a free record that was reused, - or NULL */ - rec_t* insert_rec; /*!< inserted record */ - ulint heap_no; /*!< heap number of the inserted - record */ - - page = page_align(current_rec); - - ut_ad(dict_table_is_comp(index->table) - == (ibool) !!page_is_comp(page)); - - ut_ad(fil_page_index_page_check(page)); - - ut_ad(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID) - == index->id); - - ut_ad(!page_rec_is_supremum(current_rec)); - - /* 1. Get the size of the physical record in the page */ - rec_size = index->rec_cache.rec_size; - - /* 2. Try to find suitable space from page memory management */ - free_rec = page_header_get_ptr(page, PAGE_FREE); - if (free_rec) { - /* Try to allocate from the head of the free list. */ - ulint foffsets_[REC_OFFS_NORMAL_SIZE]; - ulint* foffsets = foffsets_; - mem_heap_t* heap = NULL; - - rec_offs_init(foffsets_); - - foffsets = rec_get_offsets( - free_rec, index, foffsets, ULINT_UNDEFINED, &heap); - if (rec_offs_size(foffsets) < rec_size) { - if (heap != NULL) { - mem_heap_free(heap); - heap = NULL; - } - - free_rec = NULL; - insert_buf = page_mem_alloc_heap( - page, NULL, rec_size, &heap_no); - - if (insert_buf == NULL) { - return(NULL); - } - } else { - insert_buf = free_rec - rec_offs_extra_size(foffsets); - - if (page_is_comp(page)) { - heap_no = rec_get_heap_no_new(free_rec); - page_mem_alloc_free( - page, NULL, - rec_get_next_ptr(free_rec, TRUE), - rec_size); - } else { - heap_no = rec_get_heap_no_old(free_rec); - page_mem_alloc_free( - page, NULL, - rec_get_next_ptr(free_rec, FALSE), - rec_size); - } - - if (heap != NULL) { - mem_heap_free(heap); - heap = NULL; - } - } - } else { - free_rec = NULL; - insert_buf = page_mem_alloc_heap(page, NULL, - rec_size, &heap_no); - - if (insert_buf == NULL) { - return(NULL); - } - } - - /* 3. Create the record */ - insert_rec = rec_convert_dtuple_to_rec(insert_buf, index, tuple, n_ext); - - /* 4. Insert the record in the linked list of records */ - ut_ad(current_rec != insert_rec); - - { - /* next record after current before the insertion */ - rec_t* next_rec = page_rec_get_next(current_rec); -#ifdef UNIV_DEBUG - if (page_is_comp(page)) { - ut_ad(rec_get_status(current_rec) - <= REC_STATUS_INFIMUM); - ut_ad(rec_get_status(insert_rec) < REC_STATUS_INFIMUM); - ut_ad(rec_get_status(next_rec) != REC_STATUS_INFIMUM); - } -#endif - page_rec_set_next(insert_rec, next_rec); - page_rec_set_next(current_rec, insert_rec); - } - - page_header_set_field(page, NULL, PAGE_N_RECS, - 1 + page_get_n_recs(page)); - - /* 5. Set the n_owned field in the inserted record to zero, - and set the heap_no field */ - if (page_is_comp(page)) { - rec_set_n_owned_new(insert_rec, NULL, 0); - rec_set_heap_no_new(insert_rec, heap_no); - } else { - rec_set_n_owned_old(insert_rec, 0); - rec_set_heap_no_old(insert_rec, heap_no); - } - - /* 6. Update the last insertion info in page header */ - - last_insert = page_header_get_ptr(page, PAGE_LAST_INSERT); - ut_ad(!last_insert || !page_is_comp(page) - || rec_get_node_ptr_flag(last_insert) - == rec_get_node_ptr_flag(insert_rec)); - - if (last_insert == NULL) { - page_header_set_field(page, NULL, PAGE_DIRECTION, - PAGE_NO_DIRECTION); - page_header_set_field(page, NULL, PAGE_N_DIRECTION, 0); - - } else if ((last_insert == current_rec) - && (page_header_get_field(page, PAGE_DIRECTION) - != PAGE_LEFT)) { - - page_header_set_field(page, NULL, PAGE_DIRECTION, - PAGE_RIGHT); - page_header_set_field(page, NULL, PAGE_N_DIRECTION, - page_header_get_field( - page, PAGE_N_DIRECTION) + 1); - - } else if ((page_rec_get_next(insert_rec) == last_insert) - && (page_header_get_field(page, PAGE_DIRECTION) - != PAGE_RIGHT)) { - - page_header_set_field(page, NULL, PAGE_DIRECTION, - PAGE_LEFT); - page_header_set_field(page, NULL, PAGE_N_DIRECTION, - page_header_get_field( - page, PAGE_N_DIRECTION) + 1); - } else { - page_header_set_field(page, NULL, PAGE_DIRECTION, - PAGE_NO_DIRECTION); - page_header_set_field(page, NULL, PAGE_N_DIRECTION, 0); - } - - page_header_set_ptr(page, NULL, PAGE_LAST_INSERT, insert_rec); - - /* 7. It remains to update the owner record. */ - { - rec_t* owner_rec = page_rec_find_owner_rec(insert_rec); - ulint n_owned; - if (page_is_comp(page)) { - n_owned = rec_get_n_owned_new(owner_rec); - rec_set_n_owned_new(owner_rec, NULL, n_owned + 1); - } else { - n_owned = rec_get_n_owned_old(owner_rec); - rec_set_n_owned_old(owner_rec, n_owned + 1); - } - - /* 8. Now we have incremented the n_owned field of the owner - record. If the number exceeds PAGE_DIR_SLOT_MAX_N_OWNED, - we have to split the corresponding directory slot in two. */ - - if (n_owned == PAGE_DIR_SLOT_MAX_N_OWNED) { - page_dir_split_slot( - page, NULL, - page_dir_find_owner_slot(owner_rec)); - } - } - - /* 8. Open the mtr for name sake to set the modification flag - to true failing which no flush would be done. */ - byte* log_ptr = mlog_open(mtr, 0); - ut_ad(log_ptr == NULL); - if (log_ptr != NULL) { - /* To keep complier happy. */ - mlog_close(mtr, log_ptr); - } - - return(insert_rec); -} - /***********************************************************//** Inserts a record next to page cursor on a compressed and uncompressed page. Returns pointer to inserted record if succeed, i.e., diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index d93b80778b5..d71c6ffa9f3 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -4805,10 +4805,8 @@ page_zip_copy_recs( dict_index_t* index, /*!< in: index of the B-tree */ mtr_t* mtr) /*!< in: mini-transaction */ { - ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX) - || dict_table_is_intrinsic(index->table)); - ut_ad(mtr_memo_contains_page(mtr, src, MTR_MEMO_PAGE_X_FIX) - || dict_table_is_intrinsic(index->table)); + ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX)); + ut_ad(mtr_memo_contains_page(mtr, src, MTR_MEMO_PAGE_X_FIX)); ut_ad(!dict_index_is_ibuf(index)); #ifdef UNIV_ZIP_DEBUG /* The B-tree operations that call this function may set diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 720ad44b4b8..20c64a4288c 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -155,10 +155,7 @@ row_ins_alloc_sys_fields( ut_ad(dtuple_get_n_fields(row) == dict_table_get_n_cols(table)); /* allocate buffer to hold the needed system created hidden columns. */ - uint len = DATA_ROW_ID_LEN + DATA_TRX_ID_LEN; - if (!dict_table_is_intrinsic(table)) { - len += DATA_ROLL_PTR_LEN; - } + const uint len = DATA_ROW_ID_LEN + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN; ptr = static_cast<byte*>(mem_heap_zalloc(heap, len)); /* 1. Populate row-id */ @@ -183,13 +180,11 @@ row_ins_alloc_sys_fields( ptr += DATA_TRX_ID_LEN; - if (!dict_table_is_intrinsic(table)) { - col = dict_table_get_sys_col(table, DATA_ROLL_PTR); + col = dict_table_get_sys_col(table, DATA_ROLL_PTR); - dfield = dtuple_get_nth_field(row, dict_col_get_no(col)); + dfield = dtuple_get_nth_field(row, dict_col_get_no(col)); - dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN); - } + dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN); } /*********************************************************************//** @@ -2152,7 +2147,7 @@ row_ins_scan_sec_index_for_duplicate( cmp = cmp_dtuple_rec(entry, rec, offsets); - if (cmp == 0 && !index->allow_duplicates) { + if (cmp == 0) { if (row_ins_dupl_error_with_rec(rec, entry, index, offsets)) { err = DB_DUPLICATE_KEY; @@ -2174,7 +2169,7 @@ row_ins_scan_sec_index_for_duplicate( goto end_scan; } } else { - ut_a(cmp < 0 || index->allow_duplicates); + ut_a(cmp < 0); goto end_scan; } } while (btr_pcur_move_to_next(&pcur, mtr)); @@ -2507,9 +2502,6 @@ row_ins_clust_index_entry_low( Disable locking as temp-tables are local to a connection. */ ut_ad(flags & BTR_NO_LOCKING_FLAG); - ut_ad(!dict_table_is_intrinsic(index->table) - || (flags & BTR_NO_UNDO_LOG_FLAG)); - mtr.set_log_mode(MTR_LOG_NO_REDO); } @@ -2528,9 +2520,6 @@ row_ins_clust_index_entry_low( cursor->thr = thr; } - ut_ad(!dict_table_is_intrinsic(index->table) - || cursor->page_cur.block->made_dirty_with_no_latch); - #ifdef UNIV_DEBUG { page_t* page = btr_cur_get_page(cursor); @@ -2542,15 +2531,7 @@ row_ins_clust_index_entry_low( } #endif /* UNIV_DEBUG */ - /* Allowing duplicates in clustered index is currently enabled - only for intrinsic table and caller understand the limited - operation that can be done in this case. */ - ut_ad(!index->allow_duplicates - || (index->allow_duplicates - && dict_table_is_intrinsic(index->table))); - - if (!index->allow_duplicates - && n_uniq + if (n_uniq && (cursor->up_match >= n_uniq || cursor->low_match >= n_uniq)) { if (flags @@ -2593,20 +2574,13 @@ err_exit: } /* Note: Allowing duplicates would qualify for modification of - an existing record as the new entry is exactly same as old entry. - Avoid this check if allow duplicates is enabled. */ - if (!index->allow_duplicates && row_ins_must_modify_rec(cursor)) { + an existing record as the new entry is exactly same as old entry. */ + if (row_ins_must_modify_rec(cursor)) { /* There is already an index entry with a long enough common prefix, we must convert the insert into a modify of an existing record */ mem_heap_t* entry_heap = mem_heap_create(1024); - /* If the existing record is being modified and the new record - doesn't fit the provided slot then existing record is added - to free list and new record is inserted. This also means - cursor that we have cached for SELECT is now invalid. */ - index->last_sel_cur->invalid = true; - err = row_ins_clust_index_entry_by_modify( &pcur, flags, mode, &offsets, &offsets_heap, entry_heap, entry, thr, &mtr); @@ -2690,147 +2664,6 @@ func_exit: DBUG_RETURN(err); } -/** This is a specialized function meant for direct insertion to -auto-generated clustered index based on cached position from -last successful insert. To be used when data is sorted. - -@param[in] mode BTR_MODIFY_LEAF or BTR_MODIFY_TREE. - depending on whether we wish optimistic or - pessimistic descent down the index tree -@param[in,out] index clustered index -@param[in,out] entry index entry to insert -@param[in] thr query thread - -@return error code */ -static -dberr_t -row_ins_sorted_clust_index_entry( - ulint mode, - dict_index_t* index, - dtuple_t* entry, - ulint n_ext, - que_thr_t* thr) -{ - dberr_t err = DB_SUCCESS; - mtr_t* mtr; - const bool commit_mtr = mode == BTR_MODIFY_TREE; - - mem_heap_t* offsets_heap = NULL; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets = offsets_; - rec_offs_init(offsets_); - - DBUG_ENTER("row_ins_sorted_clust_index_entry"); - - ut_ad(index->last_ins_cur != NULL); - ut_ad(dict_index_is_clust(index)); - ut_ad(dict_table_is_intrinsic(index->table)); - ut_ad(dict_index_is_auto_gen_clust(index)); - - btr_cur_t cursor; - cursor.thr = thr; - mtr = &index->last_ins_cur->mtr; - - /* Search for position if tree needs to be split or if last position - is not cached. */ - if (mode == BTR_MODIFY_TREE - || index->last_ins_cur->rec == NULL - || index->last_ins_cur->disable_caching) { - - /* Commit the previous mtr. */ - index->last_ins_cur->release(); - - mtr_start(mtr); - mtr_set_log_mode(mtr, MTR_LOG_NO_REDO); - - err = btr_cur_search_to_nth_level_with_no_latch( - index, 0, entry, PAGE_CUR_LE, &cursor, - __FILE__, __LINE__, mtr); - ut_ad(cursor.page_cur.block != NULL); - ut_ad(cursor.page_cur.block->made_dirty_with_no_latch); - } else { - cursor.index = index; - - cursor.page_cur.index = index; - - cursor.page_cur.rec = index->last_ins_cur->rec; - - cursor.page_cur.block = index->last_ins_cur->block; - } - - const ulint flags = BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG; - - for (;;) { - rec_t* insert_rec; - big_rec_t* big_rec = NULL; - - if (mode != BTR_MODIFY_TREE) { - ut_ad((mode & ~BTR_ALREADY_S_LATCHED) - == BTR_MODIFY_LEAF); - - err = btr_cur_optimistic_insert( - flags, &cursor, &offsets, &offsets_heap, entry, - &insert_rec, &big_rec, n_ext, thr, mtr); - if (err != DB_SUCCESS) { - break; - } - } else { - /* TODO: Check if this is needed for intrinsic table. */ - if (buf_LRU_buf_pool_running_out()) { - err = DB_LOCK_TABLE_FULL; - break; - } - - err = btr_cur_optimistic_insert( - flags, &cursor, &offsets, &offsets_heap, entry, - &insert_rec, &big_rec, n_ext, thr, mtr); - - if (err == DB_FAIL) { - err = btr_cur_pessimistic_insert( - flags, &cursor, &offsets, &offsets_heap, - entry, &insert_rec, &big_rec, n_ext, - thr, mtr); - } - } - - if (big_rec != NULL) { - /* If index involves big-record optimization is - turned-off. */ - index->last_ins_cur->release(); - index->last_ins_cur->disable_caching = true; - - err = row_ins_index_entry_big_rec( - entry, big_rec, offsets, &offsets_heap, index, - thr_get_trx(thr)->mysql_thd, __FILE__, __LINE__); - - dtuple_convert_back_big_rec(index, entry, big_rec); - - } else if (err == DB_SUCCESS ) { - if (!commit_mtr - && !index->last_ins_cur->disable_caching) { - index->last_ins_cur->rec = insert_rec; - - index->last_ins_cur->block - = cursor.page_cur.block; - } else { - index->last_ins_cur->release(); - } - } - - break; - } - - if (err != DB_SUCCESS) { - index->last_ins_cur->release(); - } - - if (offsets_heap != NULL) { - mem_heap_free(offsets_heap); - } - - DBUG_RETURN(err); -} - /** Start a mini-transaction and check if the index will be dropped. @param[in,out] mtr mini-transaction @param[in,out] index secondary index @@ -2923,8 +2756,7 @@ row_ins_sec_index_entry_low( cursor.thr = thr; cursor.rtr_info = NULL; - ut_ad(thr_get_trx(thr)->id != 0 - || dict_table_is_intrinsic(index->table)); + ut_ad(thr_get_trx(thr)->id != 0); mtr_start(&mtr); mtr.set_named_space(index->space); @@ -2936,9 +2768,6 @@ row_ins_sec_index_entry_low( Disable locking as temp-tables are local to a connection. */ ut_ad(flags & BTR_NO_LOCKING_FLAG); - ut_ad(!dict_table_is_intrinsic(index->table) - || (flags & BTR_NO_UNDO_LOG_FLAG)); - mtr.set_log_mode(MTR_LOG_NO_REDO); } else if (!dict_index_is_spatial(index)) { /* Enable insert buffering if it's neither temp-table @@ -3008,18 +2837,10 @@ row_ins_sec_index_entry_low( goto func_exit;}); } else { - if (dict_table_is_intrinsic(index->table)) { - err = btr_cur_search_to_nth_level_with_no_latch( - index, 0, entry, PAGE_CUR_LE, &cursor, - __FILE__, __LINE__, &mtr); - ut_ad(cursor.page_cur.block != NULL); - ut_ad(cursor.page_cur.block->made_dirty_with_no_latch); - } else { - err = btr_cur_search_to_nth_level( - index, 0, entry, PAGE_CUR_LE, - search_mode, - &cursor, 0, __FILE__, __LINE__, &mtr); - } + err = btr_cur_search_to_nth_level( + index, 0, entry, PAGE_CUR_LE, + search_mode, + &cursor, 0, __FILE__, __LINE__, &mtr); } if (err != DB_SUCCESS) { @@ -3111,19 +2932,11 @@ row_ins_sec_index_entry_low( prevent any insertion of a duplicate by another transaction. Let us now reposition the cursor and continue the insertion. */ - if (dict_table_is_intrinsic(index->table)) { - err = btr_cur_search_to_nth_level_with_no_latch( - index, 0, entry, PAGE_CUR_LE, &cursor, - __FILE__, __LINE__, &mtr); - ut_ad(cursor.page_cur.block != NULL); - ut_ad(cursor.page_cur.block->made_dirty_with_no_latch); - } else { - btr_cur_search_to_nth_level( - index, 0, entry, PAGE_CUR_LE, - (search_mode - & ~(BTR_INSERT | BTR_IGNORE_SEC_UNIQUE)), - &cursor, 0, __FILE__, __LINE__, &mtr); - } + btr_cur_search_to_nth_level( + index, 0, entry, PAGE_CUR_LE, + (search_mode + & ~(BTR_INSERT | BTR_IGNORE_SEC_UNIQUE)), + &cursor, 0, __FILE__, __LINE__, &mtr); } if (!(flags & BTR_NO_LOCKING_FLAG) @@ -3169,12 +2982,6 @@ row_ins_sec_index_entry_low( } if (row_ins_must_modify_rec(&cursor)) { - /* If the existing record is being modified and the new record - is doesn't fit the provided slot then existing record is added - to free list and new record is inserted. This also means - cursor that we have cached for SELECT is now invalid. */ - index->last_sel_cur->invalid = true; - /* There is already an index entry with a long enough common prefix, we must convert the insert into a modify of an existing record */ @@ -3339,26 +3146,14 @@ row_ins_clust_index_entry( n_uniq = dict_index_is_unique(index) ? index->n_uniq : 0; /* Try first optimistic descent to the B-tree */ - ulint flags; + log_free_check(); + const ulint flags = dict_table_is_temporary(index->table) + ? BTR_NO_LOCKING_FLAG + : 0; - if (!dict_table_is_intrinsic(index->table)) { - log_free_check(); - flags = dict_table_is_temporary(index->table) - ? BTR_NO_LOCKING_FLAG - : 0; - } else { - flags = BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG; - } - - if (dict_table_is_intrinsic(index->table) - && dict_index_is_auto_gen_clust(index)) { - err = row_ins_sorted_clust_index_entry( - BTR_MODIFY_LEAF, index, entry, n_ext, thr); - } else { - err = row_ins_clust_index_entry_low( - flags, BTR_MODIFY_LEAF, index, n_uniq, entry, - n_ext, thr, dup_chk_only); - } + err = row_ins_clust_index_entry_low( + flags, BTR_MODIFY_LEAF, index, n_uniq, entry, + n_ext, thr, dup_chk_only); DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd, @@ -3370,21 +3165,11 @@ row_ins_clust_index_entry( } /* Try then pessimistic descent to the B-tree */ - if (!dict_table_is_intrinsic(index->table)) { - log_free_check(); - } else { - index->last_sel_cur->invalid = true; - } + log_free_check(); - if (dict_table_is_intrinsic(index->table) - && dict_index_is_auto_gen_clust(index)) { - err = row_ins_sorted_clust_index_entry( - BTR_MODIFY_TREE, index, entry, n_ext, thr); - } else { - err = row_ins_clust_index_entry_low( - flags, BTR_MODIFY_TREE, index, n_uniq, entry, - n_ext, thr, dup_chk_only); - } + err = row_ins_clust_index_entry_low( + flags, BTR_MODIFY_TREE, index, n_uniq, entry, + n_ext, thr, dup_chk_only); DBUG_RETURN(err); } @@ -3422,24 +3207,17 @@ row_ins_sec_index_entry( } } - ut_ad(thr_get_trx(thr)->id != 0 - || dict_table_is_intrinsic(index->table)); + ut_ad(thr_get_trx(thr)->id != 0); offsets_heap = mem_heap_create(1024); heap = mem_heap_create(1024); /* Try first optimistic descent to the B-tree */ - ulint flags; - - if (!dict_table_is_intrinsic(index->table)) { - log_free_check(); - flags = dict_table_is_temporary(index->table) - ? BTR_NO_LOCKING_FLAG - : 0; - } else { - flags = BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG; - } + log_free_check(); + const ulint flags = dict_table_is_temporary(index->table) + ? BTR_NO_LOCKING_FLAG + : 0; err = row_ins_sec_index_entry_low( flags, BTR_MODIFY_LEAF, index, offsets_heap, heap, entry, @@ -3448,12 +3226,7 @@ row_ins_sec_index_entry( mem_heap_empty(heap); /* Try then pessimistic descent to the B-tree */ - - if (!dict_table_is_intrinsic(index->table)) { - log_free_check(); - } else { - index->last_sel_cur->invalid = true; - } + log_free_check(); err = row_ins_sec_index_entry_low( flags, BTR_MODIFY_TREE, index, @@ -3892,7 +3665,6 @@ row_ins_step( node = static_cast<ins_node_t*>(thr->run_node); ut_ad(que_node_get_type(node) == QUE_NODE_INSERT); - ut_ad(!dict_table_is_intrinsic(node->table)); parent = que_node_get_parent(node); sel_node = node->select; diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 4a063c9af83..5b38b7c6c01 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1015,9 +1015,6 @@ row_create_prebuilt( prebuilt->mysql_row_len = mysql_row_len; - prebuilt->ins_sel_stmt = false; - prebuilt->session = NULL; - prebuilt->fts_doc_id_in_read_set = 0; prebuilt->blob_heap = NULL; @@ -1407,282 +1404,12 @@ run_again: return(err); } -/** Perform explicit rollback in absence of UNDO logs. -@param[in] index apply rollback action on this index -@param[in] entry entry to remove/rollback. -@param[in,out] thr thread handler. -@param[in,out] mtr mini transaction. -@return error code or DB_SUCCESS */ -static -dberr_t -row_explicit_rollback( - dict_index_t* index, - const dtuple_t* entry, - que_thr_t* thr, - mtr_t* mtr) -{ - btr_cur_t cursor; - ulint flags; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets; - mem_heap_t* heap = NULL; - dberr_t err = DB_SUCCESS; - - rec_offs_init(offsets_); - flags = BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG; - - err = btr_cur_search_to_nth_level_with_no_latch( - index, 0, entry, PAGE_CUR_LE, - &cursor, __FILE__, __LINE__, mtr); - - offsets = rec_get_offsets( - btr_cur_get_rec(&cursor), index, offsets_, - ULINT_UNDEFINED, &heap); - - if (dict_index_is_clust(index)) { - err = btr_cur_del_mark_set_clust_rec( - flags, btr_cur_get_block(&cursor), - btr_cur_get_rec(&cursor), index, - offsets, thr, entry, mtr); - } else { - err = btr_cur_del_mark_set_sec_rec( - flags, &cursor, TRUE, thr, mtr); - } - ut_ad(err == DB_SUCCESS); - - /* Void call just to set mtr modification flag - to true failing which block is not scheduled for flush*/ - byte* log_ptr = mlog_open(mtr, 0); - ut_ad(log_ptr == NULL); - if (log_ptr != NULL) { - /* To keep complier happy. */ - mlog_close(mtr, log_ptr); - } - - if (heap != NULL) { - mem_heap_free(heap); - } - - return(err); -} - -/** Convert a row in the MySQL format to a row in the Innobase format. -This is specialized function used for intrinsic table with reduce branching. -@param[in,out] row row where field values are copied. -@param[in] prebuilt prebuilt handler -@param[in] mysql_rec row in mysql format. */ -static -void -row_mysql_to_innobase( - dtuple_t* row, - row_prebuilt_t* prebuilt, - const byte* mysql_rec) -{ - ut_ad(dict_table_is_intrinsic(prebuilt->table)); - - const byte* ptr = mysql_rec; - - for (ulint i = 0; i < prebuilt->n_template; i++) { - const mysql_row_templ_t* templ; - dfield_t* dfield; - - templ = prebuilt->mysql_template + i; - dfield = dtuple_get_nth_field(row, i); - - /* Check if column has null value. */ - if (templ->mysql_null_bit_mask != 0) { - if (mysql_rec[templ->mysql_null_byte_offset] - & (byte) (templ->mysql_null_bit_mask)) { - dfield_set_null(dfield); - continue; - } - } - - /* Extract the column value. */ - ptr = mysql_rec + templ->mysql_col_offset; - const dtype_t* dtype = dfield_get_type(dfield); - ulint col_len = templ->mysql_col_len; - - ut_ad(dtype->mtype == DATA_INT - || dtype->mtype == DATA_CHAR - || dtype->mtype == DATA_MYSQL - || dtype->mtype == DATA_VARCHAR - || dtype->mtype == DATA_VARMYSQL - || dtype->mtype == DATA_BINARY - || dtype->mtype == DATA_FIXBINARY - || dtype->mtype == DATA_FLOAT - || dtype->mtype == DATA_DOUBLE - || dtype->mtype == DATA_DECIMAL - || dtype->mtype == DATA_BLOB - || dtype->mtype == DATA_GEOMETRY - || dtype->mtype == DATA_POINT - || dtype->mtype == DATA_VAR_POINT); - -#ifdef UNIV_DEBUG - if (dtype_get_mysql_type(dtype) == DATA_MYSQL_TRUE_VARCHAR) { - ut_ad(templ->mysql_length_bytes > 0); - } -#endif /* UNIV_DEBUG */ - - /* For now varchar field this has to be always 0 so - memcpy of 0 bytes shouldn't affect the original col_len. */ - if (dtype->mtype == DATA_INT) { - /* Convert and Store in big-endian. */ - byte* buf = prebuilt->ins_upd_rec_buff - + templ->mysql_col_offset; - byte* copy_to = buf + col_len; - for (;;) { - copy_to--; - *copy_to = *ptr; - if (copy_to == buf) { - break; - } - ptr++; - } - - if (!(dtype->prtype & DATA_UNSIGNED)) { - *buf ^= 128; - } - - ptr = buf; - buf += col_len; - } else if (dtype_get_mysql_type(dtype) == - DATA_MYSQL_TRUE_VARCHAR) { - - ut_ad(dtype->mtype == DATA_VARCHAR - || dtype->mtype == DATA_VARMYSQL - || dtype->mtype == DATA_BINARY); - - col_len = 0; - row_mysql_read_true_varchar( - &col_len, ptr, templ->mysql_length_bytes); - ptr += templ->mysql_length_bytes; - } else if (dtype->mtype == DATA_BLOB) { - ptr = row_mysql_read_blob_ref(&col_len, ptr, col_len); - } else if (DATA_GEOMETRY_MTYPE(dtype->mtype)) { - /* Point, Var-Point, Geometry */ - ptr = row_mysql_read_geometry(&col_len, ptr, col_len); - } - - dfield_set_data(dfield, ptr, col_len); - } -} - -/** Does an insert for MySQL using cursor interface. -Cursor interface is low level interface that directly interacts at -Storage Level by-passing all the locking and transaction semantics. -For InnoDB case, this will also by-pass hidden column generation. -@param[in] mysql_rec row in the MySQL format -@param[in,out] prebuilt prebuilt struct in MySQL handle -@return error code or DB_SUCCESS */ -static -dberr_t -row_insert_for_mysql_using_cursor( - const byte* mysql_rec, - row_prebuilt_t* prebuilt) -{ - dberr_t err = DB_SUCCESS; - ins_node_t* node = NULL; - que_thr_t* thr = NULL; - mtr_t mtr; - - /* Step-1: Get the reference of row to insert. */ - row_get_prebuilt_insert_row(prebuilt); - node = prebuilt->ins_node; - thr = que_fork_get_first_thr(prebuilt->ins_graph); - - /* Step-2: Convert row from MySQL row format to InnoDB row format. */ - row_mysql_to_innobase(node->row, prebuilt, mysql_rec); - - /* Step-3: Append row-id index is not unique. */ - dict_index_t* clust_index = dict_table_get_first_index(node->table); - - if (!dict_index_is_unique(clust_index)) { - dict_sys_write_row_id( - node->row_id_buf, - dict_table_get_next_table_sess_row_id(node->table)); - } - - trx_write_trx_id(node->trx_id_buf, - dict_table_get_next_table_sess_trx_id(node->table)); - - /* Step-4: Iterate over all the indexes and insert entries. */ - dict_index_t* inserted_upto = NULL; - node->entry = UT_LIST_GET_FIRST(node->entry_list); - for (dict_index_t* index = UT_LIST_GET_FIRST(node->table->indexes); - index != NULL; - index = UT_LIST_GET_NEXT(indexes, index), - node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry)) { - - node->index = index; - err = row_ins_index_entry_set_vals( - node->index, node->entry, node->row); - if (err != DB_SUCCESS) { - break; - } - - if (dict_index_is_clust(index)) { - err = row_ins_clust_index_entry( - node->index, node->entry, thr, 0, false); - } else { - err = row_ins_sec_index_entry( - node->index, node->entry, thr, false); - } - - if (err == DB_SUCCESS) { - inserted_upto = index; - } else { - break; - } - } - - /* Step-5: If error is encountered while inserting entries to any - of the index then entries inserted to previous indexes are removed - explicity. Automatic rollback is not in action as UNDO logs are - turned-off. */ - if (err != DB_SUCCESS) { - - node->entry = UT_LIST_GET_FIRST(node->entry_list); - - mtr_start(&mtr); - dict_disable_redo_if_temporary(node->table, &mtr); - - for (dict_index_t* index = - UT_LIST_GET_FIRST(node->table->indexes); - inserted_upto != NULL; - index = UT_LIST_GET_NEXT(indexes, index), - node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry)) { - - row_explicit_rollback(index, node->entry, thr, &mtr); - - if (index == inserted_upto) { - break; - } - } - - mtr_commit(&mtr); - } else { - /* Not protected by dict_table_stats_lock() for performance - reasons, we would rather get garbage in stat_n_rows (which is - just an estimate anyway) than protecting the following code - , with a latch. */ - dict_table_n_rows_inc(node->table); - - srv_stats.n_rows_inserted.inc(); - } - - thr_get_trx(thr)->error_state = DB_SUCCESS; - return(err); -} - -/** Does an insert for MySQL using INSERT graph. This function will run/execute -INSERT graph. +/** Does an insert for MySQL. @param[in] mysql_rec row in the MySQL format @param[in,out] prebuilt prebuilt struct in MySQL handle @return error code or DB_SUCCESS */ -static dberr_t -row_insert_for_mysql_using_ins_graph( +row_insert_for_mysql( const byte* mysql_rec, row_prebuilt_t* prebuilt) { @@ -1896,26 +1623,6 @@ error_exit: return(err); } -/** Does an insert for MySQL. -@param[in] mysql_rec row in the MySQL format -@param[in,out] prebuilt prebuilt struct in MySQL handle -@return error code or DB_SUCCESS*/ -dberr_t -row_insert_for_mysql( - const byte* mysql_rec, - row_prebuilt_t* prebuilt) -{ - /* For intrinsic tables there a lot of restrictions that can be - relaxed including locking of table, transaction handling, etc. - Use direct cursor interface for inserting to intrinsic tables. */ - if (dict_table_is_intrinsic(prebuilt->table)) { - return(row_insert_for_mysql_using_cursor(mysql_rec, prebuilt)); - } else { - return(row_insert_for_mysql_using_ins_graph( - mysql_rec, prebuilt)); - } -} - /*********************************************************************//** Builds a dummy query graph used in selects. */ void @@ -2129,314 +1836,6 @@ public: }; -typedef std::vector<btr_pcur_t, ut_allocator<btr_pcur_t> > cursors_t; - -/** Delete row from table (corresponding entries from all the indexes). -Function will maintain cursor to the entries to invoke explicity rollback -just incase update action following delete fails. - -@param[in] node update node carrying information to delete. -@param[out] delete_entries vector of cursor to deleted entries. -@param[in] restore_delete if true, then restore DELETE records by - unmarking delete. -@return error code or DB_SUCCESS */ -static -dberr_t -row_delete_for_mysql_using_cursor( - const upd_node_t* node, - cursors_t& delete_entries, - bool restore_delete) -{ - mtr_t mtr; - dict_table_t* table = node->table; - mem_heap_t* heap = mem_heap_create(1000); - dberr_t err = DB_SUCCESS; - dtuple_t* entry; - - mtr_start(&mtr); - dict_disable_redo_if_temporary(table, &mtr); - - for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); - index != NULL && err == DB_SUCCESS && !restore_delete; - index = UT_LIST_GET_NEXT(indexes, index)) { - - entry = row_build_index_entry( - node->row, node->ext, index, heap); - - btr_pcur_t pcur; - - btr_pcur_open(index, entry, PAGE_CUR_LE, - BTR_MODIFY_LEAF, &pcur, &mtr); - -#ifdef UNIV_DEBUG - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets = offsets_; - rec_offs_init(offsets_); - - offsets = rec_get_offsets( - btr_cur_get_rec(btr_pcur_get_btr_cur(&pcur)), - index, offsets, ULINT_UNDEFINED, &heap); - - ut_ad(!cmp_dtuple_rec( - entry, btr_cur_get_rec(btr_pcur_get_btr_cur(&pcur)), - offsets)); -#endif /* UNIV_DEBUG */ - - ut_ad(!rec_get_deleted_flag( - btr_cur_get_rec(btr_pcur_get_btr_cur(&pcur)), - dict_table_is_comp(index->table))); - - ut_ad(btr_pcur_get_block(&pcur)->made_dirty_with_no_latch); - - if (page_rec_is_infimum(btr_pcur_get_rec(&pcur)) - || page_rec_is_supremum(btr_pcur_get_rec(&pcur))) { - err = DB_ERROR; - } else { - btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur); - - btr_rec_set_deleted_flag( - btr_cur_get_rec(btr_cur), - buf_block_get_page_zip( - btr_cur_get_block(btr_cur)), - TRUE); - - /* Void call just to set mtr modification flag - to true failing which block is not scheduled for flush*/ - byte* log_ptr = mlog_open(&mtr, 0); - ut_ad(log_ptr == NULL); - if (log_ptr != NULL) { - /* To keep complier happy. */ - mlog_close(&mtr, log_ptr); - } - - btr_pcur_store_position(&pcur, &mtr); - - delete_entries.push_back(pcur); - } - } - - if (err != DB_SUCCESS || restore_delete) { - - /* Rollback half-way delete action that might have been - applied to few of the indexes. */ - cursors_t::iterator end = delete_entries.end(); - for (cursors_t::iterator it = delete_entries.begin(); - it != end; - ++it) { - - ibool success = btr_pcur_restore_position( - BTR_MODIFY_LEAF, &(*it), &mtr); - - if (!success) { - ut_a(success); - } else { - btr_cur_t* btr_cur = btr_pcur_get_btr_cur( - &(*it)); - - ut_ad(btr_cur_get_block( - btr_cur)->made_dirty_with_no_latch); - - btr_rec_set_deleted_flag( - btr_cur_get_rec(btr_cur), - buf_block_get_page_zip( - btr_cur_get_block(btr_cur)), - FALSE); - - /* Void call just to set mtr modification flag - to true failing which block is not scheduled for - flush. */ - byte* log_ptr = mlog_open(&mtr, 0); - ut_ad(log_ptr == NULL); - if (log_ptr != NULL) { - /* To keep complier happy. */ - mlog_close(&mtr, log_ptr); - } - } - } - } - - mtr_commit(&mtr); - - mem_heap_free(heap); - - return(err); -} - -/** Does an update of a row for MySQL by inserting new entry with update values. -@param[in] node update node carrying information to delete. -@param[out] delete_entries vector of cursor to deleted entries. -@param[in] thr thread handler -@return error code or DB_SUCCESS */ -static -dberr_t -row_update_for_mysql_using_cursor( - const upd_node_t* node, - cursors_t& delete_entries, - que_thr_t* thr) -{ - dberr_t err = DB_SUCCESS; - dict_table_t* table = node->table; - mem_heap_t* heap = mem_heap_create(1000); - dtuple_t* entry; - dfield_t* trx_id_field; - - /* Step-1: Update row-id column if table doesn't have unique index. */ - if (!dict_index_is_unique(dict_table_get_first_index(table))) { - /* Update the row_id column. */ - dfield_t* row_id_field; - - row_id_field = dtuple_get_nth_field( - node->upd_row, dict_table_get_n_cols(table) - 2); - - dict_sys_write_row_id( - static_cast<byte*>(row_id_field->data), - dict_table_get_next_table_sess_row_id(node->table)); - } - - /* Step-2: Update the trx_id column. */ - trx_id_field = dtuple_get_nth_field( - node->upd_row, dict_table_get_n_cols(table) - 1); - trx_write_trx_id(static_cast<byte*>(trx_id_field->data), - dict_table_get_next_table_sess_trx_id(node->table)); - - - /* Step-3: Check if UPDATE can lead to DUPLICATE key violation. - If yes, then avoid executing it and return error. Only after ensuring - that UPDATE is safe execute it as we can't rollback. */ - for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); - index != NULL && err == DB_SUCCESS; - index = UT_LIST_GET_NEXT(indexes, index)) { - - entry = row_build_index_entry( - node->upd_row, node->upd_ext, index, heap); - - if (dict_index_is_clust(index)) { - if (!dict_index_is_auto_gen_clust(index)) { - err = row_ins_clust_index_entry( - index, entry, thr, - node->upd_ext - ? node->upd_ext->n_ext : 0, - true); - } - } else { - err = row_ins_sec_index_entry(index, entry, thr, true); - } - } - - if (err != DB_SUCCESS) { - /* This suggest update can't be executed safely. - Avoid executing update. Rollback DELETE action. */ - row_delete_for_mysql_using_cursor(node, delete_entries, true); - } - - /* Step-4: It is now safe to execute update if there is no error */ - for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); - index != NULL && err == DB_SUCCESS; - index = UT_LIST_GET_NEXT(indexes, index)) { - - entry = row_build_index_entry( - node->upd_row, node->upd_ext, index, heap); - - if (dict_index_is_clust(index)) { - err = row_ins_clust_index_entry( - index, entry, thr, - node->upd_ext ? node->upd_ext->n_ext : 0, - false); - /* Commit the open mtr as we are processing UPDATE. */ - index->last_ins_cur->release(); - } else { - err = row_ins_sec_index_entry(index, entry, thr, false); - } - - /* Too big record is valid error and suggestion is to use - bigger page-size or different format. */ - ut_ad(err == DB_SUCCESS - || err == DB_TOO_BIG_RECORD - || err == DB_OUT_OF_FILE_SPACE); - - if (err == DB_TOO_BIG_RECORD) { - row_delete_for_mysql_using_cursor( - node, delete_entries, true); - } - } - - if (heap != NULL) { - mem_heap_free(heap); - } - return(err); -} - -/** Does an update or delete of a row for MySQL. -@param[in] mysql_rec row in the MySQL format -@param[in,out] prebuilt prebuilt struct in MySQL handle -@return error code or DB_SUCCESS */ -static -dberr_t -row_del_upd_for_mysql_using_cursor( - const byte* mysql_rec, - row_prebuilt_t* prebuilt) -{ - dberr_t err = DB_SUCCESS; - upd_node_t* node; - cursors_t delete_entries; - dict_index_t* clust_index; - que_thr_t* thr = NULL; - - /* Step-0: If there is cached insert position commit it before - starting delete/update action as this can result in btree structure - to change. */ - thr = que_fork_get_first_thr(prebuilt->upd_graph); - clust_index = dict_table_get_first_index(prebuilt->table); - clust_index->last_ins_cur->release(); - - /* Step-1: Select the appropriate cursor that will help build - the original row and updated row. */ - node = prebuilt->upd_node; - if (prebuilt->pcur->btr_cur.index == clust_index) { - btr_pcur_copy_stored_position(node->pcur, prebuilt->pcur); - } else { - btr_pcur_copy_stored_position(node->pcur, - prebuilt->clust_pcur); - } - - ut_ad(dict_table_is_intrinsic(prebuilt->table)); - ut_ad(!prebuilt->table->n_v_cols); - - /* Internal table is created by optimiser. So there - should not be any virtual columns. */ - row_upd_store_row(node, NULL, NULL); - - /* Step-2: Execute DELETE operation. */ - err = row_delete_for_mysql_using_cursor(node, delete_entries, false); - - /* Step-3: If only DELETE operation then exit immediately. */ - if (node->is_delete) { - if (err == DB_SUCCESS) { - dict_table_n_rows_dec(prebuilt->table); - srv_stats.n_rows_deleted.inc(); - } - } - - if (err == DB_SUCCESS && !node->is_delete) { - /* Step-4: Complete UPDATE operation by inserting new row with - updated data. */ - err = row_update_for_mysql_using_cursor( - node, delete_entries, thr); - - if (err == DB_SUCCESS) { - srv_stats.n_rows_updated.inc(); - } - } - - thr_get_trx(thr)->error_state = DB_SUCCESS; - cursors_t::iterator end = delete_entries.end(); - for (cursors_t::iterator it = delete_entries.begin(); it != end; ++it) { - btr_pcur_close(&(*it)); - } - - return(err); -} - /** Does an update or delete of a row for MySQL. @param[in] mysql_rec row in the MySQL format @param[in,out] prebuilt prebuilt struct in MySQL handle @@ -2794,41 +2193,8 @@ row_update_for_mysql( const byte* mysql_rec, row_prebuilt_t* prebuilt) { - if (dict_table_is_intrinsic(prebuilt->table)) { - return(row_del_upd_for_mysql_using_cursor(mysql_rec, prebuilt)); - } else { - ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW); - return(row_update_for_mysql_using_upd_graph( - mysql_rec, prebuilt)); - } -} - -/** Delete all rows for the given table by freeing/truncating indexes. -@param[in,out] table table handler -@return error code or DB_SUCCESS */ -dberr_t -row_delete_all_rows( - dict_table_t* table) -{ - dberr_t err = DB_SUCCESS; - - /* Step-0: If there is cached insert position along with mtr - commit it before starting delete/update action. */ - dict_table_get_first_index(table)->last_ins_cur->release(); - - /* Step-1: Now truncate all the indexes and re-create them. - Note: This is ddl action even though delete all rows is - DML action. Any error during this action is ir-reversible. */ - for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); - index != NULL && err == DB_SUCCESS; - index = UT_LIST_GET_NEXT(indexes, index)) { - - err = dict_truncate_index_tree_in_mem(index); - // TODO: what happen if get an error - ut_ad(err == DB_SUCCESS); - } - - return(err); + ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW); + return(row_update_for_mysql_using_upd_graph(mysql_rec, prebuilt)); } /** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this @@ -3258,13 +2624,12 @@ row_create_index_for_mysql( dict_index_t* index, /*!< in, own: index definition (will be freed) */ trx_t* trx, /*!< in: transaction handle */ - const ulint* field_lengths, /*!< in: if not NULL, must contain + const ulint* field_lengths) /*!< in: if not NULL, must contain dict_index_get_n_fields(index) actual field lengths for the index columns, which are then checked for not being too large. */ - dict_table_t* handler) /*!< in/out: table handler. */ { ind_node_t* node; mem_heap_t* heap; @@ -3287,22 +2652,11 @@ row_create_index_for_mysql( is_fts = (index->type == DICT_FTS); - if (handler != NULL && dict_table_is_intrinsic(handler)) { - table = handler; - } - - if (table == NULL) { - - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); - ut_ad(mutex_own(&dict_sys->mutex)); - - table = dict_table_open_on_name(table_name, TRUE, TRUE, - DICT_ERR_IGNORE_NONE); + ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(mutex_own(&dict_sys->mutex)); - } else { - table->acquire(); - ut_ad(dict_table_is_intrinsic(table)); - } + table = dict_table_open_on_name(table_name, TRUE, TRUE, + DICT_ERR_IGNORE_NONE); if (!dict_table_is_temporary(table)) { trx_start_if_not_started_xa(trx, true); @@ -3361,13 +2715,9 @@ row_create_index_for_mysql( index_id_t index_id = index->id; - /* add index to dictionary cache and also free index object. - We allow instrinsic table to violate the size limits because - they are used by optimizer for all record formats. */ + /* add index to dictionary cache and also free index object. */ err = dict_index_add_to_cache( - table, index, FIL_NULL, - !dict_table_is_intrinsic(table) - && trx_is_strict(trx)); + table, index, FIL_NULL, trx_is_strict(trx)); if (err != DB_SUCCESS) { goto error_handling; @@ -3375,23 +2725,13 @@ row_create_index_for_mysql( /* as above function has freed index object re-load it now from dictionary cache using index_id */ - if (!dict_table_is_intrinsic(table)) { - index = dict_index_get_if_in_cache_low(index_id); - } else { - index = dict_table_find_index_on_id(table, index_id); - - /* trx_id field is used for tracking which transaction - created the index. For intrinsic table this is - ir-relevant and so re-use it for tracking consistent - view while processing SELECT as part of UPDATE. */ - index->trx_id = ULINT_UNDEFINED; - } + index = dict_index_get_if_in_cache_low(index_id); ut_a(index != NULL); index->table = table; err = dict_create_index_tree_in_mem(index, trx); - if (err != DB_SUCCESS && !dict_table_is_intrinsic(table)) { + if (err != DB_SUCCESS) { dict_index_remove_from_cache(table, index); } } @@ -3420,7 +2760,7 @@ error_handling: trx_rollback_to_savepoint(trx, NULL); } - row_drop_table_for_mysql(table_name, trx, FALSE, true, handler); + row_drop_table_for_mysql(table_name, trx, FALSE, true); if (trx_is_started(trx)) { @@ -3489,9 +2829,6 @@ row_table_add_foreign_constraints( DEBUG_SYNC_C("table_add_foreign_constraints"); - /* Check like this shouldn't be done for table that doesn't - have foreign keys but code still continues to run with void action. - Disable it for intrinsic table at-least */ if (err == DB_SUCCESS) { /* Check that also referencing constraints are ok */ dict_names_t fk_tables; @@ -4263,23 +3600,7 @@ row_drop_table_from_cache( is going to be destroyed below. */ trx->mod_tables.erase(table); - if (!dict_table_is_intrinsic(table)) { - dict_table_remove_from_cache(table); - } else { - for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); - index != NULL; - index = UT_LIST_GET_FIRST(table->indexes)) { - - rw_lock_free(&index->lock); - - UT_LIST_REMOVE(table->indexes, index); - - dict_mem_index_free(index); - } - - dict_mem_table_free(table); - table = NULL; - } + dict_table_remove_from_cache(table); if (!is_temp && dict_load_table(tablename, true, @@ -4355,7 +3676,6 @@ will remain locked. because e.g. foreign key column @param[in] nonatomic Whether it is permitted to release and reacquire dict_operation_lock -@param[in,out] handler Table handler @return error code or DB_SUCCESS */ dberr_t row_drop_table_for_mysql( @@ -4363,18 +3683,16 @@ row_drop_table_for_mysql( trx_t* trx, bool drop_db, ibool create_failed, - bool nonatomic, - dict_table_t* handler) + bool nonatomic) { dberr_t err; dict_foreign_t* foreign; - dict_table_t* table = NULL; + dict_table_t* table; char* filepath = NULL; char* tablename = NULL; bool locked_dictionary = false; pars_info_t* info = NULL; mem_heap_t* heap = NULL; - bool is_intrinsic_temp_table = false; DBUG_ENTER("row_drop_table_for_mysql"); DBUG_PRINT("row_drop_table_for_mysql", ("table: '%s'", name)); @@ -4386,35 +3704,24 @@ row_drop_table_for_mysql( trx->op_info = "dropping table"; - if (handler != NULL && dict_table_is_intrinsic(handler)) { - table = handler; - is_intrinsic_temp_table = true; - } - - if (table == NULL) { - - if (trx->dict_operation_lock_mode != RW_X_LATCH) { - /* Prevent foreign key checks etc. while we are - dropping the table */ + if (trx->dict_operation_lock_mode != RW_X_LATCH) { + /* Prevent foreign key checks etc. while we are + dropping the table */ - row_mysql_lock_data_dictionary(trx); + row_mysql_lock_data_dictionary(trx); - locked_dictionary = true; - nonatomic = true; - } + locked_dictionary = true; + nonatomic = true; + } - ut_ad(mutex_own(&dict_sys->mutex)); - ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); + ut_ad(mutex_own(&dict_sys->mutex)); + ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X)); - table = dict_table_open_on_name( - name, TRUE, FALSE, - static_cast<dict_err_ignore_t>( - DICT_ERR_IGNORE_INDEX_ROOT - | DICT_ERR_IGNORE_CORRUPT)); - } else { - table->acquire(); - ut_ad(dict_table_is_intrinsic(table)); - } + table = dict_table_open_on_name( + name, TRUE, FALSE, + static_cast<dict_err_ignore_t>( + DICT_ERR_IGNORE_INDEX_ROOT + | DICT_ERR_IGNORE_CORRUPT)); if (!table) { err = DB_TABLE_NOT_FOUND; @@ -4495,10 +3802,7 @@ row_drop_table_for_mysql( } } - if (!dict_table_is_intrinsic(table)) { - dict_table_prevent_eviction(table); - } - + dict_table_prevent_eviction(table); dict_table_close(table, TRUE, FALSE); /* Check if the table is referenced by foreign key constraints from @@ -4600,16 +3904,11 @@ row_drop_table_for_mysql( fil_wait_crypt_bg_threads(table); if (table->get_ref_count() == 0) { - /* We don't take lock on intrinsic table so nothing to remove.*/ - if (!dict_table_is_intrinsic(table)) { - lock_remove_all_on_table(table, TRUE); - } + lock_remove_all_on_table(table, TRUE); ut_a(table->n_rec_locks == 0); } else if (table->get_ref_count() > 0 || table->n_rec_locks > 0) { ibool added; - ut_ad(!dict_table_is_intrinsic(table)); - added = row_add_table_to_background_drop_list( table->name.m_name); @@ -4641,7 +3940,7 @@ row_drop_table_for_mysql( /* If we get this far then the table to be dropped must not have any table or record locks on it. */ - ut_a(dict_table_is_intrinsic(table) || !lock_table_has_locks(table)); + ut_a(!lock_table_has_locks(table)); switch (trx_get_dict_operation(trx)) { case TRX_DICT_OP_NONE: @@ -4974,12 +4273,7 @@ funct_exit: trx->op_info = ""; - /* No need to immediately invoke master thread as there is no work - generated by intrinsic table operation that needs master thread - attention. */ - if (!is_intrinsic_temp_table) { - srv_wake_master_thread(); - } + srv_wake_master_thread(); DBUG_RETURN(err); } diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index d23a0d8c432..62fd18d027b 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -4091,320 +4091,6 @@ row_search_idx_cond_check( return(result); } -/** Traverse to next/previous record. -@param[in] moves_up if true, move to next record else previous -@param[in] match_mode 0 or ROW_SEL_EXACT or ROW_SEL_EXACT_PREFIX -@param[in,out] pcur cursor to record -@param[in] mtr mini transaction - -@return DB_SUCCESS or error code */ -static -dberr_t -row_search_traverse( - bool moves_up, - ulint match_mode, - btr_pcur_t* pcur, - mtr_t* mtr) -{ - dberr_t err = DB_SUCCESS; - - if (moves_up) { - if (!btr_pcur_move_to_next(pcur, mtr)) { - err = (match_mode != 0) - ? DB_RECORD_NOT_FOUND : DB_END_OF_INDEX; - return(err); - } - } else { - if (!btr_pcur_move_to_prev(pcur, mtr)) { - err = (match_mode != 0) - ? DB_RECORD_NOT_FOUND : DB_END_OF_INDEX; - return(err); - } - } - - return(err); -} - -/** Searches for rows in the database using cursor. -Function is for temporary tables that are not shared accross connections -and so lot of complexity is reduced especially locking and transaction related. -The cursor is an iterator over the table/index. - -@param[out] buf buffer for the fetched row in MySQL format -@param[in] mode search mode PAGE_CUR_L -@param[in,out] prebuilt prebuilt struct for the table handler; - this contains the info to search_tuple, - index; if search tuple contains 0 field then - we position the cursor at start or the end of - index, depending on 'mode' -@param[in] match_mode 0 or ROW_SEL_EXACT or ROW_SEL_EXACT_PREFIX -@param[in] direction 0 or ROW_SEL_NEXT or ROW_SEL_PREV; - Note: if this is != 0, then prebuilt must has a - pcur with stored position! In opening of a - cursor 'direction' should be 0. -@return DB_SUCCESS or error code */ -dberr_t -row_search_no_mvcc( - byte* buf, - page_cur_mode_t mode, - row_prebuilt_t* prebuilt, - ulint match_mode, - ulint direction) -{ - dict_index_t* index = prebuilt->index; - const dtuple_t* search_tuple = prebuilt->search_tuple; - btr_pcur_t* pcur = prebuilt->pcur; - - const rec_t* result_rec = NULL; - const rec_t* clust_rec = NULL; - - dberr_t err = DB_SUCCESS; - - mem_heap_t* heap = NULL; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets = offsets_; - rec_offs_init(offsets_); - ut_ad(index && pcur && search_tuple); - - /* Step-0: Re-use the cached mtr. */ - mtr_t* mtr = &index->last_sel_cur->mtr; - dict_index_t* clust_index = dict_table_get_first_index(index->table); - - /* Step-1: Build the select graph. */ - if (direction == 0 && prebuilt->sel_graph == NULL) { - row_prebuild_sel_graph(prebuilt); - } - - que_thr_t* thr = que_fork_get_first_thr(prebuilt->sel_graph); - - bool moves_up; - - if (direction == 0) { - - if (mode == PAGE_CUR_GE || mode == PAGE_CUR_G) { - moves_up = true; - } else { - moves_up = false; - } - - } else if (direction == ROW_SEL_NEXT) { - moves_up = true; - } else { - moves_up = false; - } - - /* Step-2: Open or Restore the cursor. - If search key is specified, cursor is open using the key else - cursor is open to return all the records. */ - if (direction != 0) { - if (index->last_sel_cur->invalid) { - - /* Index tree has changed and so active cached cursor - is no more valid. Re-set it based on the last selected - position. */ - index->last_sel_cur->release(); - - mtr_start(mtr); - dict_disable_redo_if_temporary(index->table, mtr); - - mem_heap_t* heap = mem_heap_create(256); - dtuple_t* tuple; - - tuple = dict_index_build_data_tuple( - index, pcur->old_rec, - pcur->old_n_fields, heap); - - btr_pcur_open_with_no_init( - index, tuple, pcur->search_mode, - BTR_SEARCH_LEAF, pcur, 0, mtr); - - mem_heap_free(heap); - } else { - /* Restore the cursor for reading next record from cache - information. */ - ut_ad(index->last_sel_cur->rec != NULL); - - pcur->btr_cur.page_cur.rec = index->last_sel_cur->rec; - pcur->btr_cur.page_cur.block = - index->last_sel_cur->block; - - err = row_search_traverse( - moves_up, match_mode, pcur, mtr); - if (err != DB_SUCCESS) { - return(err); - } - } - } else { - /* There could be previous uncommitted transaction if SELECT - is operation as part of SELECT (IF NOT FOUND) INSERT - (IF DUPLICATE) UPDATE plan. */ - index->last_sel_cur->release(); - - /* Capture table snapshot in form of trx-id. */ - index->trx_id = dict_table_get_curr_table_sess_trx_id( - index->table); - - /* Fresh search commences. */ - mtr_start(mtr); - dict_disable_redo_if_temporary(index->table, mtr); - - if (dtuple_get_n_fields(search_tuple) > 0) { - - btr_pcur_open_with_no_init( - index, search_tuple, mode, BTR_SEARCH_LEAF, - pcur, 0, mtr); - - } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_L) { - - btr_pcur_open_at_index_side( - mode == PAGE_CUR_G, index, BTR_SEARCH_LEAF, - pcur, false, 0, mtr); - - } - } - - /* Step-3: Traverse the records filtering non-qualifiying records. */ - for (/* No op */; - err == DB_SUCCESS; - err = row_search_traverse(moves_up, match_mode, pcur, mtr)) { - - const rec_t* rec = btr_pcur_get_rec(pcur); - - if (page_rec_is_infimum(rec) - || page_rec_is_supremum(rec) - || rec_get_deleted_flag( - rec, dict_table_is_comp(index->table))) { - - /* The infimum record on a page cannot be in the - result set, and neither can a record lock be placed on - it: we skip such a record. */ - continue; - } - - offsets = rec_get_offsets( - rec, index, offsets, ULINT_UNDEFINED, &heap); - - /* Note that we cannot trust the up_match value in the cursor - at this place because we can arrive here after moving the - cursor! Thus we have to recompare rec and search_tuple to - determine if they match enough. */ - if (match_mode == ROW_SEL_EXACT) { - /* Test if the index record matches completely to - search_tuple in prebuilt: if not, then we return with - DB_RECORD_NOT_FOUND */ - if (0 != cmp_dtuple_rec(search_tuple, rec, offsets)) { - err = DB_RECORD_NOT_FOUND; - break; - } - } else if (match_mode == ROW_SEL_EXACT_PREFIX) { - if (!cmp_dtuple_is_prefix_of_rec( - search_tuple, rec, offsets)) { - err = DB_RECORD_NOT_FOUND; - break; - } - } - - /* Get the clustered index. We always need clustered index - record for snapshort verification. */ - if (index != clust_index) { - - err = row_sel_get_clust_rec_for_mysql( - prebuilt, index, rec, thr, &clust_rec, - &offsets, &heap, NULL, mtr); - - if (err != DB_SUCCESS) { - break; - } - - if (rec_get_deleted_flag( - clust_rec, dict_table_is_comp(index->table))) { - - /* The record is delete marked in clustered - index. We can skip this record. */ - continue; - } - - result_rec = clust_rec; - } else { - result_rec = rec; - } - - /* Step-4: Check if row is part of the consistent view that was - captured while SELECT statement started execution. */ - { - trx_id_t trx_id; - - ulint len; - ulint trx_id_off = rec_get_nth_field_offs( - offsets, clust_index->n_uniq, &len); - - ut_ad(len == DATA_TRX_ID_LEN); - - trx_id = trx_read_trx_id(result_rec + trx_id_off); - - if (trx_id > index->trx_id) { - /* This row was recently added skip it from - SELECT view. */ - continue; - } - } - - /* Step-5: Cache the row-id of selected row to prebuilt cache.*/ - if (prebuilt->clust_index_was_generated) { - row_sel_store_row_id_to_prebuilt( - prebuilt, result_rec, clust_index, offsets); - } - - /* Step-6: Convert selected record to MySQL format and - store it. */ - if (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE) { - - const rec_t* ret_rec = - (index != clust_index - && prebuilt->need_to_access_clustered) - ? result_rec : rec; - - offsets = rec_get_offsets(ret_rec, index, offsets, - ULINT_UNDEFINED, &heap); - - memcpy(buf + 4, ret_rec - rec_offs_extra_size(offsets), - rec_offs_size(offsets)); - - mach_write_to_4(buf, rec_offs_extra_size(offsets) + 4); - - } else if (!row_sel_store_mysql_rec( - buf, prebuilt, result_rec, NULL, TRUE, - clust_index, offsets)) { - err = DB_ERROR; - break; - } - - /* Step-7: Store cursor position to fetch next record. - MySQL calls this function iteratively get_next(), get_next() - fashion. */ - ut_ad(err == DB_SUCCESS); - index->last_sel_cur->rec = btr_pcur_get_rec(pcur); - index->last_sel_cur->block = btr_pcur_get_block(pcur); - - /* This is needed in order to restore the cursor if index - structure changes while SELECT is still active. */ - pcur->old_rec = dict_index_copy_rec_order_prefix( - index, rec, &pcur->old_n_fields, - &pcur->old_rec_buf, &pcur->buf_size); - - break; - } - - if (err != DB_SUCCESS) { - index->last_sel_cur->release(); - } - - if (heap != NULL) { - mem_heap_free(heap); - } - return(err); -} - /** Extract virtual column data from a virtual index record and fill a dtuple @param[in] rec the virtual (secondary) index record @param[in] index the virtual index @@ -4459,7 +4145,7 @@ row_sel_fill_vrow( } /** Searches for rows in the database using cursor. -Function is mainly used for tables that are shared accorss connection and +Function is mainly used for tables that are shared across connections and so it employs technique that can help re-construct the rows that transaction is suppose to see. It also has optimization such as pre-caching the rows, using AHI, etc. @@ -4719,7 +4405,6 @@ row_search_mvcc( mode = PAGE_CUR_GE; if (trx->mysql_n_tables_locked == 0 - && !prebuilt->ins_sel_stmt && prebuilt->select_lock_type == LOCK_NONE && trx->isolation_level > TRX_ISO_READ_UNCOMMITTED && MVCC::is_view_active(trx->read_view)) { diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 4e515bab30d..d4b8decaea7 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -1032,9 +1032,8 @@ row_upd_build_difference_binary( n_diff = 0; trx_id_pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); - ut_ad(dict_table_is_intrinsic(index->table) - || (dict_index_get_sys_col_pos(index, DATA_ROLL_PTR) - == trx_id_pos + 1)); + ut_ad(dict_index_get_sys_col_pos(index, DATA_ROLL_PTR) + == trx_id_pos + 1); if (!offsets) { offsets = rec_get_offsets(rec, index, offsets_, @@ -1058,8 +1057,7 @@ row_upd_build_difference_binary( } /* DB_ROLL_PTR */ - if (i == trx_id_pos + 1 - && !dict_table_is_intrinsic(index->table)) { + if (i == trx_id_pos + 1) { continue; } } @@ -2255,7 +2253,7 @@ row_upd_sec_index_entry( dberr_t err = DB_SUCCESS; trx_t* trx = thr_get_trx(thr); ulint mode; - ulint flags = 0; + ulint flags; enum row_search_result search_result; ut_ad(trx->id != 0); @@ -2273,9 +2271,7 @@ row_upd_sec_index_entry( entry = row_build_index_entry(node->row, node->ext, index, heap); ut_a(entry); - if (!dict_table_is_intrinsic(index->table)) { - log_free_check(); - } + log_free_check(); DEBUG_SYNC_C_IF_THD(trx->mysql_thd, "before_row_upd_sec_index_entry"); @@ -2288,12 +2284,10 @@ row_upd_sec_index_entry( on restart for recovery. Disable locking as temp-tables are not shared across connection. */ if (dict_table_is_temporary(index->table)) { - flags |= BTR_NO_LOCKING_FLAG; + flags = BTR_NO_LOCKING_FLAG; mtr.set_log_mode(MTR_LOG_NO_REDO); - - if (dict_table_is_intrinsic(index->table)) { - flags |= BTR_NO_UNDO_LOG_FLAG; - } + } else { + flags = 0; } if (!index->is_committed()) { @@ -2877,10 +2871,6 @@ row_upd_clust_rec( if (dict_table_is_temporary(index->table)) { flags |= BTR_NO_LOCKING_FLAG; mtr->set_log_mode(MTR_LOG_NO_REDO); - - if (dict_table_is_intrinsic(index->table)) { - flags |= BTR_NO_UNDO_LOG_FLAG; - } } /* NOTE: this transaction has an s-lock or x-lock on the record and @@ -3058,7 +3048,7 @@ row_upd_clust_step( ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets; ibool referenced; - ulint flags = 0; + ulint flags; ibool foreign = FALSE; trx_t* trx = thr_get_trx(thr); @@ -3085,12 +3075,10 @@ row_upd_clust_step( on restart for recovery. Disable locking as temp-tables are not shared across connection. */ if (dict_table_is_temporary(index->table)) { - flags |= BTR_NO_LOCKING_FLAG; + flags = BTR_NO_LOCKING_FLAG; mtr.set_log_mode(MTR_LOG_NO_REDO); - - if (dict_table_is_intrinsic(index->table)) { - flags |= BTR_NO_UNDO_LOG_FLAG; - } + } else { + flags = 0; } /* If the restoration does not succeed, then the same @@ -3290,9 +3278,8 @@ row_upd( switch (node->state) { case UPD_NODE_UPDATE_CLUSTERED: case UPD_NODE_INSERT_CLUSTERED: - if (!dict_table_is_intrinsic(node->table)) { - log_free_check(); - } + log_free_check(); + err = row_upd_clust_step(node, thr); if (err != DB_SUCCESS) { diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index e7ca007e73e..38f9744e2c6 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1046,10 +1046,7 @@ srv_init(void) srv_sys->n_sys_threads = n_sys_threads; - /* Even in read-only mode we flush pages related to intrinsic table - and so mutex creation is needed. */ - { - + if (!srv_read_only_mode) { mutex_create(LATCH_ID_SRV_SYS, &srv_sys->mutex); mutex_create(LATCH_ID_SRV_SYS_TASKS, &srv_sys->tasks_mutex); @@ -1119,7 +1116,7 @@ srv_free(void) mutex_free(&srv_innodb_monitor_mutex); mutex_free(&page_zip_stat_per_index_mutex); - { + if (!srv_read_only_mode) { mutex_free(&srv_sys->mutex); mutex_free(&srv_sys->tasks_mutex); diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 4be92906851..f8347469c73 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1247,13 +1247,12 @@ srv_shutdown_all_bg_threads() /* NOTE: IF YOU CREATE THREADS IN INNODB, YOU MUST EXIT THEM HERE OR EARLIER */ - if (!srv_read_only_mode) { - - if (srv_start_state_is_set(SRV_START_STATE_LOCK_SYS)) { - /* a. Let the lock timeout thread exit */ - os_event_set(lock_sys->timeout_event); - } + if (srv_start_state_is_set(SRV_START_STATE_LOCK_SYS)) { + /* a. Let the lock timeout thread exit */ + os_event_set(lock_sys->timeout_event); + } + if (!srv_read_only_mode) { /* b. srv error monitor thread exits automatically, no need to do anything here */ @@ -1270,31 +1269,31 @@ srv_shutdown_all_bg_threads() } if (srv_start_state_is_set(SRV_START_STATE_IO)) { + ut_ad(!srv_read_only_mode); + /* e. Exit the i/o threads */ - if (!srv_read_only_mode) { - if (recv_sys->flush_start != NULL) { - os_event_set(recv_sys->flush_start); - } - if (recv_sys->flush_end != NULL) { - os_event_set(recv_sys->flush_end); - } + if (recv_sys->flush_start != NULL) { + os_event_set(recv_sys->flush_start); + } + if (recv_sys->flush_end != NULL) { + os_event_set(recv_sys->flush_end); } os_event_set(buf_flush_event); - if (!buf_page_cleaner_is_active - && os_aio_all_slots_free()) { - os_aio_wake_all_threads_at_shutdown(); + /* f. dict_stats_thread is signaled from + logs_empty_and_mark_files_at_shutdown() and + should have already quit or is quitting right + now. */ + + if (srv_use_mtflush) { + /* g. Exit the multi threaded flush threads */ + buf_mtflu_io_thread_exit(); } } - /* f. dict_stats_thread is signaled from - logs_empty_and_mark_files_at_shutdown() and should have - already quit or is quitting right now. */ - - if (srv_use_mtflush) { - /* g. Exit the multi threaded flush threads */ - buf_mtflu_io_thread_exit(); + if (!buf_page_cleaner_is_active && os_aio_all_slots_free()) { + os_aio_wake_all_threads_at_shutdown(); } bool active = os_thread_active(); @@ -1465,8 +1464,9 @@ innobase_start_or_create_for_mysql(void) if (srv_read_only_mode) { ib::info() << "Started in read only mode"; - /* There is no write except to intrinsic table and so turn-off - doublewrite mechanism completely. */ + /* There is no write to InnoDB tablespaces (not even + temporary ones, because also CREATE TEMPORARY TABLE is + refused in read-only mode). */ srv_use_doublewrite_buf = FALSE; } @@ -1856,26 +1856,26 @@ innobase_start_or_create_for_mysql(void) thread_started[t] = true; } - /* Even in read-only mode there could be flush job generated by - intrinsic table operations. */ - buf_flush_page_cleaner_init(); + if (!srv_read_only_mode) { + buf_flush_page_cleaner_init(); - os_thread_create(buf_flush_page_cleaner_coordinator, - NULL, NULL); + os_thread_create(buf_flush_page_cleaner_coordinator, + NULL, NULL); - buf_flush_page_cleaner_thread_started = true; + buf_flush_page_cleaner_thread_started = true; - for (i = 1; i < srv_n_page_cleaners; ++i) { - os_thread_create(buf_flush_page_cleaner_worker, - NULL, NULL); - } + for (i = 1; i < srv_n_page_cleaners; ++i) { + os_thread_create(buf_flush_page_cleaner_worker, + NULL, NULL); + } - /* Make sure page cleaner is active. */ - while (!buf_page_cleaner_is_active) { - os_thread_sleep(10000); - } + /* Make sure page cleaner is active. */ + while (!buf_page_cleaner_is_active) { + os_thread_sleep(10000); + } - srv_start_state_set(SRV_START_STATE_IO); + srv_start_state_set(SRV_START_STATE_IO); + } if (srv_n_log_files * srv_log_file_size * UNIV_PAGE_SIZE >= 512ULL * 1024ULL * 1024ULL * 1024ULL) { @@ -2575,10 +2575,10 @@ files_checked: purge_sys->state = PURGE_STATE_DISABLED; } - /* wake main loop of page cleaner up */ - os_event_set(buf_flush_event); - if (!srv_read_only_mode) { + /* wake main loop of page cleaner up */ + os_event_set(buf_flush_event); + if (srv_use_mtflush) { /* Start multi-threaded flush threads */ mtflush_ctx = buf_mtflu_handler_init( |