summaryrefslogtreecommitdiff
path: root/storage/innobase/row
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-11-17 21:35:12 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2022-11-17 21:35:12 +0200
commitf46efb4476d4cb7401ea73e4c452d9460bdd0f33 (patch)
tree7322dc983c668ea995631a4697d489a33db429e0 /storage/innobase/row
parent038cd5195612084542704f181695358e3b8959a8 (diff)
parentd5332086d7aa1eaef9da5850d38dd1489fad7032 (diff)
downloadmariadb-git-f46efb4476d4cb7401ea73e4c452d9460bdd0f33.tar.gz
Merge 10.7 into 10.8
Diffstat (limited to 'storage/innobase/row')
-rw-r--r--storage/innobase/row/row0import.cc30
-rw-r--r--storage/innobase/row/row0ins.cc160
-rw-r--r--storage/innobase/row/row0log.cc41
-rw-r--r--storage/innobase/row/row0merge.cc17
-rw-r--r--storage/innobase/row/row0mysql.cc16
-rw-r--r--storage/innobase/row/row0purge.cc25
-rw-r--r--storage/innobase/row/row0row.cc52
-rw-r--r--storage/innobase/row/row0sel.cc88
-rw-r--r--storage/innobase/row/row0uins.cc31
-rw-r--r--storage/innobase/row/row0umod.cc56
-rw-r--r--storage/innobase/row/row0upd.cc23
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;