diff options
Diffstat (limited to 'storage/xtradb/row/row0ins.cc')
-rw-r--r-- | storage/xtradb/row/row0ins.cc | 71 |
1 files changed, 51 insertions, 20 deletions
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc index b1291404176..934a91edc5c 100644 --- a/storage/xtradb/row/row0ins.cc +++ b/storage/xtradb/row/row0ins.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2354,24 +2354,34 @@ row_ins_clust_index_entry_low( big_rec_t* big_rec = NULL; mtr_t mtr; mem_heap_t* offsets_heap = NULL; + ulint search_mode; ut_ad(dict_index_is_clust(index)); ut_ad(!dict_index_is_unique(index) || n_uniq == dict_index_get_n_unique(index)); ut_ad(!n_uniq || n_uniq == dict_index_get_n_unique(index)); + /* If running with fake_changes mode on then switch from modify to + search so that code takes only s-latch and not x-latch. + For dry-run (fake-changes) s-latch is acceptable. Taking x-latch will + make it more restrictive and will block real changes/workflow. */ + if (UNIV_UNLIKELY(thr_get_trx(thr)->fake_changes)) { + search_mode = (mode & BTR_MODIFY_TREE) + ? BTR_SEARCH_TREE : BTR_SEARCH_LEAF; + } else { + search_mode = mode; + } + mtr_start_trx(&mtr, thr_get_trx(thr)); if (mode == BTR_MODIFY_LEAF && dict_index_is_online_ddl(index)) { - if (UNIV_UNLIKELY(thr_get_trx(thr)->fake_changes)) { - mode = BTR_SEARCH_LEAF | BTR_ALREADY_S_LATCHED; - } else { - mode = BTR_MODIFY_LEAF | BTR_ALREADY_S_LATCHED; - } + + /* We really don't need to OR mode but will leave it for + code consistency. */ + mode |= BTR_ALREADY_S_LATCHED; + search_mode |= BTR_ALREADY_S_LATCHED; + mtr_s_lock(dict_index_get_lock(index), &mtr); - } else if (UNIV_UNLIKELY(thr_get_trx(thr)->fake_changes)) { - mode = (mode & BTR_MODIFY_TREE) - ? BTR_SEARCH_TREE : BTR_SEARCH_LEAF; } cursor.thr = thr; @@ -2380,7 +2390,7 @@ row_ins_clust_index_entry_low( the function will return in both low_match and up_match of the cursor sensible values */ - btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, mode, + btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, search_mode, &cursor, 0, __FILE__, __LINE__, &mtr); #ifdef UNIV_DEBUG @@ -2652,7 +2662,7 @@ row_ins_sec_index_entry_low( que_thr_t* thr) /*!< in: query thread */ { btr_cur_t cursor; - ulint search_mode = mode | BTR_INSERT; + ulint search_mode; dberr_t err = DB_SUCCESS; ulint n_unique; mtr_t mtr; @@ -2666,6 +2676,18 @@ row_ins_sec_index_entry_low( ut_ad(thr_get_trx(thr)->id); mtr_start_trx(&mtr, trx); + /* If running with fake_changes mode on then avoid using insert buffer + and also switch from modify to search so that code takes only s-latch + and not x-latch. For dry-run (fake-changes) s-latch is acceptable. + Taking x-latch will make it more restrictive and will block real + changes/workflow. */ + if (UNIV_UNLIKELY(thr_get_trx(thr)->fake_changes)) { + search_mode = (mode & BTR_MODIFY_TREE) + ? BTR_SEARCH_TREE : BTR_SEARCH_LEAF; + } else { + search_mode = mode | BTR_INSERT; + } + /* Ensure that we acquire index->lock when inserting into an index with index->online_status == ONLINE_INDEX_COMPLETE, but could still be subject to rollback_inplace_alter_table(). @@ -2673,11 +2695,24 @@ row_ins_sec_index_entry_low( The memory object cannot be freed as long as we have an open reference to the table, or index->table->n_ref_count > 0. */ const bool check = *index->name == TEMP_INDEX_PREFIX; + if (check) { + DEBUG_SYNC_C("row_ins_sec_index_enter"); - if (mode == BTR_MODIFY_LEAF) { + + /* mode = MODIFY_LEAF is synonymous to search_mode = SEARCH_LEAF + search_mode = SEARCH_TREE suggest operation in fake_change mode + so continue to s-latch in this mode too. */ + + if (mode == BTR_MODIFY_LEAF || search_mode == BTR_SEARCH_TREE) { + + ut_ad((search_mode == BTR_SEARCH_TREE + && thr_get_trx(thr)->fake_changes) + || mode == BTR_MODIFY_LEAF); + search_mode |= BTR_ALREADY_S_LATCHED; mtr_s_lock(dict_index_get_lock(index), &mtr); + } else { mtr_x_lock(dict_index_get_lock(index), &mtr); } @@ -2688,14 +2723,13 @@ row_ins_sec_index_entry_low( } } - /* Note that we use PAGE_CUR_LE as the search mode, because then - the function will return in both low_match and up_match of the - cursor sensible values */ - if (!thr_get_trx(thr)->check_unique_secondary) { search_mode |= BTR_IGNORE_SEC_UNIQUE; } + /* Note that we use PAGE_CUR_LE as the search mode, because then + the function will return in both low_match and up_match of the + cursor sensible values */ btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, search_mode, &cursor, 0, __FILE__, __LINE__, &mtr); @@ -2775,10 +2809,7 @@ row_ins_sec_index_entry_low( btr_cur_search_to_nth_level( index, 0, entry, PAGE_CUR_LE, - UNIV_UNLIKELY(thr_get_trx(thr)->fake_changes) - ? BTR_SEARCH_LEAF - : (btr_latch_mode) - (search_mode & ~(BTR_INSERT | BTR_IGNORE_SEC_UNIQUE)), + search_mode & ~(BTR_INSERT | BTR_IGNORE_SEC_UNIQUE), &cursor, 0, __FILE__, __LINE__, &mtr); } |