diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-11-17 21:35:12 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-11-17 21:35:12 +0200 |
commit | f46efb4476d4cb7401ea73e4c452d9460bdd0f33 (patch) | |
tree | 7322dc983c668ea995631a4697d489a33db429e0 /storage/innobase/row | |
parent | 038cd5195612084542704f181695358e3b8959a8 (diff) | |
parent | d5332086d7aa1eaef9da5850d38dd1489fad7032 (diff) | |
download | mariadb-git-f46efb4476d4cb7401ea73e4c452d9460bdd0f33.tar.gz |
Merge 10.7 into 10.8
Diffstat (limited to 'storage/innobase/row')
-rw-r--r-- | storage/innobase/row/row0import.cc | 30 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.cc | 160 | ||||
-rw-r--r-- | storage/innobase/row/row0log.cc | 41 | ||||
-rw-r--r-- | storage/innobase/row/row0merge.cc | 17 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.cc | 16 | ||||
-rw-r--r-- | storage/innobase/row/row0purge.cc | 25 | ||||
-rw-r--r-- | storage/innobase/row/row0row.cc | 52 | ||||
-rw-r--r-- | storage/innobase/row/row0sel.cc | 88 | ||||
-rw-r--r-- | storage/innobase/row/row0uins.cc | 31 | ||||
-rw-r--r-- | storage/innobase/row/row0umod.cc | 56 | ||||
-rw-r--r-- | storage/innobase/row/row0upd.cc | 23 |
11 files changed, 260 insertions, 279 deletions
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index e11f4e8a26d..fbfe8a0f709 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -253,9 +253,10 @@ public: } /** Position the cursor on the first user record. */ - rec_t* open(buf_block_t* block) noexcept + rec_t* open(buf_block_t* block, const dict_index_t* index) noexcept MY_ATTRIBUTE((warn_unused_result)) { + m_cur.index = const_cast<dict_index_t*>(index); page_cur_set_before_first(block, &m_cur); return next(); } @@ -285,10 +286,9 @@ public: /** Remove the current record @return true on success */ - bool remove( - const dict_index_t* index, - rec_offs* offsets) UNIV_NOTHROW + bool remove(rec_offs* offsets) UNIV_NOTHROW { + const dict_index_t* const index = m_cur.index; ut_ad(page_is_leaf(m_cur.block->page.frame)); /* We can't end up with an empty page unless it is root. */ if (page_get_n_recs(m_cur.block->page.frame) <= 1) { @@ -311,7 +311,7 @@ public: page_zip, m_cur.block->page.frame, index)); #endif /* UNIV_ZIP_DEBUG */ - page_cur_delete_rec(&m_cur, index, offsets, &m_mtr); + page_cur_delete_rec(&m_cur, offsets, &m_mtr); #ifdef UNIV_ZIP_DEBUG ut_a(!page_zip || page_zip_validate( @@ -1513,8 +1513,9 @@ inline bool IndexPurge::open() noexcept m_mtr.start(); m_mtr.set_log_mode(MTR_LOG_NO_REDO); - if (btr_pcur_open_at_index_side(true, m_index, BTR_MODIFY_LEAF, - &m_pcur, true, 0, &m_mtr) != DB_SUCCESS) + btr_pcur_init(&m_pcur); + + if (m_pcur.open_leaf(true, m_index, BTR_MODIFY_LEAF, &m_mtr) != DB_SUCCESS) return false; rec_t *rec= page_rec_get_next(btr_pcur_get_rec(&m_pcur)); @@ -1559,7 +1560,7 @@ dberr_t IndexPurge::next() noexcept return DB_CORRUPTION; } /* The following is based on btr_pcur_move_to_next_user_rec(). */ - m_pcur.old_stored = false; + m_pcur.old_rec = nullptr; ut_ad(m_pcur.latch_mode == BTR_MODIFY_LEAF); do { if (btr_pcur_is_after_last_on_page(&m_pcur)) { @@ -1586,8 +1587,7 @@ tree structure may be changed during a pessimistic delete. */ inline dberr_t IndexPurge::purge_pessimistic_delete() noexcept { dberr_t err; - if (m_pcur.restore_position(BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE, - &m_mtr) != btr_pcur_t::CORRUPTED) + if (m_pcur.restore_position(BTR_PURGE_TREE, &m_mtr) != btr_pcur_t::CORRUPTED) { ut_ad(rec_get_deleted_flag(btr_pcur_get_rec(&m_pcur), m_index->table->not_redundant())); @@ -1722,10 +1722,8 @@ re-organising the B+tree. @return true if purge succeeded */ inline bool PageConverter::purge() UNIV_NOTHROW { - const dict_index_t* index = m_index->m_srv_index; - /* We can't have a page that is empty and not root. */ - if (m_rec_iter.remove(index, m_offsets)) { + if (m_rec_iter.remove(m_offsets)) { ++m_index->m_stats.m_n_purged; @@ -1789,7 +1787,7 @@ PageConverter::update_records( /* This will also position the cursor on the first user record. */ - if (!m_rec_iter.open(block)) { + if (!m_rec_iter.open(block, m_index->m_srv_index)) { return DB_CORRUPTION; } @@ -2289,8 +2287,8 @@ row_import_set_sys_max_row_id( mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO); - if (btr_pcur_open_at_index_side(false, index, BTR_SEARCH_LEAF, - &pcur, true, 0, &mtr) == DB_SUCCESS) { + if (pcur.open_leaf(false, index, BTR_SEARCH_LEAF, &mtr) + == DB_SUCCESS) { rec = btr_pcur_move_to_prev_on_page(&pcur); if (!rec) { diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 7f9fbe896ee..827d31eee2f 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -174,7 +174,7 @@ dberr_t row_ins_sec_index_entry_by_modify( /*==============================*/ ulint flags, /*!< in: undo logging and locking flags */ - ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE, + ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_INSERT_TREE, depending on whether mtr holds just a leaf latch or also a tree latch */ btr_cur_t* cursor, /*!< in: B-tree cursor */ @@ -194,8 +194,8 @@ row_ins_sec_index_entry_by_modify( rec = btr_cur_get_rec(cursor); - ut_ad(!dict_index_is_clust(cursor->index)); - ut_ad(rec_offs_validate(rec, cursor->index, *offsets)); + ut_ad(!cursor->index()->is_clust()); + ut_ad(rec_offs_validate(rec, cursor->index(), *offsets)); ut_ad(!entry->info_bits); /* We know that in the alphabetical ordering, entry and rec are @@ -204,7 +204,7 @@ row_ins_sec_index_entry_by_modify( difference. */ update = row_upd_build_sec_rec_difference_binary( - rec, cursor->index, *offsets, entry, heap); + rec, cursor->index(), *offsets, entry, heap); if (!rec_get_deleted_flag(rec, rec_offs_comp(*offsets))) { /* We should never insert in place of a record that @@ -218,8 +218,8 @@ row_ins_sec_index_entry_by_modify( returns. After that point, set_committed(true) would be invoked in commit_inplace_alter_table(). */ ut_a(update->n_fields == 0); - ut_a(!cursor->index->is_committed()); - ut_ad(!dict_index_is_online_ddl(cursor->index)); + ut_a(!cursor->index()->is_committed()); + ut_ad(!dict_index_is_online_ddl(cursor->index())); return(DB_SUCCESS); } @@ -241,7 +241,7 @@ row_ins_sec_index_entry_by_modify( break; } } else { - ut_a(mode == BTR_MODIFY_TREE); + ut_ad(mode == BTR_INSERT_TREE); if (buf_pool.running_out()) { return(DB_LOCK_TABLE_FULL); @@ -288,15 +288,15 @@ row_ins_clust_index_entry_by_modify( dberr_t err = DB_SUCCESS; btr_cur_t* cursor = btr_pcur_get_btr_cur(pcur); TABLE* mysql_table = NULL; - ut_ad(dict_index_is_clust(cursor->index)); + ut_ad(cursor->index()->is_clust()); rec = btr_cur_get_rec(cursor); ut_ad(rec_get_deleted_flag(rec, - dict_table_is_comp(cursor->index->table))); + cursor->index()->table->not_redundant())); /* In delete-marked records, DB_TRX_ID must always refer to an existing undo log record. */ - ut_ad(rec_get_trx_id(rec, cursor->index)); + ut_ad(rec_get_trx_id(rec, cursor->index())); /* Build an update vector containing all the fields to be modified; NOTE that this vector may NOT contain system columns trx_id or @@ -307,7 +307,7 @@ row_ins_clust_index_entry_by_modify( } update = row_upd_build_difference_binary( - cursor->index, entry, rec, NULL, true, true, + cursor->index(), entry, rec, NULL, true, true, thr_get_trx(thr), heap, mysql_table, &err); if (err != DB_SUCCESS) { return(err); @@ -1115,7 +1115,7 @@ row_ins_foreign_check_on_constraint( goto nonstandard_exit_func; } - index = btr_pcur_get_btr_cur(pcur)->index; + index = pcur->index(); ut_a(index == foreign->foreign_index); @@ -1138,7 +1138,9 @@ row_ins_foreign_check_on_constraint( ref = row_build_row_ref(ROW_COPY_POINTERS, index, rec, tmp_heap); - err = btr_pcur_open_with_no_init(clust_index, ref, + cascade->pcur->old_rec = nullptr; + cascade->pcur->btr_cur.page_cur.index = clust_index; + err = btr_pcur_open_with_no_init(ref, PAGE_CUR_LE, BTR_SEARCH_LEAF, cascade->pcur, mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { @@ -1622,9 +1624,9 @@ row_ins_check_foreign_constraint( n_fields_cmp = dtuple_get_n_fields_cmp(entry); dtuple_set_n_fields_cmp(entry, foreign->n_fields); - - err = btr_pcur_open(check_index, entry, PAGE_CUR_GE, - BTR_SEARCH_LEAF, &pcur, &mtr); + pcur.btr_cur.page_cur.index = check_index; + err = btr_pcur_open(entry, PAGE_CUR_GE, BTR_SEARCH_LEAF, &pcur, 0, + &mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { goto end_scan; } @@ -2064,9 +2066,9 @@ row_ins_scan_sec_index_for_duplicate( dtuple_set_n_fields_cmp(entry, n_unique); const auto allow_duplicates = thr_get_trx(thr)->duplicates; - - dberr_t err = btr_pcur_open(index, entry, PAGE_CUR_GE, BTR_SEARCH_LEAF, - &pcur, mtr); + pcur.btr_cur.page_cur.index = index; + dberr_t err = btr_pcur_open(entry, PAGE_CUR_GE, BTR_SEARCH_LEAF, + &pcur, 0, mtr); if (err != DB_SUCCESS) { goto end_scan; } @@ -2220,14 +2222,14 @@ row_ins_duplicate_error_in_clust_online( dberr_t err = DB_SUCCESS; const rec_t* rec = btr_cur_get_rec(cursor); - ut_ad(!cursor->index->is_instant()); + ut_ad(!cursor->index()->is_instant()); if (cursor->low_match >= n_uniq && !page_rec_is_infimum(rec)) { - *offsets = rec_get_offsets(rec, cursor->index, *offsets, - cursor->index->n_fields, + *offsets = rec_get_offsets(rec, cursor->index(), *offsets, + cursor->index()->n_fields, ULINT_UNDEFINED, heap); err = row_ins_duplicate_online(n_uniq, entry, - rec, cursor->index, *offsets); + rec, cursor->index(), *offsets); if (err != DB_SUCCESS) { return(err); } @@ -2238,11 +2240,11 @@ row_ins_duplicate_error_in_clust_online( } if (cursor->up_match >= n_uniq && !page_rec_is_supremum(rec)) { - *offsets = rec_get_offsets(rec, cursor->index, *offsets, - cursor->index->n_fields, + *offsets = rec_get_offsets(rec, cursor->index(), *offsets, + cursor->index()->n_fields, ULINT_UNDEFINED, heap); err = row_ins_duplicate_online(n_uniq, entry, - rec, cursor->index, *offsets); + rec, cursor->index(), *offsets); } return(err); @@ -2273,7 +2275,7 @@ row_ins_duplicate_error_in_clust( rec_offs* offsets = offsets_; rec_offs_init(offsets_); - ut_ad(dict_index_is_clust(cursor->index)); + ut_ad(cursor->index()->is_clust()); /* NOTE: For unique non-clustered indexes there may be any number of delete marked records with the same value for the non-clustered @@ -2288,15 +2290,17 @@ row_ins_duplicate_error_in_clust( user records on the leaf level. So, even if low_match would suggest that a duplicate key violation may occur, this may not be the case. */ - n_unique = dict_index_get_n_unique(cursor->index); + n_unique = dict_index_get_n_unique(cursor->index()); if (cursor->low_match >= n_unique) { rec = btr_cur_get_rec(cursor); if (!page_rec_is_infimum(rec)) { - offsets = rec_get_offsets(rec, cursor->index, offsets, - cursor->index->n_core_fields, + offsets = rec_get_offsets(rec, cursor->index(), + offsets, + cursor->index() + ->n_core_fields, ULINT_UNDEFINED, &heap); /* We set a lock on the possible duplicate: this @@ -2317,13 +2321,13 @@ row_ins_duplicate_error_in_clust( err = row_ins_set_exclusive_rec_lock( LOCK_REC_NOT_GAP, btr_cur_get_block(cursor), - rec, cursor->index, offsets, thr); + rec, cursor->index(), offsets, thr); } else { err = row_ins_set_shared_rec_lock( LOCK_REC_NOT_GAP, btr_cur_get_block(cursor), rec, - cursor->index, offsets, thr); + cursor->index(), offsets, thr); } switch (err) { @@ -2335,11 +2339,11 @@ row_ins_duplicate_error_in_clust( } if (row_ins_dupl_error_with_rec( - rec, entry, cursor->index, offsets)) { + rec, entry, cursor->index(), offsets)) { duplicate: - trx->error_info = cursor->index; + trx->error_info = cursor->index(); err = DB_DUPLICATE_KEY; - if (cursor->index->table->versioned() + if (cursor->index()->table->versioned() && entry->vers_history_row()) { ulint trx_id_len; @@ -2363,8 +2367,10 @@ duplicate: rec = page_rec_get_next(btr_cur_get_rec(cursor)); if (rec && !page_rec_is_supremum(rec)) { - offsets = rec_get_offsets(rec, cursor->index, offsets, - cursor->index->n_core_fields, + offsets = rec_get_offsets(rec, cursor->index(), + offsets, + cursor->index() + ->n_core_fields, ULINT_UNDEFINED, &heap); if (trx->duplicates) { @@ -2377,13 +2383,13 @@ duplicate: err = row_ins_set_exclusive_rec_lock( LOCK_REC_NOT_GAP, btr_cur_get_block(cursor), - rec, cursor->index, offsets, thr); + rec, cursor->index(), offsets, thr); } else { err = row_ins_set_shared_rec_lock( LOCK_REC_NOT_GAP, btr_cur_get_block(cursor), - rec, cursor->index, offsets, thr); + rec, cursor->index(), offsets, thr); } switch (err) { @@ -2394,7 +2400,7 @@ duplicate: /* fall through */ case DB_SUCCESS: if (row_ins_dupl_error_with_rec( - rec, entry, cursor->index, + rec, entry, cursor->index(), offsets)) { goto duplicate; } @@ -2436,7 +2442,7 @@ row_ins_must_modify_rec( and a secondary index node pointer contains all index fields. */ return(cursor->low_match - >= dict_index_get_n_unique_in_tree(cursor->index) + >= dict_index_get_n_unique_in_tree(cursor->index()) && !page_rec_is_infimum(btr_cur_get_rec(cursor))); } @@ -2465,6 +2471,7 @@ row_ins_index_entry_big_rec( btr_pcur_t pcur; rec_t* rec; + pcur.btr_cur.page_cur.index = index; ut_ad(index->is_primary()); DEBUG_SYNC_C_IF_THD(thd, "before_row_ins_extern_latch"); @@ -2476,8 +2483,8 @@ row_ins_index_entry_big_rec( index->set_modified(mtr); } - dberr_t error = btr_pcur_open(index, entry, PAGE_CUR_LE, - BTR_MODIFY_TREE, &pcur, &mtr); + dberr_t error = btr_pcur_open(entry, PAGE_CUR_LE, + BTR_MODIFY_TREE, &pcur, 0, &mtr); if (error != DB_SUCCESS) { return error; } @@ -2525,7 +2532,7 @@ dberr_t row_ins_clust_index_entry_low( /*==========================*/ ulint flags, /*!< in: undo logging and locking flags */ - ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE, + btr_latch_mode mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE, depending on whether we wish optimistic or pessimistic descent down the index tree */ dict_index_t* index, /*!< in: clustered index */ @@ -2578,7 +2585,7 @@ row_ins_clust_index_entry_low( } else { if (mode == BTR_MODIFY_LEAF && dict_index_is_online_ddl(index)) { - mode = BTR_MODIFY_LEAF_ALREADY_S_LATCHED; + mode = BTR_MODIFY_LEAF_ALREADY_LATCHED; mtr_s_lock_index(index, &mtr); } @@ -2603,8 +2610,8 @@ row_ins_clust_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 */ - err = btr_pcur_open_low(index, 0, entry, PAGE_CUR_LE, mode, &pcur, - auto_inc, &mtr); + pcur.btr_cur.page_cur.index = index; + err = btr_pcur_open(entry, PAGE_CUR_LE, mode, &pcur, auto_inc, &mtr); if (err != DB_SUCCESS) { index->table->file_unreadable = true; commit_exit: @@ -2732,7 +2739,7 @@ skip_bulk_insert: /* fall through */ case DB_SUCCESS_LOCKED_REC: case DB_DUPLICATE_KEY: - trx->error_info = cursor->index; + trx->error_info = cursor->index(); } } else { /* Note that the following may return also @@ -2769,8 +2776,8 @@ do_insert: rec_t* insert_rec; if (mode != BTR_MODIFY_TREE) { - ut_ad((mode & ulint(~BTR_ALREADY_S_LATCHED)) - == BTR_MODIFY_LEAF); + ut_ad(mode == BTR_MODIFY_LEAF || + mode == BTR_MODIFY_LEAF_ALREADY_LATCHED); err = btr_cur_optimistic_insert( flags, cursor, &offsets, &offsets_heap, entry, &insert_rec, &big_rec, @@ -2846,13 +2853,13 @@ same fields is found, the other record is necessarily marked deleted. It is then unmarked. Otherwise, the entry is just inserted to the index. @retval DB_SUCCESS on success @retval DB_LOCK_WAIT on lock wait when !(flags & BTR_NO_LOCKING_FLAG) -@retval DB_FAIL if retry with BTR_MODIFY_TREE is needed +@retval DB_FAIL if retry with BTR_INSERT_TREE is needed @return error code */ dberr_t row_ins_sec_index_entry_low( /*========================*/ ulint flags, /*!< in: undo logging and locking flags */ - ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE, + btr_latch_mode mode, /*!< in: BTR_MODIFY_LEAF or BTR_INSERT_TREE, depending on whether we wish optimistic or pessimistic descent down the index tree */ dict_index_t* index, /*!< in: secondary index */ @@ -2867,7 +2874,7 @@ row_ins_sec_index_entry_low( DBUG_ENTER("row_ins_sec_index_entry_low"); btr_cur_t cursor; - ulint search_mode = mode; + btr_latch_mode search_mode = mode; dberr_t err; ulint n_unique; mtr_t mtr; @@ -2877,10 +2884,11 @@ row_ins_sec_index_entry_low( rtr_info_t rtr_info; ut_ad(!dict_index_is_clust(index)); - ut_ad(mode == BTR_MODIFY_LEAF || mode == BTR_MODIFY_TREE); + ut_ad(mode == BTR_MODIFY_LEAF || mode == BTR_INSERT_TREE); cursor.thr = thr; cursor.rtr_info = NULL; + cursor.page_cur.index = index; ut_ad(thr_get_trx(thr)->id != 0); mtr.start(); @@ -2892,24 +2900,19 @@ row_ins_sec_index_entry_low( mtr.set_log_mode(MTR_LOG_NO_REDO); } else { index->set_modified(mtr); - if (!dict_index_is_spatial(index)) { - search_mode |= BTR_INSERT; - } } /* 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 (dict_index_is_spatial(index)) { - cursor.index = index; + if (index->is_spatial()) { rtr_init_rtr_info(&rtr_info, false, &cursor, index, false); rtr_info_update_btr(&cursor, &rtr_info); - err = btr_cur_search_to_nth_level( - index, 0, entry, PAGE_CUR_RTREE_INSERT, - search_mode, - &cursor, &mtr); + err = btr_cur_search_to_nth_level(0, entry, + PAGE_CUR_RTREE_INSERT, + search_mode, &cursor, &mtr); if (err == DB_SUCCESS && search_mode == BTR_MODIFY_LEAF && rtr_info.mbr_adj) { @@ -2926,9 +2929,8 @@ row_ins_sec_index_entry_low( index->set_modified(mtr); } err = btr_cur_search_to_nth_level( - index, 0, entry, PAGE_CUR_RTREE_INSERT, - search_mode, - &cursor, &mtr); + 0, entry, PAGE_CUR_RTREE_INSERT, + search_mode, &cursor, &mtr); } DBUG_EXECUTE_IF( @@ -2936,14 +2938,16 @@ row_ins_sec_index_entry_low( goto func_exit;}); } else { - if (!thr_get_trx(thr)->check_unique_secondary) { - search_mode |= BTR_IGNORE_SEC_UNIQUE; + if (!index->table->is_temporary()) { + search_mode = btr_latch_mode( + search_mode + | (thr_get_trx(thr)->check_unique_secondary + ? BTR_INSERT | BTR_IGNORE_SEC_UNIQUE + : BTR_INSERT)); } - err = btr_cur_search_to_nth_level( - index, 0, entry, PAGE_CUR_LE, - search_mode, - &cursor, &mtr); + err = btr_cur_search_to_nth_level(0, entry, PAGE_CUR_LE, + search_mode, &cursor, &mtr); } if (err != DB_SUCCESS) { @@ -3018,11 +3022,12 @@ row_ins_sec_index_entry_low( locked with s-locks the necessary records to prevent any insertion of a duplicate by another transaction. Let us now reposition the cursor and - continue the insertion. */ + continue the insertion (bypassing the change buffer). */ err = btr_cur_search_to_nth_level( - index, 0, entry, PAGE_CUR_LE, - (search_mode - & ~(BTR_INSERT | BTR_IGNORE_SEC_UNIQUE)), + 0, entry, PAGE_CUR_LE, + btr_latch_mode(search_mode + & ~(BTR_INSERT + | BTR_IGNORE_SEC_UNIQUE)), &cursor, &mtr); if (err != DB_SUCCESS) { goto func_exit; @@ -3061,7 +3066,6 @@ row_ins_sec_index_entry_low( err = rtr_ins_enlarge_mbr(&cursor, &mtr); } } else { - ut_ad(mode == BTR_MODIFY_TREE); if (buf_pool.running_out()) { err = DB_LOCK_TABLE_FULL; goto func_exit; @@ -3264,7 +3268,7 @@ row_ins_sec_index_entry( log_free_check(); err = row_ins_sec_index_entry_low( - flags, BTR_MODIFY_TREE, index, + flags, BTR_INSERT_TREE, index, offsets_heap, heap, entry, 0, thr); } diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index ff190bd0779..404aa8edafb 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -1583,7 +1583,7 @@ row_log_table_apply_insert_low( entry = row_build_index_entry(row, NULL, index, heap); error = row_ins_sec_index_entry_low( - flags, BTR_MODIFY_TREE, + flags, BTR_INSERT_TREE, index, offsets_heap, heap, entry, thr_get_trx(thr)->id, thr); @@ -1658,7 +1658,7 @@ row_log_table_apply_delete_low( dberr_t error; row_ext_t* ext; dtuple_t* row; - dict_index_t* index = btr_pcur_get_btr_cur(pcur)->index; + dict_index_t* index = pcur->index(); ut_ad(dict_index_is_clust(index)); @@ -1695,9 +1695,9 @@ err_exit: row, ext, index, heap); mtr->start(); index->set_modified(*mtr); - error = btr_pcur_open(index, entry, PAGE_CUR_LE, - BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE, - pcur, mtr); + pcur->btr_cur.page_cur.index = index; + error = btr_pcur_open(entry, PAGE_CUR_LE, + BTR_PURGE_TREE, pcur, 0, mtr); if (error) { goto err_exit; } @@ -1761,6 +1761,7 @@ row_log_table_apply_delete( btr_pcur_t pcur; rec_offs* offsets; + pcur.btr_cur.page_cur.index = index; ut_ad(rec_offs_n_fields(moffsets) == index->first_user_field()); ut_ad(!rec_offs_any_extern(moffsets)); @@ -1779,9 +1780,8 @@ row_log_table_apply_delete( mtr_start(&mtr); index->set_modified(mtr); - dberr_t err = btr_pcur_open(index, old_pk, PAGE_CUR_LE, - BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE, - &pcur, &mtr); + dberr_t err = btr_pcur_open(old_pk, PAGE_CUR_LE, + BTR_PURGE_TREE, &pcur, 0, &mtr); if (err != DB_SUCCESS) { goto all_done; } @@ -1893,6 +1893,8 @@ row_log_table_apply_update( dberr_t error; ulint n_index = 0; + pcur.btr_cur.page_cur.index = index; + ut_ad(dtuple_get_n_fields_cmp(old_pk) == dict_index_get_n_unique(index)); ut_ad(dtuple_get_n_fields(old_pk) - (log->same_pk ? 0 : 2) @@ -1915,8 +1917,8 @@ row_log_table_apply_update( mtr.start(); index->set_modified(mtr); - error = btr_pcur_open(index, old_pk, PAGE_CUR_LE, - BTR_MODIFY_TREE, &pcur, &mtr); + error = btr_pcur_open(old_pk, PAGE_CUR_LE, + BTR_MODIFY_TREE, &pcur, 0, &mtr); if (error != DB_SUCCESS) { func_exit: mtr.commit(); @@ -2061,7 +2063,7 @@ func_exit_committed: for (n_index += index->type != DICT_CLUSTERED; (index = dict_table_get_next_index(index)); n_index++) { - if (index->type & DICT_FTS) { + if (!index->is_btree()) { continue; } @@ -2089,9 +2091,10 @@ func_exit_committed: mtr.start(); index->set_modified(mtr); + pcur.btr_cur.page_cur.index = index; if (ROW_FOUND != row_search_index_entry( - index, entry, BTR_MODIFY_TREE, &pcur, &mtr)) { + entry, BTR_MODIFY_TREE, &pcur, &mtr)) { ut_ad(0); error = DB_CORRUPTION; break; @@ -2111,7 +2114,7 @@ func_exit_committed: error = row_ins_sec_index_entry_low( BTR_CREATE_FLAG | BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG | BTR_KEEP_SYS_FLAG, - BTR_MODIFY_TREE, index, offsets_heap, heap, + BTR_INSERT_TREE, index, offsets_heap, heap, entry, thr_get_trx(thr)->id, thr); /* Report correct index name for duplicate key error. */ @@ -3071,13 +3074,14 @@ row_log_apply_op_low( mtr_start(&mtr); index->set_modified(mtr); + cursor.page_cur.index = index; /* We perform the pessimistic variant of the operations if we already hold index->lock exclusively. First, search the record. The operation may already have been performed, depending on when the row in the clustered index was scanned. */ - *error = btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, + *error = btr_cur_search_to_nth_level(0, entry, PAGE_CUR_LE, has_index_lock ? BTR_MODIFY_TREE : BTR_MODIFY_LEAF, @@ -3132,7 +3136,7 @@ row_log_apply_op_low( mtr_start(&mtr); index->set_modified(mtr); *error = btr_cur_search_to_nth_level( - index, 0, entry, PAGE_CUR_LE, + 0, entry, PAGE_CUR_LE, BTR_MODIFY_TREE, &cursor, &mtr); if (UNIV_UNLIKELY(*error != DB_SUCCESS)) { goto func_exit; @@ -3236,7 +3240,7 @@ insert_the_rec: mtr_start(&mtr); index->set_modified(mtr); *error = btr_cur_search_to_nth_level( - index, 0, entry, PAGE_CUR_LE, + 0, entry, PAGE_CUR_LE, BTR_MODIFY_TREE, &cursor, &mtr); if (*error != DB_SUCCESS) { break; @@ -3951,8 +3955,8 @@ void UndorecApplier::log_insert(const dtuple_t &tuple, } bool success= true; - dict_index_t *index= dict_table_get_next_index(clust_index); - while (index) + for (dict_index_t *index= clust_index; + (index= dict_table_get_next_index(index)) != nullptr; ) { index->lock.s_lock(SRW_LOCK_CALL); if (index->online_log && @@ -3971,7 +3975,6 @@ void UndorecApplier::log_insert(const dtuple_t &tuple, row_log_mark_other_online_index_abort(index->table); return; } - index= dict_table_get_next_index(index); } } } diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index f9fef9747c6..a10e67850d9 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -145,13 +145,13 @@ public: mtr.start(); index->set_modified(mtr); - ins_cur.index = index; + ins_cur.page_cur.index = index; rtr_init_rtr_info(&rtr_info, false, &ins_cur, index, false); rtr_info_update_btr(&ins_cur, &rtr_info); error = btr_cur_search_to_nth_level( - index, 0, dtuple, PAGE_CUR_RTREE_INSERT, + 0, dtuple, PAGE_CUR_RTREE_INSERT, BTR_MODIFY_LEAF, &ins_cur, &mtr); /* It need to update MBR in parent entry, @@ -165,7 +165,7 @@ public: mtr.start(); index->set_modified(mtr); error = btr_cur_search_to_nth_level( - index, 0, dtuple, + 0, dtuple, PAGE_CUR_RTREE_INSERT, BTR_MODIFY_TREE, &ins_cur, &mtr); } @@ -190,7 +190,7 @@ public: rtr_info_update_btr(&ins_cur, &rtr_info); error = btr_cur_search_to_nth_level( - index, 0, dtuple, + 0, dtuple, PAGE_CUR_RTREE_INSERT, BTR_MODIFY_TREE, &ins_cur, &mtr); @@ -1999,8 +1999,7 @@ row_merge_read_clustered_index( ? col_map[old_trx_id_col] : old_trx_id_col; uint64_t n_rows = 0; - err = btr_pcur_open_at_index_side(true, clust_index, BTR_SEARCH_LEAF, - &pcur, true, 0, &mtr); + err = pcur.open_leaf(true, clust_index, BTR_SEARCH_LEAF, &mtr); if (err != DB_SUCCESS) { err_exit: trx->error_key_num = 0; @@ -2232,13 +2231,15 @@ end_of_index: if (!block) { goto err_exit; } - btr_leaf_page_release(page_cur_get_block(cur), - BTR_SEARCH_LEAF, &mtr); + page_cur_set_before_first(block, cur); if (!page_cur_move_to_next(cur) || page_cur_is_after_last(cur)) { goto corrupted_rec; } + + const auto s = mtr.get_savepoint(); + mtr.rollback_to_savepoint(s - 2, s - 1); } } else { mem_heap_empty(row_heap); diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index de469c5b088..6ac0d26bb2a 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1456,11 +1456,8 @@ row_create_update_node_for_mysql( node->in_mysql_interface = true; node->is_delete = NO_DELETE; - node->searched_update = FALSE; - node->select = NULL; - node->pcur = btr_pcur_create_for_mysql(); - - DBUG_PRINT("info", ("node: %p, pcur: %p", node, node->pcur)); + node->pcur = new (mem_heap_alloc(heap, sizeof(btr_pcur_t))) + btr_pcur_t(); node->table = table; @@ -1472,10 +1469,6 @@ row_create_update_node_for_mysql( UT_LIST_INIT(node->columns, &sym_node_t::col_var_list); node->has_clust_rec_x_lock = TRUE; - node->cmpl_info = 0; - - node->table_sym = NULL; - node->col_assign_list = NULL; DBUG_RETURN(node); } @@ -1650,8 +1643,7 @@ row_update_for_mysql(row_prebuilt_t* prebuilt) clust_index = dict_table_get_first_index(table); btr_pcur_copy_stored_position(node->pcur, - prebuilt->pcur->btr_cur.index - == clust_index + prebuilt->pcur->index() == clust_index ? prebuilt->pcur : prebuilt->clust_pcur); @@ -1804,7 +1796,7 @@ row_unlock_for_mysql( } rec = btr_pcur_get_rec(pcur); - index = btr_pcur_get_btr_cur(pcur)->index; + index = pcur->index(); /* If the record has been modified by this transaction, do not unlock it. */ diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index b60b21d2aff..df042f66521 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -67,7 +67,7 @@ static ibool row_purge_reposition_pcur( /*======================*/ - ulint mode, /*!< in: latching mode */ + btr_latch_mode mode, /*!< in: latching mode */ purge_node_t* node, /*!< in: row purge node */ mtr_t* mtr) /*!< in: mtr */ { @@ -104,7 +104,7 @@ bool row_purge_remove_clust_if_poss_low( /*===============================*/ purge_node_t* node, /*!< in/out: row purge node */ - ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ + btr_latch_mode mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ { dict_index_t* index = dict_table_get_first_index(node->table); table_id_t table_id = 0; @@ -216,7 +216,7 @@ close_and_exit: btr_pcur_get_btr_cur(&node->pcur), 0, &mtr); } else { dberr_t err; - ut_ad(mode == (BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE)); + ut_ad(mode == BTR_PURGE_TREE); btr_cur_pessimistic_delete( &err, FALSE, btr_pcur_get_btr_cur(&node->pcur), 0, false, &mtr); @@ -257,8 +257,7 @@ row_purge_remove_clust_if_poss( for (ulint n_tries = 0; n_tries < BTR_CUR_RETRY_DELETE_N_TIMES; n_tries++) { - if (row_purge_remove_clust_if_poss_low( - node, BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE)) { + if (row_purge_remove_clust_if_poss_low(node, BTR_PURGE_TREE)) { return(true); } @@ -348,11 +347,10 @@ row_purge_remove_sec_if_poss_tree( log_free_check(); mtr.start(); index->set_modified(mtr); + pcur.btr_cur.page_cur.index = index; - search_result = row_search_index_entry( - index, entry, - BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE, - &pcur, &mtr); + search_result = row_search_index_entry(entry, BTR_PURGE_TREE, + &pcur, &mtr); switch (search_result) { case ROW_NOT_FOUND: @@ -455,6 +453,7 @@ row_purge_remove_sec_if_poss_leaf( virtual index. */ mode = (index->type & (DICT_SPATIAL | DICT_VIRTUAL)) ? BTR_MODIFY_LEAF : BTR_PURGE_LEAF; + pcur.btr_cur.page_cur.index = index; /* Set the purge node for the call to row_purge_poss_sec(). */ pcur.btr_cur.purge_node = node; @@ -462,7 +461,7 @@ row_purge_remove_sec_if_poss_leaf( pcur.btr_cur.thr = NULL; index->lock.u_lock(SRW_LOCK_CALL); search_result = row_search_index_entry( - index, entry, mode, &pcur, &mtr); + entry, mode, &pcur, &mtr); index->lock.u_unlock(); } else { /* Set the query thread, so that ibuf_insert_low() will be @@ -470,7 +469,7 @@ row_purge_remove_sec_if_poss_leaf( pcur.btr_cur.thr = static_cast<que_thr_t*>( que_node_get_parent(node)); search_result = row_search_index_entry( - index, entry, mode, &pcur, &mtr); + entry, mode, &pcur, &mtr); } switch (search_result) { @@ -1343,11 +1342,11 @@ purge_node_t::validate_pcur() return(true); } - if (!pcur.old_stored) { + if (!pcur.old_rec) { return(true); } - dict_index_t* clust_index = pcur.btr_cur.index; + dict_index_t* clust_index = pcur.index(); rec_offs* offsets = rec_get_offsets( pcur.old_rec, clust_index, NULL, pcur.old_n_core_fields, diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc index 9218e739e96..599033353c5 100644 --- a/storage/innobase/row/row0row.cc +++ b/storage/innobase/row/row0row.cc @@ -1183,32 +1183,28 @@ row_build_row_ref_in_tuple( /***************************************************************//** Searches the clustered index record for a row, if we have the row reference. @return TRUE if found */ -ibool +bool row_search_on_row_ref( /*==================*/ btr_pcur_t* pcur, /*!< out: persistent cursor, which must be closed by the caller */ - ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */ + btr_latch_mode mode, /*!< in: BTR_MODIFY_LEAF, ... */ const dict_table_t* table, /*!< in: table */ const dtuple_t* ref, /*!< in: row reference */ mtr_t* mtr) /*!< in/out: mtr */ { - ulint low_match; - rec_t* rec; - dict_index_t* index; - ut_ad(dtuple_check_typed(ref)); - index = dict_table_get_first_index(table); + dict_index_t *index = dict_table_get_first_index(table); + btr_pcur_init(pcur); + pcur->btr_cur.page_cur.index = index; if (UNIV_UNLIKELY(ref->info_bits != 0)) { ut_ad(ref->is_metadata()); ut_ad(ref->n_fields <= index->n_uniq); - if (btr_pcur_open_at_index_side( - true, index, mode, pcur, true, 0, mtr) - != DB_SUCCESS + if (pcur->open_leaf(true, index, mode, mtr) != DB_SUCCESS || !btr_pcur_move_to_next_user_rec(pcur, mtr)) { - return FALSE; + return false; } /* We do not necessarily have index->is_instant() here, because we could be executing a rollback of an @@ -1220,27 +1216,14 @@ row_search_on_row_ref( & REC_INFO_MIN_REC_FLAG; } else { ut_a(ref->n_fields == index->n_uniq); - if (btr_pcur_open(index, ref, PAGE_CUR_LE, mode, pcur, mtr) + if (btr_pcur_open(ref, PAGE_CUR_LE, mode, pcur, 0, mtr) != DB_SUCCESS) { - return FALSE; + return false; } } - low_match = btr_pcur_get_low_match(pcur); - - rec = btr_pcur_get_rec(pcur); - - if (page_rec_is_infimum(rec)) { - - return(FALSE); - } - - if (low_match != dtuple_get_n_fields(ref)) { - - return(FALSE); - } - - return(TRUE); + return !page_rec_is_infimum(btr_pcur_get_rec(pcur)) + && btr_pcur_get_low_match(pcur) == dtuple_get_n_fields(ref); } /*********************************************************************//** @@ -1250,7 +1233,7 @@ on the secondary index record are preserved. rec_t* row_get_clust_rec( /*==============*/ - ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */ + btr_latch_mode mode, /*!< in: BTR_MODIFY_LEAF, ... */ const rec_t* rec, /*!< in: record in a secondary index */ dict_index_t* index, /*!< in: secondary index */ dict_index_t** clust_index,/*!< out: clustered index */ @@ -1283,9 +1266,8 @@ Searches an index record. enum row_search_result row_search_index_entry( /*===================*/ - dict_index_t* index, /*!< in: index */ const dtuple_t* entry, /*!< in: index entry */ - ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */ + btr_latch_mode mode, /*!< in: BTR_MODIFY_LEAF, ... */ btr_pcur_t* pcur, /*!< in/out: persistent cursor, which must be closed by the caller */ mtr_t* mtr) /*!< in: mtr */ @@ -1296,12 +1278,12 @@ row_search_index_entry( ut_ad(dtuple_check_typed(entry)); - if (index->is_spatial()) { - if (rtr_pcur_open(index, entry, mode, pcur, mtr)) { + if (pcur->index()->is_spatial()) { + if (rtr_pcur_open(pcur->index(), entry, mode, pcur, mtr)) { return ROW_NOT_FOUND; } } else { - if (btr_pcur_open(index, entry, PAGE_CUR_LE, mode, pcur, mtr) + if (btr_pcur_open(entry, PAGE_CUR_LE, mode, pcur, 0, mtr) != DB_SUCCESS) { return ROW_NOT_FOUND; } @@ -1310,7 +1292,7 @@ row_search_index_entry( switch (btr_pcur_get_btr_cur(pcur)->flag) { case BTR_CUR_DELETE_REF: ut_ad(!(~mode & BTR_DELETE)); - ut_ad(!index->is_spatial()); + ut_ad(!pcur->index()->is_spatial()); return(ROW_NOT_DELETED_REF); case BTR_CUR_DEL_MARK_IBUF: diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index cf1aaedf240..b13a727f59f 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -1008,17 +1008,16 @@ row_sel_get_clust_rec( *out_rec = NULL; - offsets = rec_get_offsets(rec, - btr_pcur_get_btr_cur(&plan->pcur)->index, - offsets, - btr_pcur_get_btr_cur(&plan->pcur)->index - ->n_core_fields, ULINT_UNDEFINED, &heap); + offsets = rec_get_offsets(rec, plan->pcur.index(), offsets, + plan->pcur.index()->n_core_fields, + ULINT_UNDEFINED, &heap); row_build_row_ref_fast(plan->clust_ref, plan->clust_map, rec, offsets); index = dict_table_get_first_index(plan->table); - - dberr_t err = btr_pcur_open_with_no_init(index, plan->clust_ref, + plan->clust_pcur.old_rec = nullptr; + plan->clust_pcur.btr_cur.page_cur.index = index; + dberr_t err = btr_pcur_open_with_no_init(plan->clust_ref, PAGE_CUR_LE, BTR_SEARCH_LEAF, &plan->clust_pcur, mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { @@ -1410,6 +1409,9 @@ row_sel_open_pcur( cond = UT_LIST_GET_NEXT(cond_list, cond); } + plan->pcur.old_rec = nullptr; + plan->pcur.btr_cur.page_cur.index = index; + dberr_t err; if (plan->tuple) { @@ -1429,13 +1431,12 @@ row_sel_open_pcur( que_node_get_val(exp)); } - err = btr_pcur_open_with_no_init(index, plan->tuple, + err = btr_pcur_open_with_no_init(plan->tuple, plan->mode, BTR_SEARCH_LEAF, &plan->pcur, mtr); } else { - err = btr_pcur_open_at_index_side(plan->asc, index, - BTR_SEARCH_LEAF, &plan->pcur, - false, 0, mtr); + err = plan->pcur.open_leaf(plan->asc, index, BTR_SEARCH_LEAF, + mtr); } plan->pcur_is_open = err == DB_SUCCESS; @@ -3370,6 +3371,7 @@ Row_sel_get_clust_rec_for_mysql::operator()( rec_t* old_vers; trx_t* trx; + prebuilt->clust_pcur->old_rec = nullptr; *out_rec = NULL; trx = thr_get_trx(thr); @@ -3380,9 +3382,9 @@ Row_sel_get_clust_rec_for_mysql::operator()( sec_index, *offsets); clust_index = dict_table_get_first_index(sec_index->table); + prebuilt->clust_pcur->btr_cur.page_cur.index = clust_index; - dberr_t err = btr_pcur_open_with_no_init(clust_index, - prebuilt->clust_ref, + dberr_t err = btr_pcur_open_with_no_init(prebuilt->clust_ref, PAGE_CUR_LE, BTR_SEARCH_LEAF, prebuilt->clust_pcur, mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { @@ -3447,9 +3449,10 @@ Row_sel_get_clust_rec_for_mysql::operator()( rec, sec_index, true, sec_index->n_fields, heap); page_cur_t page_cursor; + page_cursor.block = block; + page_cursor.index = sec_index; ulint up_match = 0, low_match = 0; - ut_ad(!page_cur_search_with_match(block, sec_index, - tuple, PAGE_CUR_LE, + ut_ad(!page_cur_search_with_match(tuple, PAGE_CUR_LE, &up_match, &low_match, &page_cursor, @@ -3639,7 +3642,8 @@ record with the same ordering prefix in in the B-tree index @return true if we may need to process the record the cursor is now positioned on (i.e. we should not go to the next record yet) */ static bool sel_restore_position_for_mysql(bool *same_user_rec, - ulint latch_mode, btr_pcur_t *pcur, + btr_latch_mode latch_mode, + btr_pcur_t *pcur, bool moves_up, mtr_t *mtr) { auto status = pcur->restore_position(latch_mode, mtr); @@ -3668,7 +3672,7 @@ static bool sel_restore_position_for_mysql(bool *same_user_rec, next: if (btr_pcur_move_to_next(pcur, mtr) && rec_is_metadata(btr_pcur_get_rec(pcur), - *pcur->btr_cur.index)) { + *pcur->index())) { btr_pcur_move_to_next(pcur, mtr); } @@ -3684,7 +3688,7 @@ next: prev: if (btr_pcur_is_on_user_rec(pcur) && !moves_up && !rec_is_metadata(btr_pcur_get_rec(pcur), - *pcur->btr_cur.index)) { + *pcur->index())) { if (!btr_pcur_move_to_prev(pcur, mtr)) { return true; } @@ -3964,8 +3968,9 @@ row_sel_try_search_shortcut_for_mysql( ut_ad(!index->table->is_temporary()); ut_ad(!prebuilt->templ_contains_blob); ut_ad(trx->read_view.is_open()); + pcur->old_rec = nullptr; - if (btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE, + if (btr_pcur_open_with_no_init(search_tuple, PAGE_CUR_GE, BTR_SEARCH_LEAF, pcur, mtr) != DB_SUCCESS) { return SEL_RETRY; @@ -4395,6 +4400,8 @@ row_search_mvcc( DBUG_RETURN(DB_CORRUPTION); } + pcur->btr_cur.page_cur.index = index; + /* We need to get the virtual column values stored in secondary index key, if this is covered index scan or virtual key read is requested. */ @@ -4766,6 +4773,7 @@ wait_table_again: } else if (dtuple_get_n_fields(search_tuple) > 0) { pcur->btr_cur.thr = thr; + pcur->old_rec = nullptr; if (dict_index_is_spatial(index)) { if (!prebuilt->rtr_info) { @@ -4785,7 +4793,7 @@ wait_table_again: } } - err = btr_pcur_open_with_no_init(index, search_tuple, mode, + err = btr_pcur_open_with_no_init(search_tuple, mode, BTR_SEARCH_LEAF, pcur, &mtr); if (err != DB_SUCCESS) { @@ -4831,9 +4839,8 @@ page_corrupted: } } } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_L) { - err = btr_pcur_open_at_index_side( - mode == PAGE_CUR_G, index, BTR_SEARCH_LEAF, - pcur, false, 0, &mtr); + err = pcur->open_leaf(mode == PAGE_CUR_G, index, + BTR_SEARCH_LEAF, &mtr); if (err != DB_SUCCESS) { if (err == DB_DECRYPTION_FAILED) { @@ -5019,7 +5026,7 @@ wrong_offs: page_cur_set_after_last(btr_pcur_get_block(pcur), btr_pcur_get_page_cur(pcur)); - pcur->old_stored = false; + pcur->old_rec = nullptr; goto next_rec; } } @@ -5786,7 +5793,7 @@ next_rec_after_check: /* This is based on btr_pcur_move_to_next() */ ut_ad(pcur->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(pcur->latch_mode != BTR_NO_LATCHES); - pcur->old_stored = false; + pcur->old_rec = nullptr; if (btr_pcur_is_after_last_on_page(pcur)) { if (btr_pcur_is_after_last_in_tree(pcur)) { goto not_moved; @@ -6198,8 +6205,6 @@ dberr_t row_check_index(row_prebuilt_t *prebuilt, ulint *n_rows) *n_rows= 0; dict_index_t *const index= prebuilt->index; - prebuilt->fetch_direction= ROW_SEL_NEXT; - if (!index->is_btree()) return DB_CORRUPTION; @@ -6210,9 +6215,8 @@ dberr_t row_check_index(row_prebuilt_t *prebuilt, ulint *n_rows) mtr.start(); dict_index_t *clust_index= dict_table_get_first_index(prebuilt->table); - - dberr_t err= btr_pcur_open_at_index_side(true, index, BTR_SEARCH_LEAF, - prebuilt->pcur, false, 0, &mtr); + prebuilt->clust_pcur->btr_cur.page_cur.index = clust_index; + dberr_t err= prebuilt->pcur->open_leaf(true, index, BTR_SEARCH_LEAF, &mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { func_exit: @@ -6300,14 +6304,16 @@ rec_loop: goto next_rec; } - if (index->is_clust()) + if (prebuilt->table->is_temporary()) { - if (prebuilt->trx->isolation_level == TRX_ISO_READ_UNCOMMITTED) - { - if (!rec_deleted) - goto count_row; + count_or_not: + if (rec_deleted) goto next_rec; - } + } + else if (index->is_clust()) + { + if (prebuilt->trx->isolation_level == TRX_ISO_READ_UNCOMMITTED) + goto count_or_not; trx_id_t rec_trx_id= row_get_rec_trx_id(rec, index, offsets); @@ -6371,10 +6377,7 @@ rec_loop: ER_NOT_KEYFILE, "InnoDB: %s", w.m_oss.str().c_str()); } - if (!rec_deleted) - goto count_row; - - goto next_rec; + goto count_or_not; } else if (const trx_id_t page_trx_id= page_get_max_trx_id(page_align(rec))) { @@ -6388,7 +6391,7 @@ rec_loop: const auto savepoint= mtr.get_savepoint(); row_build_row_ref_in_tuple(prebuilt->clust_ref, rec, index, offsets); - err= btr_pcur_open_with_no_init(clust_index, prebuilt->clust_ref, + err= btr_pcur_open_with_no_init(prebuilt->clust_ref, PAGE_CUR_LE, BTR_SEARCH_LEAF, prebuilt->clust_pcur, &mtr); if (err != DB_SUCCESS) @@ -6887,8 +6890,7 @@ row_search_get_max_rec( const rec_t* rec; const bool desc = index->fields[0].descending; - if (btr_pcur_open_at_index_side(desc, index, BTR_SEARCH_LEAF, &pcur, - true, 0, mtr) != DB_SUCCESS) { + if (pcur.open_leaf(desc, index, BTR_SEARCH_LEAF, mtr) != DB_SUCCESS) { return nullptr; } diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index f730637c8d2..6567019a33d 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -68,7 +68,7 @@ row_undo_ins_remove_clust_rec( dberr_t err; ulint n_tries = 0; mtr_t mtr; - dict_index_t* index = node->pcur.btr_cur.index; + dict_index_t* index = node->pcur.index(); table_id_t table_id = 0; const bool dict_locked = node->trx->dict_operation_lock_mode; restart: @@ -207,9 +207,8 @@ retry: } else { index->set_modified(mtr); } - ut_a( - node->pcur.restore_position(BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE, - &mtr) == btr_pcur_t::SAME_ALL); + ut_a(node->pcur.restore_position(BTR_PURGE_TREE, &mtr) + == btr_pcur_t::SAME_ALL); btr_cur_pessimistic_delete(&err, FALSE, &node->pcur.btr_cur, 0, true, &mtr); @@ -254,7 +253,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_ins_remove_sec_low( /*========================*/ - ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE, + btr_latch_mode mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE, depending on whether we wish optimistic or pessimistic descent down the index tree */ dict_index_t* index, /*!< in: index */ @@ -266,25 +265,27 @@ row_undo_ins_remove_sec_low( mtr_t mtr; const bool modify_leaf = mode == BTR_MODIFY_LEAF; + pcur.btr_cur.page_cur.index = index; row_mtr_start(&mtr, index, !modify_leaf); if (modify_leaf) { - mode = BTR_MODIFY_LEAF | BTR_ALREADY_S_LATCHED; + mode = BTR_MODIFY_LEAF_ALREADY_LATCHED; mtr_s_lock_index(index, &mtr); } else { - ut_ad(mode == (BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE)); + ut_ad(mode == BTR_PURGE_TREE); mtr_sx_lock_index(index, &mtr); } - if (dict_index_is_spatial(index)) { - if (modify_leaf) { - mode |= BTR_RTREE_DELETE_MARK; - } + if (index->is_spatial()) { + mode = modify_leaf + ? btr_latch_mode(BTR_MODIFY_LEAF_ALREADY_LATCHED + | BTR_RTREE_DELETE_MARK + | BTR_RTREE_UNDO_INS) + : btr_latch_mode(BTR_PURGE_TREE | BTR_RTREE_UNDO_INS); btr_pcur_get_btr_cur(&pcur)->thr = thr; - mode |= BTR_RTREE_UNDO_INS; } - switch (row_search_index_entry(index, entry, mode, &pcur, &mtr)) { + switch (row_search_index_entry(entry, mode, &pcur, &mtr)) { case ROW_BUFFERED: case ROW_NOT_DELETED_REF: /* These are invalid outcomes, because the mode passed @@ -349,9 +350,7 @@ row_undo_ins_remove_sec( /* Try then pessimistic descent to the B-tree */ retry: - err = row_undo_ins_remove_sec_low( - BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE, - index, entry, thr); + err = row_undo_ins_remove_sec_low(BTR_PURGE_TREE, index, entry, thr); /* The delete operation may fail if we have little file space left: TODO: easiest to crash the database diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index cca44f01920..2d04dca4003 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -84,7 +84,7 @@ row_undo_mod_clust_low( que_thr_t* thr, /*!< in: query thread */ mtr_t* mtr, /*!< in: mtr; must be committed before latching any further pages */ - ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ + btr_latch_mode mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ { btr_pcur_t* pcur; btr_cur_t* btr_cur; @@ -106,8 +106,8 @@ row_undo_mod_clust_low( || node->update->info_bits == REC_INFO_METADATA_ALTER); if (mode != BTR_MODIFY_TREE) { - ut_ad((mode & ulint(~BTR_ALREADY_S_LATCHED)) - == BTR_MODIFY_LEAF); + ut_ad(mode == BTR_MODIFY_LEAF + || mode == BTR_MODIFY_LEAF_ALREADY_LATCHED); err = btr_cur_optimistic_update( BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG @@ -224,14 +224,14 @@ static bool row_undo_mod_must_purge(const undo_node_t &node) ut_ad(!node.table->is_temporary()); const btr_cur_t &btr_cur= node.pcur.btr_cur; - ut_ad(btr_cur.index->is_primary()); + ut_ad(btr_cur.index()->is_primary()); DEBUG_SYNC_C("rollback_purge_clust"); if (!purge_sys.is_purgeable(node.new_trx_id)) return false; const rec_t *rec= btr_cur_get_rec(&btr_cur); - return trx_read_trx_id(rec + row_trx_id_offset(rec, btr_cur.index)) == + return trx_read_trx_id(rec + row_trx_id_offset(rec, btr_cur.index())) == node.new_trx_id; } @@ -356,8 +356,7 @@ row_undo_mod_clust( } mtr.start(); - if (pcur->restore_position( - BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE, &mtr) != + if (pcur->restore_position(BTR_PURGE_TREE, &mtr) != btr_pcur_t::SAME_ALL) { goto mtr_commit_exit; } @@ -483,7 +482,7 @@ row_undo_mod_del_mark_or_remove_sec_low( que_thr_t* thr, /*!< in: query thread */ dict_index_t* index, /*!< in: index */ dtuple_t* entry, /*!< in: index entry */ - ulint mode) /*!< in: latch mode BTR_MODIFY_LEAF or + btr_latch_mode mode) /*!< in: latch mode BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ { btr_pcur_t pcur; @@ -496,15 +495,25 @@ row_undo_mod_del_mark_or_remove_sec_low( row_mtr_start(&mtr, index, !modify_leaf); - if (!index->is_committed()) { + pcur.btr_cur.page_cur.index = index; + btr_cur = btr_pcur_get_btr_cur(&pcur); + + if (index->is_spatial()) { + mode = modify_leaf + ? btr_latch_mode(BTR_MODIFY_LEAF + | BTR_RTREE_DELETE_MARK + | BTR_RTREE_UNDO_INS) + : btr_latch_mode(BTR_PURGE_TREE | BTR_RTREE_UNDO_INS); + btr_cur->thr = thr; + } else if (!index->is_committed()) { /* The index->online_status may change if the index is or was being created online, but not committed yet. It is protected by index->lock. */ if (modify_leaf) { - mode = BTR_MODIFY_LEAF | BTR_ALREADY_S_LATCHED; + mode = BTR_MODIFY_LEAF_ALREADY_LATCHED; mtr_s_lock_index(index, &mtr); } else { - ut_ad(mode == (BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE)); + ut_ad(mode == BTR_PURGE_TREE); mtr_sx_lock_index(index, &mtr); } } else { @@ -514,18 +523,7 @@ row_undo_mod_del_mark_or_remove_sec_low( ut_ad(!dict_index_is_online_ddl(index)); } - btr_cur = btr_pcur_get_btr_cur(&pcur); - - if (dict_index_is_spatial(index)) { - if (modify_leaf) { - btr_cur->thr = thr; - mode |= BTR_RTREE_DELETE_MARK; - } - mode |= BTR_RTREE_UNDO_INS; - } - - search_result = row_search_index_entry(index, entry, mode, - &pcur, &mtr); + search_result = row_search_index_entry(entry, mode, &pcur, &mtr); switch (UNIV_EXPECT(search_result, ROW_FOUND)) { case ROW_NOT_FOUND: @@ -634,7 +632,7 @@ row_undo_mod_del_mark_or_remove_sec( } err = row_undo_mod_del_mark_or_remove_sec_low(node, thr, index, - entry, BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE); + entry, BTR_PURGE_TREE); return(err); } @@ -652,7 +650,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_mod_del_unmark_sec_and_undo_update( /*========================================*/ - ulint mode, /*!< in: search mode: BTR_MODIFY_LEAF or + btr_latch_mode mode, /*!< in: search mode: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ que_thr_t* thr, /*!< in: query thread */ dict_index_t* index, /*!< in: index */ @@ -668,8 +666,9 @@ row_undo_mod_del_unmark_sec_and_undo_update( const ulint flags = BTR_KEEP_SYS_FLAG | BTR_NO_LOCKING_FLAG; row_search_result search_result; - ulint orig_mode = mode; + const auto orig_mode = mode; + pcur.btr_cur.page_cur.index = index; ut_ad(trx->id != 0); if (dict_index_is_spatial(index)) { @@ -679,7 +678,7 @@ row_undo_mod_del_unmark_sec_and_undo_update( secondary index updates to avoid this. */ static_assert(BTR_MODIFY_TREE == (8 | BTR_MODIFY_LEAF), ""); ut_ad(!(mode & 8)); - mode |= BTR_RTREE_DELETE_MARK; + mode = btr_latch_mode(mode | BTR_RTREE_DELETE_MARK); } try_again: @@ -687,8 +686,7 @@ try_again: btr_cur->thr = thr; - search_result = row_search_index_entry(index, entry, mode, - &pcur, &mtr); + search_result = row_search_index_entry(entry, mode, &pcur, &mtr); switch (search_result) { mem_heap_t* heap; diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 26c434ca474..3b2fe849bcd 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -1840,7 +1840,7 @@ row_upd_sec_index_entry( btr_cur_t* btr_cur; dberr_t err = DB_SUCCESS; trx_t* trx = thr_get_trx(thr); - ulint mode; + btr_latch_mode mode; ulint flags; enum row_search_result search_result; @@ -1870,14 +1870,16 @@ row_upd_sec_index_entry( "before_row_upd_sec_index_entry"); mtr.start(); + mode = BTR_MODIFY_LEAF; switch (index->table->space_id) { case SRV_TMP_SPACE_ID: mtr.set_log_mode(MTR_LOG_NO_REDO); flags = BTR_NO_LOCKING_FLAG; - mode = index->is_spatial() - ? ulint(BTR_MODIFY_LEAF | BTR_RTREE_DELETE_MARK) - : ulint(BTR_MODIFY_LEAF); + if (index->is_spatial()) { + mode = btr_latch_mode(BTR_MODIFY_LEAF + | BTR_RTREE_DELETE_MARK); + } break; default: index->set_modified(mtr); @@ -1887,18 +1889,19 @@ row_upd_sec_index_entry( /* We can only buffer delete-mark operations if there are no foreign key constraints referring to the index. */ mode = index->is_spatial() - ? ulint(BTR_MODIFY_LEAF | BTR_RTREE_DELETE_MARK) + ? btr_latch_mode(BTR_MODIFY_LEAF + | BTR_RTREE_DELETE_MARK) : referenced - ? ulint(BTR_MODIFY_LEAF) : ulint(BTR_DELETE_MARK_LEAF); + ? BTR_MODIFY_LEAF : BTR_DELETE_MARK_LEAF; break; } /* Set the query thread, so that ibuf_insert_low() will be able to invoke thd_get_trx(). */ btr_pcur_get_btr_cur(&pcur)->thr = thr; + pcur.btr_cur.page_cur.index = index; - search_result = row_search_index_entry(index, entry, mode, - &pcur, &mtr); + search_result = row_search_index_entry(entry, mode, &pcur, &mtr); btr_cur = btr_pcur_get_btr_cur(&pcur); @@ -2590,13 +2593,13 @@ row_upd_clust_step( ut_a(pcur->rel_pos == BTR_PCUR_ON); - ulint mode; + btr_latch_mode mode; DEBUG_SYNC_C_IF_THD(trx->mysql_thd, "innodb_row_upd_clust_step_enter"); if (dict_index_is_online_ddl(index)) { ut_ad(node->table->id != DICT_INDEXES_ID); - mode = BTR_MODIFY_LEAF | BTR_ALREADY_S_LATCHED; + mode = BTR_MODIFY_LEAF_ALREADY_LATCHED; mtr_s_lock_index(index, &mtr); } else { mode = BTR_MODIFY_LEAF; |