MDEV-29603: Implement btr_cur_t::open_leaf()

btr_cur_t::open_leaf(): Replaces btr_cur_open_at_index_side() for
most calls, except dict_stats_analyze_index(), which is the only
place where we need to open a page at the non-leaf level.
Use btr_block_get() for better error handling.

Also, use the enumeration type btr_latch_mode wherever possible.

Reviewed by: Vladislav Lesin
This commit is contained in:
Marko Mäkelä 2022-11-16 09:43:48 +02:00
parent 6b2d6a81d4
commit 89ec4b53ac
28 changed files with 627 additions and 452 deletions

View File

@ -726,7 +726,7 @@ btr_page_get_father_node_ptr_func(
btr_cur_t* cursor, /*!< in: cursor pointing to user record,
out: cursor on node pointer record,
its page x-latched */
ulint latch_mode,/*!< in: BTR_CONT_MODIFY_TREE
btr_latch_mode latch_mode,/*!< in: BTR_CONT_MODIFY_TREE
or BTR_CONT_SEARCH_TREE */
mtr_t* mtr) /*!< in: mtr */
{

View File

@ -196,7 +196,7 @@ btr_rec_free_externally_stored_fields(
void
btr_cur_latch_leaves(
buf_block_t* block,
ulint latch_mode,
btr_latch_mode latch_mode,
btr_cur_t* cursor,
mtr_t* mtr,
btr_latch_leaves_t* latch_leaves)
@ -223,6 +223,8 @@ btr_cur_latch_leaves(
static_assert(BTR_SEARCH_LEAF & BTR_SEARCH_TREE, "");
switch (latch_mode) {
default:
break;
uint32_t left_page_no;
uint32_t right_page_no;
ulint save;
@ -392,10 +394,10 @@ static dberr_t btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr)
/* Relax the assertion in rec_init_offsets(). */
ut_ad(!index->in_instant_init);
ut_d(index->in_instant_init = true);
err = btr_cur_open_at_index_side(true, index, BTR_SEARCH_LEAF,
&cur, 0, mtr);
err = cur.open_leaf(true, index, BTR_SEARCH_LEAF, mtr);
ut_d(index->in_instant_init = false);
if (err != DB_SUCCESS) {
index->table->file_unreadable = true;
index->table->corrupted = true;
return err;
}
@ -738,7 +740,7 @@ bool
btr_cur_optimistic_latch_leaves(
buf_block_t* block,
ib_uint64_t modify_clock,
ulint* latch_mode,
btr_latch_mode* latch_mode,
btr_cur_t* cursor,
mtr_t* mtr)
{
@ -803,7 +805,7 @@ btr_cur_optimistic_latch_leaves(
buf_page_optimistic_get() buffer-fixes
it again. */
ut_ad(2 <= block->page.buf_fix_count());
*latch_mode = mode;
*latch_mode = btr_latch_mode(mode);
return(true);
} else {
/* release the block and decrement of
@ -828,9 +830,7 @@ at the latch_mode.
@param latch_mode in/out: pointer to latch_mode
@return intention for latching tree */
static
btr_intention_t
btr_cur_get_and_clear_intention(
ulint *latch_mode)
btr_intention_t btr_cur_get_and_clear_intention(btr_latch_mode *latch_mode)
{
btr_intention_t intention;
@ -845,7 +845,8 @@ btr_cur_get_and_clear_intention(
/* both or unknown */
intention = BTR_INTENTION_BOTH;
}
*latch_mode &= ulint(~(BTR_LATCH_FOR_INSERT | BTR_LATCH_FOR_DELETE));
*latch_mode = btr_latch_mode(
*latch_mode & ~(BTR_LATCH_FOR_INSERT | BTR_LATCH_FOR_DELETE));
return(intention);
}
@ -1232,7 +1233,8 @@ or on a page infimum record.
TRANSACTIONAL_TARGET
dberr_t btr_cur_search_to_nth_level(dict_index_t *index, ulint level,
const dtuple_t *tuple,
page_cur_mode_t mode, ulint latch_mode,
page_cur_mode_t mode,
btr_latch_mode latch_mode,
btr_cur_t *cursor, mtr_t *mtr,
ib_uint64_t autoinc)
{
@ -2408,6 +2410,239 @@ dberr_t btr_cur_search_to_nth_level(dict_index_t *index, ulint level,
DBUG_RETURN(err);
}
dberr_t btr_cur_t::open_leaf(bool first, dict_index_t *index,
btr_latch_mode latch_mode, mtr_t *mtr)
{
ulint node_ptr_max_size= srv_page_size / 2;
btr_intention_t lock_intention;
buf_block_t *tree_blocks[BTR_MAX_LEVELS]; // FIXME: just use mtr->m_memo
ulint tree_savepoints[BTR_MAX_LEVELS];
ulint n_blocks= 0;
ulint n_releases= 0;
mem_heap_t *heap= nullptr;
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs *offsets= offsets_;
dberr_t err;
rec_offs_init(offsets_);
const bool latch_by_caller= latch_mode & BTR_ALREADY_S_LATCHED;
latch_mode = btr_latch_mode(latch_mode & ~BTR_ALREADY_S_LATCHED);
lock_intention= btr_cur_get_and_clear_intention(&latch_mode);
/* This function doesn't need to lock left page of the leaf page */
if (latch_mode == BTR_SEARCH_PREV)
latch_mode= BTR_SEARCH_LEAF;
else if (latch_mode == BTR_MODIFY_PREV)
latch_mode= BTR_MODIFY_LEAF;
/* Store the position of the tree latch we push to mtr so that we
know how to release it when we have latched the leaf node */
auto savepoint= mtr->get_savepoint();
rw_lock_type_t upper_rw_latch= RW_X_LATCH;
switch (latch_mode) {
case BTR_CONT_MODIFY_TREE:
case BTR_CONT_SEARCH_TREE:
abort();
break;
case BTR_MODIFY_TREE:
/* Most of delete-intended operations are purging. Free blocks
and read IO bandwidth should be prioritized for them, when the
history list is growing huge. */
savepoint+= sizeof(mtr_memo_slot_t);
if (lock_intention == BTR_INTENTION_DELETE
&& buf_pool.n_pend_reads
&& trx_sys.history_size_approx() > BTR_CUR_FINE_HISTORY_LENGTH)
mtr_x_lock_index(index, mtr);
else
mtr_sx_lock_index(index, mtr);
break;
default:
ut_ad(!latch_by_caller ||
mtr->memo_contains_flagged(&index->lock,
MTR_MEMO_SX_LOCK | MTR_MEMO_S_LOCK));
upper_rw_latch= RW_S_LATCH;
if (latch_by_caller)
break;
ut_ad(latch_mode != BTR_SEARCH_TREE);
savepoint+= sizeof(mtr_memo_slot_t);
mtr_s_lock_index(index, mtr);
}
ut_ad(savepoint == mtr->get_savepoint());
const rw_lock_type_t root_leaf_rw_latch=
btr_cur_latch_for_root_leaf(latch_mode);
this->index = index;
page_id_t page_id(index->table->space_id, index->page);
const auto zip_size= index->table->space->zip_size();
if (root_leaf_rw_latch == RW_X_LATCH)
node_ptr_max_size= btr_node_ptr_max_size(index);
for (ulint height= ULINT_UNDEFINED;;)
{
ut_ad(n_blocks < BTR_MAX_LEVELS);
#if 0 // FIXME: encryption.innodb_onlinealter_encryption innodb.alter_algorithm
ut_ad(savepoint + n_blocks * sizeof(mtr_memo_slot_t) == mtr->get_savepoint());
#endif
tree_savepoints[n_blocks]= mtr->get_savepoint();
const rw_lock_type_t rw_latch= height && latch_mode != BTR_MODIFY_TREE
? upper_rw_latch
: RW_NO_LATCH;
buf_block_t *block= buf_page_get_gen(page_id, zip_size, rw_latch, nullptr,
BUF_GET, mtr, &err,
!height && !index->is_clust());
ut_ad(!block == (err != DB_SUCCESS));
tree_blocks[n_blocks]= block;
if (!block)
{
if (err == DB_DECRYPTION_FAILED)
btr_decryption_failed(*index);
break;
}
const page_t *page= buf_block_get_frame(block);
if (first)
page_cur_set_before_first(block, &page_cur);
else
page_cur_set_after_last(block, &page_cur);
ut_ad(fil_page_index_page_check(page));
ut_ad(index->id == btr_page_get_index_id(page));
if (height == ULINT_UNDEFINED)
{
/* We are in the root node */
height= btr_page_get_level(page);
if (height);
else if (upper_rw_latch != root_leaf_rw_latch)
{
/* We should retry to get the page, because the root page
is latched with different level as a leaf page. */
ut_ad(n_blocks == 0);
ut_ad(root_leaf_rw_latch != RW_NO_LATCH);
upper_rw_latch= root_leaf_rw_latch;
mtr->rollback_to_savepoint(savepoint);
continue;
}
else
{
reached_leaf:
if (rw_latch == RW_NO_LATCH)
btr_cur_latch_leaves(block, latch_mode, this, mtr);
switch (latch_mode) {
case BTR_MODIFY_TREE:
case BTR_CONT_MODIFY_TREE:
case BTR_CONT_SEARCH_TREE:
break;
default:
if (UNIV_UNLIKELY(srv_read_only_mode))
break;
if (!latch_by_caller)
/* Release the tree s-latch */
mtr->release_s_latch_at_savepoint(savepoint -
sizeof(mtr_memo_slot_t),
&index->lock);
/* release upper blocks */
for (; n_releases < n_blocks; n_releases++)
mtr_release_block_at_savepoint(mtr,
#if 0
savepoint + n_releases,
#else
tree_savepoints[n_releases],
#endif
tree_blocks[n_releases]);
}
break;
}
}
else if (UNIV_UNLIKELY(height != btr_page_get_level(page)))
{
corrupted:
err= DB_CORRUPTION;
break;
}
if (!height)
goto reached_leaf;
height--;
if (first
? !page_cur_move_to_next(&page_cur)
: !page_cur_move_to_prev(&page_cur))
goto corrupted;
const rec_t *node_ptr= page_cur.rec;
offsets= rec_get_offsets(node_ptr, index, offsets, 0, ULINT_UNDEFINED,
&heap);
ut_ad(latch_mode != BTR_MODIFY_TREE || upper_rw_latch == RW_X_LATCH);
if (latch_mode != BTR_MODIFY_TREE);
else if (btr_cur_need_opposite_intention(page, lock_intention, node_ptr))
{
/* If the rec is the first or last in the page for pessimistic
delete intention, it might cause node_ptr insert for the upper
level. We should change the intention and retry. */
mtr->rollback_to_savepoint(savepoint);
lock_intention= BTR_INTENTION_BOTH;
page_id.set_page_no(index->page);
height= ULINT_UNDEFINED;
n_blocks= 0;
n_releases= 0;
continue;
}
else if (!btr_cur_will_modify_tree(index, page, lock_intention, node_ptr,
node_ptr_max_size, zip_size, mtr))
{
ut_ad(n_releases <= n_blocks);
/* release non-leaf pages (except the root) */
for (; n_releases < n_blocks; n_releases++)
if (n_releases)
mtr_release_block_at_savepoint(mtr, tree_savepoints[n_releases],
tree_blocks[n_releases]);
}
if (latch_mode == BTR_MODIFY_TREE && !height)
{
ut_ad(upper_rw_latch == RW_X_LATCH);
/* we should U-latch root page, if released already.
It contains seg_header. */
if (n_releases)
mtr_block_sx_latch_at_savepoint(mtr, tree_savepoints[0],
tree_blocks[0]);
/* x-latch the branch blocks not released yet. */
for (ulint i= n_releases; i <= n_blocks; i++)
mtr_block_x_latch_at_savepoint(mtr,
tree_savepoints[i], tree_blocks[i]);
}
/* Go to the child node */
page_id.set_page_no(btr_node_ptr_get_child_page_no(node_ptr, offsets));
n_blocks++;
}
if (UNIV_LIKELY_NULL(heap))
mem_heap_free(heap);
return err;
}
/*****************************************************************//**
Opens a cursor at either end of an index. */
dberr_t
@ -2415,7 +2650,7 @@ btr_cur_open_at_index_side(
bool from_left, /*!< in: true if open to the low end,
false if to the high end */
dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: latch mode */
btr_latch_mode latch_mode, /*!< in: latch mode */
btr_cur_t* cursor, /*!< in/out: cursor */
ulint level, /*!< in: level to search for
(0=leaf). */
@ -2440,7 +2675,7 @@ btr_cur_open_at_index_side(
ut_ad(level != ULINT_UNDEFINED);
const bool latch_by_caller = latch_mode & BTR_ALREADY_S_LATCHED;
latch_mode &= ulint(~BTR_ALREADY_S_LATCHED);
latch_mode = btr_latch_mode(latch_mode & ~BTR_ALREADY_S_LATCHED);
lock_intention = btr_cur_get_and_clear_intention(&latch_mode);
@ -2607,10 +2842,6 @@ btr_cur_open_at_index_side(
ut_ad(upper_rw_latch == RW_S_LATCH);
ut_ad(mtr->memo_contains_flagged(block,
MTR_MEMO_PAGE_S_FIX));
if (latch_by_caller) {
/* to exclude modifying tree operations
should sx-latch the index. */
ut_ad(mtr->memo_contains(index->lock,
MTR_MEMO_SX_LOCK));
/* because has sx-latch of index,
@ -2622,7 +2853,6 @@ btr_cur_open_at_index_side(
tree_blocks[n_releases]);
}
}
}
if (from_left) {
page_cur_set_before_first(block, page_cursor);
@ -2740,7 +2970,7 @@ if the index is unavailable */
bool
btr_cur_open_at_rnd_pos(
dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_latch_mode latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_cur_t* cursor, /*!< in/out: B-tree cursor */
mtr_t* mtr) /*!< in: mtr */
{
@ -2890,7 +3120,7 @@ btr_cur_open_at_rnd_pos(
mtr);
}
/* btr_cur_open_at_index_side() and
/* btr_cur_t::open_leaf() and
btr_cur_search_to_nth_level() release
tree s-latch here.*/
switch (latch_mode) {
@ -6055,8 +6285,8 @@ class btr_est_cur_t
}
ut_ad(page_rec_is_supremum(page_cur_get_rec(&m_page_cur)));
/* The range specified is wihout a right border, just 'x > 123' or 'x >=
123' and btr_cur_open_at_index_side() positioned the cursor on the
/* The range specified is without a right border, just 'x > 123'
or 'x >= 123' and search_on_page() positioned the cursor on the
supremum record on the rightmost page, which must not be counted. */
return false;
}

View File

@ -253,10 +253,11 @@ otherwise. */
struct optimistic_latch_leaves
{
btr_pcur_t *const cursor;
ulint *latch_mode;
btr_latch_mode *latch_mode;
mtr_t *const mtr;
optimistic_latch_leaves(btr_pcur_t *cursor, ulint *latch_mode, mtr_t *mtr)
optimistic_latch_leaves(btr_pcur_t *cursor, btr_latch_mode *latch_mode,
mtr_t *mtr)
: cursor(cursor), latch_mode(latch_mode), mtr(mtr) {}
bool operator() (buf_block_t *hint) const
@ -289,7 +290,7 @@ record with the same unique field values as in the stored record,
btr_pcur_t::NOT_SAME cursor position is not on user rec or points on
the record with not the samebuniq field values as in the stored */
btr_pcur_t::restore_status
btr_pcur_t::restore_position(ulint restore_latch_mode, mtr_t *mtr)
btr_pcur_t::restore_position(btr_latch_mode restore_latch_mode, mtr_t *mtr)
{
dict_index_t* index;
dtuple_t* tuple;
@ -309,10 +310,9 @@ btr_pcur_t::restore_position(ulint restore_latch_mode, mtr_t *mtr)
/* In these cases we do not try an optimistic restoration,
but always do a search */
if (btr_cur_open_at_index_side(
rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
index, restore_latch_mode,
&btr_cur, 0, mtr) != DB_SUCCESS) {
if (btr_cur.open_leaf(rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
index, restore_latch_mode, mtr)
!= DB_SUCCESS) {
return restore_status::CORRUPTED;
}
@ -330,6 +330,8 @@ btr_pcur_t::restore_position(ulint restore_latch_mode, mtr_t *mtr)
ut_a(old_n_fields);
switch (restore_latch_mode) {
default:
break;
case BTR_SEARCH_LEAF:
case BTR_MODIFY_LEAF:
case BTR_SEARCH_PREV:
@ -553,7 +555,7 @@ btr_pcur_move_backward_from_page(
ut_ad(btr_pcur_is_before_first_on_page(cursor));
ut_ad(!btr_pcur_is_before_first_in_tree(cursor));
const ulint latch_mode = cursor->latch_mode;
const auto latch_mode = cursor->latch_mode;
ut_ad(latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF);
btr_pcur_store_position(cursor, mtr);
@ -565,7 +567,8 @@ btr_pcur_move_backward_from_page(
static_assert(BTR_SEARCH_PREV == (4 | BTR_SEARCH_LEAF), "");
static_assert(BTR_MODIFY_PREV == (4 | BTR_MODIFY_LEAF), "");
if (UNIV_UNLIKELY(cursor->restore_position(4 | latch_mode, mtr)
if (UNIV_UNLIKELY(cursor->restore_position(
btr_latch_mode(4 | latch_mode), mtr)
== btr_pcur_t::CORRUPTED)) {
return true;
}

View File

@ -215,8 +215,9 @@ dict_startscan_system(
mtr_t* mtr, /*!< in: the mini-transaction */
dict_table_t* table) /*!< in: system table */
{
if (btr_pcur_open_at_index_side(true, table->indexes.start, BTR_SEARCH_LEAF,
pcur, true, 0, mtr) != DB_SUCCESS)
btr_pcur_init(pcur);
if (pcur->open_leaf(true, table->indexes.start, BTR_SEARCH_LEAF, mtr) !=
DB_SUCCESS)
return nullptr;
const rec_t *rec;
do

View File

@ -1560,6 +1560,25 @@ dict_stats_update_transient(
return err;
}
/** Open persistent cursor at the first page in a tree level.
@param index B-tree index
@param pcur persistent cursor
@param level level to search for (0=leaf)
@param mtr mini-transaction */
static dberr_t btr_pcur_open_level(dict_index_t *index, btr_pcur_t *pcur,
ulint level, mtr_t *mtr)
{
btr_pcur_init(pcur);
pcur->trx_if_known= nullptr;
pcur->latch_mode= BTR_SEARCH_TREE;
pcur->search_mode= PAGE_CUR_G;
pcur->pos_state= BTR_PCUR_IS_POSITIONED;
return btr_cur_open_at_index_side(true, index,
BTR_SEARCH_TREE_ALREADY_S_LATCHED,
btr_pcur_get_btr_cur(pcur), level, mtr);
}
/* @{ Pseudo code about the relation between the following functions
let N = N_SAMPLE_PAGES(index)
@ -1649,9 +1668,7 @@ dict_stats_analyze_index_level(
/* Position pcur on the leftmost record on the leftmost page
on the desired level. */
if (btr_pcur_open_at_index_side(
true, index, BTR_SEARCH_TREE_ALREADY_S_LATCHED,
&pcur, true, level, mtr) != DB_SUCCESS
if (btr_pcur_open_level(index, &pcur, level, mtr) != DB_SUCCESS
|| !btr_pcur_move_to_next_on_page(&pcur)) {
goto func_exit;
}
@ -2289,9 +2306,7 @@ dict_stats_analyze_index_for_n_prefix(
n_diff_data->n_diff_all_analyzed_pages = 0;
n_diff_data->n_external_pages_sum = 0;
if (btr_pcur_open_at_index_side(true, index,
BTR_SEARCH_TREE_ALREADY_S_LATCHED,
&pcur, true, n_diff_data->level, mtr)
if (btr_pcur_open_level(index, &pcur, n_diff_data->level, mtr)
!= DB_SUCCESS
|| !btr_pcur_move_to_next_on_page(&pcur)) {
return;

View File

@ -3551,12 +3551,11 @@ fts_get_max_doc_id(
ut_ad(innobase_strcasecmp(FTS_DOC_ID_COL_NAME, dfield->name) == 0);
#endif
mtr_start(&mtr);
mtr.start();
/* fetch the largest indexes value */
if (btr_pcur_open_at_index_side(false, index, BTR_SEARCH_LEAF, &pcur,
true, 0, &mtr) != DB_SUCCESS) {
} else if (!page_is_empty(btr_pcur_get_page(&pcur))) {
if (pcur.open_leaf(false, index, BTR_SEARCH_LEAF, &mtr) == DB_SUCCESS
&& !page_is_empty(btr_pcur_get_page(&pcur))) {
const rec_t* rec = NULL;
do {
@ -3575,7 +3574,7 @@ fts_get_max_doc_id(
}
func_exit:
mtr_commit(&mtr);
mtr.commit();
return(doc_id);
}

View File

@ -102,7 +102,6 @@ rtr_pcur_getnext_from_path(
node_visit_t next_rec;
rtr_info_t* rtr_info = btr_cur->rtr_info;
node_seq_t page_ssn;
ulint my_latch_mode;
ulint skip_parent = false;
bool new_split = false;
bool for_delete = false;
@ -115,7 +114,7 @@ rtr_pcur_getnext_from_path(
ut_ad(dtuple_get_n_fields_cmp(tuple));
my_latch_mode = BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode);
const auto my_latch_mode = BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode);
for_delete = latch_mode & BTR_RTREE_DELETE_MARK;
for_undo_ins = latch_mode & BTR_RTREE_UNDO_INS;
@ -351,17 +350,12 @@ rtr_pcur_getnext_from_path(
BTR_PCUR_IS_POSITIONED;
r_cursor->latch_mode = my_latch_mode;
btr_pcur_store_position(r_cursor, mtr);
#ifdef UNIV_DEBUG
ulint num_stored =
ut_d(ulint num_stored =)
rtr_store_parent_path(
block, btr_cur,
rw_latch, level, mtr);
ut_ad(num_stored > 0);
#else
rtr_store_parent_path(
block, btr_cur, rw_latch,
btr_latch_mode(rw_latch),
level, mtr);
#endif /* UNIV_DEBUG */
ut_ad(num_stored > 0);
}
}
} else {
@ -521,7 +515,7 @@ bool
rtr_pcur_open(
dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
btr_latch_mode latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
mtr_t* mtr) /*!< in: mtr */
{
@ -1352,7 +1346,7 @@ rtr_store_parent_path(
/*==================*/
const buf_block_t* block, /*!< in: block of the page */
btr_cur_t* btr_cur,/*!< in/out: persistent cursor */
ulint latch_mode,
btr_latch_mode latch_mode,
/*!< in: latch_mode */
ulint level, /*!< in: index level */
mtr_t* mtr) /*!< in: mtr */

View File

@ -2051,9 +2051,8 @@ static void drop_garbage_tables_after_restore()
ut_d(purge_sys.stop_FTS());
mtr.start();
if (btr_pcur_open_at_index_side(true, dict_sys.sys_tables->indexes.start,
BTR_SEARCH_LEAF, &pcur, true, 0, &mtr) !=
DB_SUCCESS)
if (pcur.open_leaf(true, dict_sys.sys_tables->indexes.start, BTR_SEARCH_LEAF,
&mtr) != DB_SUCCESS)
goto all_fail;
for (;;)
{
@ -15061,9 +15060,7 @@ inline int ha_innobase::defragment_table()
mtr_t mtr;
mtr.start();
if (dberr_t err= btr_pcur_open_at_index_side(true, index,
BTR_SEARCH_LEAF, &pcur,
true, 0, &mtr))
if (dberr_t err= pcur.open_leaf(true, index, BTR_SEARCH_LEAF, &mtr))
{
mtr.commit();
return convert_error_code_to_mysql(err, 0, m_user_thd);

View File

@ -2128,8 +2128,7 @@ static bool innobase_table_is_empty(const dict_table_t *table,
bool next_page= false;
mtr.start();
if (btr_pcur_open_at_index_side(true, clust_index, BTR_SEARCH_LEAF,
&pcur, true, 0, &mtr) != DB_SUCCESS)
if (pcur.open_leaf(true, clust_index, BTR_SEARCH_LEAF, &mtr) != DB_SUCCESS)
{
non_empty:
mtr.commit();
@ -6023,8 +6022,7 @@ static bool innobase_instant_try(
mtr.start();
index->set_modified(mtr);
btr_pcur_t pcur;
dberr_t err = btr_pcur_open_at_index_side(true, index, BTR_MODIFY_TREE,
&pcur, true, 0, &mtr);
dberr_t err= pcur.open_leaf(true, index, BTR_MODIFY_TREE, &mtr);
if (err != DB_SUCCESS) {
func_exit:
mtr.commit();

View File

@ -466,9 +466,8 @@ ibuf_init_at_db_start(void)
ib::info() << "Dumping the change buffer";
ibuf_mtr_start(&mtr);
btr_pcur_t pcur;
if (DB_SUCCESS == btr_pcur_open_at_index_side(
true, ibuf.index, BTR_SEARCH_LEAF, &pcur,
true, 0, &mtr)) {
if (DB_SUCCESS
== pcur.open_leaf(true, ibuf.index, BTR_SEARCH_LEAF, &mtr)) {
while (btr_pcur_move_to_next_user_rec(&pcur, &mtr)) {
rec_print_old(stderr, btr_pcur_get_rec(&pcur));
}
@ -2911,8 +2910,8 @@ ibuf_update_max_tablespace_id(void)
ibuf_mtr_start(&mtr);
if (btr_pcur_open_at_index_side(false, ibuf.index, BTR_SEARCH_LEAF,
&pcur, true, 0, &mtr) != DB_SUCCESS) {
if (pcur.open_leaf(false, ibuf.index, BTR_SEARCH_LEAF, &mtr)
!= DB_SUCCESS) {
func_exit:
ibuf_mtr_commit(&mtr);
return;
@ -3105,7 +3104,7 @@ or clustered
static TRANSACTIONAL_TARGET MY_ATTRIBUTE((warn_unused_result))
dberr_t
ibuf_insert_low(
ulint mode,
btr_latch_mode mode,
ibuf_op_t op,
ibool no_counter,
const dtuple_t* entry,
@ -3919,7 +3918,7 @@ ibuf_restore_pos(
const page_id_t page_id,/*!< in: page identifier */
const dtuple_t* search_tuple,
/*!< in: search tuple for entries of page_no */
ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_PURGE_TREE */
btr_latch_mode mode, /*!< in: BTR_MODIFY_LEAF or BTR_PURGE_TREE */
btr_pcur_t* pcur, /*!< in/out: persistent cursor whose
position is to be restored */
mtr_t* mtr) /*!< in/out: mini-transaction */

View File

@ -55,103 +55,8 @@ not acceptable for it to lead to mysterious memory corruption, but it
is acceptable for the program to die with a clear assert failure. */
#define BTR_MAX_LEVELS 100
/** Latching modes for btr_cur_search_to_nth_level(). */
enum btr_latch_mode {
/** Search a record on a leaf page and S-latch it. */
BTR_SEARCH_LEAF = RW_S_LATCH,
/** (Prepare to) modify a record on a leaf page and X-latch it. */
BTR_MODIFY_LEAF = RW_X_LATCH,
/** Obtain no latches. */
BTR_NO_LATCHES = RW_NO_LATCH,
/** Search the previous record. */
BTR_SEARCH_PREV = 4 | BTR_SEARCH_LEAF,
/** Modify the previous record. */
BTR_MODIFY_PREV = 4 | BTR_MODIFY_LEAF,
/** Start searching the entire B-tree. */
BTR_SEARCH_TREE = 8 | BTR_SEARCH_LEAF,
/** Start modifying1 the entire B-tree. */
BTR_MODIFY_TREE = 8 | BTR_MODIFY_LEAF,
/** Continue searching the entire B-tree. */
BTR_CONT_SEARCH_TREE = 4 | BTR_SEARCH_TREE,
/** Continue modifying the entire B-tree. */
BTR_CONT_MODIFY_TREE = 4 | BTR_MODIFY_TREE,
/* BTR_INSERT, BTR_DELETE and BTR_DELETE_MARK are mutually
exclusive. */
/** The search tuple will be inserted to the secondary index
at the searched position. When the leaf page is not in the
buffer pool, try to use the change buffer. */
BTR_INSERT = 64,
/** Try to delete mark a secondary index leaf page record at
the searched position using the change buffer when the page is
not in the buffer pool. */
BTR_DELETE_MARK = 128,
/** Try to purge the record using the change buffer when the
secondary index leaf page is not in the buffer pool. */
BTR_DELETE = BTR_INSERT | BTR_DELETE_MARK,
/** The caller is already holding dict_index_t::lock S-latch. */
BTR_ALREADY_S_LATCHED = 256,
/** Search and S-latch a leaf page, assuming that the
dict_index_t::lock S-latch is being held. */
BTR_SEARCH_LEAF_ALREADY_S_LATCHED = BTR_SEARCH_LEAF
| BTR_ALREADY_S_LATCHED,
/** Search the entire index tree, assuming that the
dict_index_t::lock S-latch is being held. */
BTR_SEARCH_TREE_ALREADY_S_LATCHED = BTR_SEARCH_TREE
| BTR_ALREADY_S_LATCHED,
/** Search and X-latch a leaf page, assuming that the
dict_index_t::lock is being held in non-exclusive mode. */
BTR_MODIFY_LEAF_ALREADY_LATCHED = BTR_MODIFY_LEAF
| BTR_ALREADY_S_LATCHED,
/** Attempt to delete-mark a secondary index record. */
BTR_DELETE_MARK_LEAF = BTR_MODIFY_LEAF | BTR_DELETE_MARK,
/** Attempt to delete-mark a secondary index record
while holding the dict_index_t::lock S-latch. */
BTR_DELETE_MARK_LEAF_ALREADY_S_LATCHED = BTR_DELETE_MARK_LEAF
| BTR_ALREADY_S_LATCHED,
/** Attempt to purge a secondary index record. */
BTR_PURGE_LEAF = BTR_MODIFY_LEAF | BTR_DELETE,
/** Attempt to purge a secondary index record
while holding the dict_index_t::lock S-latch. */
BTR_PURGE_LEAF_ALREADY_S_LATCHED = BTR_PURGE_LEAF
| BTR_ALREADY_S_LATCHED,
/** In the case of BTR_MODIFY_TREE, the caller specifies
the intention to delete record only. It is used to optimize
block->lock range.*/
BTR_LATCH_FOR_DELETE = 512,
/** In the case of BTR_MODIFY_TREE, the caller specifies
the intention to delete record only. It is used to optimize
block->lock range.*/
BTR_LATCH_FOR_INSERT = 1024,
/** Attempt to delete a record in the tree. */
BTR_PURGE_TREE = BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE,
/** Attempt to insert a record into the tree. */
BTR_INSERT_TREE = BTR_MODIFY_TREE | BTR_LATCH_FOR_INSERT
};
/** This flag ORed to BTR_INSERT says that we can ignore possible
UNIQUE definition on secondary indexes when we decide if we can use
the insert buffer to speed up inserts */
#define BTR_IGNORE_SEC_UNIQUE 2048U
/** This flag is for undo insert of rtree. For rtree, we need this flag
to find proper rec to undo insert.*/
#define BTR_RTREE_UNDO_INS 4096U
/** Try to delete mark the record at the searched position when the
record is in spatial index */
#define BTR_RTREE_DELETE_MARK 16384U
#define BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode) \
((latch_mode) & ulint(~(BTR_INSERT \
btr_latch_mode((latch_mode) & ~(BTR_INSERT \
| BTR_DELETE_MARK \
| BTR_RTREE_UNDO_INS \
| BTR_RTREE_DELETE_MARK \
@ -159,11 +64,11 @@ record is in spatial index */
| BTR_IGNORE_SEC_UNIQUE \
| BTR_ALREADY_S_LATCHED \
| BTR_LATCH_FOR_INSERT \
| BTR_LATCH_FOR_DELETE)))
| BTR_LATCH_FOR_DELETE))
#define BTR_LATCH_MODE_WITHOUT_INTENTION(latch_mode) \
((latch_mode) & ulint(~(BTR_LATCH_FOR_INSERT \
| BTR_LATCH_FOR_DELETE)))
btr_latch_mode((latch_mode) \
& ~(BTR_LATCH_FOR_INSERT | BTR_LATCH_FOR_DELETE))
/**************************************************************//**
Checks and adjusts the root node of a tree during IMPORT TABLESPACE.

View File

@ -137,7 +137,7 @@ bool
btr_cur_optimistic_latch_leaves(
buf_block_t* block,
ib_uint64_t modify_clock,
ulint* latch_mode,
btr_latch_mode* latch_mode,
btr_cur_t* cursor,
mtr_t* mtr);
@ -168,7 +168,8 @@ If mode is PAGE_CUR_GE, then up_match will a have a sensible value.
@return DB_SUCCESS on success or error code otherwise */
dberr_t btr_cur_search_to_nth_level(dict_index_t *index, ulint level,
const dtuple_t *tuple,
page_cur_mode_t mode, ulint latch_mode,
page_cur_mode_t mode,
btr_latch_mode latch_mode,
btr_cur_t *cursor, mtr_t *mtr,
ib_uint64_t autoinc= 0);
@ -180,7 +181,7 @@ btr_cur_open_at_index_side(
bool from_left, /*!< in: true if open to the low end,
false if to the high end */
dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: latch mode */
btr_latch_mode latch_mode, /*!< in: latch mode */
btr_cur_t* cursor, /*!< in/out: cursor */
ulint level, /*!< in: level to search for
(0=leaf) */
@ -194,7 +195,7 @@ if the index is unavailable */
bool
btr_cur_open_at_rnd_pos(
dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_latch_mode latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
btr_cur_t* cursor, /*!< in/out: B-tree cursor */
mtr_t* mtr) /*!< in: mtr */
MY_ATTRIBUTE((nonnull,warn_unused_result));
@ -689,7 +690,7 @@ btr_rec_copy_externally_stored_field(
void
btr_cur_latch_leaves(
buf_block_t* block,
ulint latch_mode,
btr_latch_mode latch_mode,
btr_cur_t* cursor,
mtr_t* mtr,
btr_latch_leaves_t* latch_leaves = nullptr);
@ -839,6 +840,15 @@ struct btr_cur_t {
path_arr = NULL;
rtr_info = NULL;
}
/** Open the cursor on the first or last record.
@param first true=first record, false=last record
@param index B-tree
@param latch_mode which latches to acquire
@param mtr mini-transaction
@return error code */
dberr_t open_leaf(bool first, dict_index_t *index, btr_latch_mode latch_mode,
mtr_t *mtr);
};
/** Modify the delete-mark flag of a record.

View File

@ -105,7 +105,7 @@ btr_pcur_open_low(
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page from the
record! */
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
btr_latch_mode latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
ib_uint64_t autoinc,/*!< in: PAGE_ROOT_AUTO_INC to be written
(0 if none) */
@ -127,25 +127,10 @@ cursor.
@return DB_SUCCESS on success or error code otherwise. */
inline
dberr_t btr_pcur_open_with_no_init(dict_index_t *index, const dtuple_t *tuple,
page_cur_mode_t mode, ulint latch_mode,
page_cur_mode_t mode,
btr_latch_mode latch_mode,
btr_pcur_t *cursor, mtr_t *mtr);
/*****************************************************************//**
Opens a persistent cursor at either end of an index. */
UNIV_INLINE
dberr_t
btr_pcur_open_at_index_side(
/*========================*/
bool from_left, /*!< in: true if open to the low end,
false if to the high end */
dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: latch mode */
btr_pcur_t* pcur, /*!< in/out: cursor */
bool init_pcur, /*!< in: whether to initialize pcur */
ulint level, /*!< in: level to search for
(0=leaf) */
mtr_t* mtr) /*!< in/out: mini-transaction */
MY_ATTRIBUTE((nonnull,warn_unused_result));
/**************************************************************//**
Gets the up_match value for a pcur after a search.
@return number of matched fields at the cursor or to the right if
@ -356,7 +341,8 @@ enum pcur_pos_t {
/* The persistent B-tree cursor structure. This is used mainly for SQL
selects, updates, and deletes. */
struct btr_pcur_t{
struct btr_pcur_t
{
/** Return value of restore_position() */
enum restore_status {
/** cursor position on user rec and points on the record with
@ -373,56 +359,41 @@ struct btr_pcur_t{
};
/** a B-tree cursor */
btr_cur_t btr_cur;
/** see TODO note below!
/** @see BTR_PCUR_WAS_POSITIONED
BTR_SEARCH_LEAF, BTR_MODIFY_LEAF, BTR_MODIFY_TREE or BTR_NO_LATCHES,
depending on the latching state of the page and tree where the cursor
is positioned; BTR_NO_LATCHES means that the cursor is not currently
positioned:
we say then that the cursor is detached; it can be restored to
attached if the old position was stored in old_rec */
ulint latch_mode;
btr_latch_mode latch_mode= BTR_NO_LATCHES;
/** if cursor position is stored, contains an initial segment of the
latest record cursor was positioned either on, before or after */
rec_t* old_rec;
rec_t *old_rec= nullptr;
/** btr_cur.index->n_core_fields when old_rec was copied */
uint16 old_n_core_fields;
uint16 old_n_core_fields= 0;
/** number of fields in old_rec */
uint16 old_n_fields;
uint16 old_n_fields= 0;
/** BTR_PCUR_ON, BTR_PCUR_BEFORE, or BTR_PCUR_AFTER, depending on
whether cursor was on, before, or after the old_rec record */
enum btr_pcur_pos_t rel_pos;
btr_pcur_pos_t rel_pos= btr_pcur_pos_t(0);
/** buffer block when the position was stored */
buf::Block_hint block_when_stored;
/** the modify clock value of the buffer block when the cursor position
was stored */
ib_uint64_t modify_clock;
ib_uint64_t modify_clock= 0;
/** btr_pcur_store_position() and btr_pcur_restore_position() state. */
enum pcur_pos_t pos_state;
/** PAGE_CUR_G, ... */
page_cur_mode_t search_mode;
enum pcur_pos_t pos_state= BTR_PCUR_NOT_POSITIONED;
page_cur_mode_t search_mode= PAGE_CUR_UNSUPP;
/** the transaction, if we know it; otherwise this field is not defined;
can ONLY BE USED in error prints in fatal assertion failures! */
trx_t* trx_if_known;
/*-----------------------------*/
/* NOTE that the following fields may possess dynamically allocated
memory which should be freed if not needed anymore! */
trx_t *trx_if_known= nullptr;
/** a dynamically allocated buffer for old_rec */
byte *old_rec_buf= nullptr;
/** old_rec_buf size if old_rec_buf is not nullptr */
ulint buf_size= 0;
/** NULL, or a dynamically allocated buffer for old_rec */
byte* old_rec_buf;
/** old_rec_buf size if old_rec_buf is not NULL */
ulint buf_size;
btr_pcur_t() :
btr_cur(), latch_mode(RW_NO_LATCH),
old_rec(NULL),
old_n_fields(0), rel_pos(btr_pcur_pos_t(0)),
block_when_stored(),
modify_clock(0), pos_state(BTR_PCUR_NOT_POSITIONED),
search_mode(PAGE_CUR_UNSUPP), trx_if_known(NULL),
old_rec_buf(NULL), buf_size(0)
{
btr_cur.init();
}
btr_pcur_t() : btr_cur() { btr_cur.init(); }
/** Return the index of this persistent cursor */
dict_index_t *index() const { return(btr_cur.index); }
@ -449,7 +420,26 @@ struct btr_pcur_t{
@retval NOT_SAME cursor position is not on user rec or points on
the record with not the same uniq field values as in the stored
@retval CORRUPTED if the index is corrupted */
restore_status restore_position(ulint latch_mode, mtr_t *mtr);
restore_status restore_position(btr_latch_mode latch_mode, mtr_t *mtr);
/** Open the cursor on the first or last record.
@param first true=first record, false=last record
@param index B-tree
@param latch_mode which latches to acquire
@param mtr mini-transaction
@return error code */
dberr_t open_leaf(bool first, dict_index_t *index, btr_latch_mode latch_mode,
mtr_t *mtr)
{
this->latch_mode= BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode);
search_mode= first ? PAGE_CUR_G : PAGE_CUR_L;
pos_state= BTR_PCUR_IS_POSITIONED;
old_rec= nullptr;
return btr_cur.open_leaf(first, index,
BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode), mtr);
}
};
inline buf_block_t *btr_pcur_get_block(btr_pcur_t *cursor)
@ -480,7 +470,7 @@ btr_pcur_open_on_user_rec(
dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */
page_cur_mode_t mode, /*!< in: PAGE_CUR_L, ... */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
btr_latch_mode latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent
cursor */

View File

@ -324,7 +324,7 @@ btr_pcur_open_low(
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page from the
record! */
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
btr_latch_mode latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
ib_uint64_t autoinc,/*!< in: PAGE_ROOT_AUTO_INC to be written
(0 if none) */
@ -355,7 +355,8 @@ cursor.
@return DB_SUCCESS on success or error code otherwise. */
inline
dberr_t btr_pcur_open_with_no_init(dict_index_t *index, const dtuple_t *tuple,
page_cur_mode_t mode, ulint latch_mode,
page_cur_mode_t mode,
btr_latch_mode latch_mode,
btr_pcur_t *cursor, mtr_t *mtr)
{
cursor->latch_mode= BTR_LATCH_MODE_WITHOUT_INTENTION(latch_mode);
@ -368,44 +369,6 @@ dberr_t btr_pcur_open_with_no_init(dict_index_t *index, const dtuple_t *tuple,
btr_pcur_get_btr_cur(cursor), mtr);
}
/*****************************************************************//**
Opens a persistent cursor at either end of an index. */
UNIV_INLINE
dberr_t
btr_pcur_open_at_index_side(
/*========================*/
bool from_left, /*!< in: true if open to the low end,
false if to the high end */
dict_index_t* index, /*!< in: index */
ulint latch_mode, /*!< in: latch mode */
btr_pcur_t* pcur, /*!< in/out: cursor */
bool init_pcur, /*!< in: whether to initialize pcur */
ulint level, /*!< in: level to search for
(0=leaf) */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
dberr_t err = DB_SUCCESS;
pcur->latch_mode = BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode);
pcur->search_mode = from_left ? PAGE_CUR_G : PAGE_CUR_L;
if (init_pcur) {
btr_pcur_init(pcur);
}
err = btr_cur_open_at_index_side(
from_left, index, latch_mode,
btr_pcur_get_btr_cur(pcur), level, mtr);
pcur->pos_state = BTR_PCUR_IS_POSITIONED;
pcur->old_rec = nullptr;
pcur->trx_if_known = NULL;
return (err);
}
/**************************************************************//**
Frees the possible memory heap of a persistent cursor and sets the latch
mode of the persistent cursor to BTR_NO_LATCHES.

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, 2019, MariaDB Corporation.
Copyright (c) 2018, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -24,8 +24,7 @@ The index tree general types
Created 2/17/1996 Heikki Tuuri
*************************************************************************/
#ifndef btr0types_h
#define btr0types_h
#pragma once
#include "page0types.h"
#include "rem0types.h"
@ -56,4 +55,93 @@ in the index record. */
#define BTR_EXTERN_LOCAL_STORED_MAX_SIZE \
(BTR_EXTERN_FIELD_REF_SIZE * 2)
#endif
/** Latching modes for btr_cur_search_to_nth_level(). */
enum btr_latch_mode {
/** Search a record on a leaf page and S-latch it. */
BTR_SEARCH_LEAF = RW_S_LATCH,
/** (Prepare to) modify a record on a leaf page and X-latch it. */
BTR_MODIFY_LEAF = RW_X_LATCH,
/** Obtain no latches. */
BTR_NO_LATCHES = RW_NO_LATCH,
/** Search the previous record. */
BTR_SEARCH_PREV = 4 | BTR_SEARCH_LEAF,
/** Modify the previous record. */
BTR_MODIFY_PREV = 4 | BTR_MODIFY_LEAF,
/** Start searching the entire B-tree. */
BTR_SEARCH_TREE = 8 | BTR_SEARCH_LEAF,
/** Start modifying1 the entire B-tree. */
BTR_MODIFY_TREE = 8 | BTR_MODIFY_LEAF,
/** Continue searching the entire B-tree. */
BTR_CONT_SEARCH_TREE = 4 | BTR_SEARCH_TREE,
/** Continue modifying the entire B-tree. */
BTR_CONT_MODIFY_TREE = 4 | BTR_MODIFY_TREE,
/* BTR_INSERT, BTR_DELETE and BTR_DELETE_MARK are mutually
exclusive. */
/** The search tuple will be inserted to the secondary index
at the searched position. When the leaf page is not in the
buffer pool, try to use the change buffer. */
BTR_INSERT = 64,
/** Try to delete mark a secondary index leaf page record at
the searched position using the change buffer when the page is
not in the buffer pool. */
BTR_DELETE_MARK = 128,
/** Try to purge the record using the change buffer when the
secondary index leaf page is not in the buffer pool. */
BTR_DELETE = BTR_INSERT | BTR_DELETE_MARK,
/** The caller is already holding dict_index_t::lock S-latch. */
BTR_ALREADY_S_LATCHED = 256,
/** Search and S-latch a leaf page, assuming that the
dict_index_t::lock S-latch is being held. */
BTR_SEARCH_LEAF_ALREADY_S_LATCHED = BTR_SEARCH_LEAF
| BTR_ALREADY_S_LATCHED,
/** Search the entire index tree, assuming that the
dict_index_t::lock S-latch is being held. */
BTR_SEARCH_TREE_ALREADY_S_LATCHED = BTR_SEARCH_TREE
| BTR_ALREADY_S_LATCHED,
/** Search and X-latch a leaf page, assuming that the
dict_index_t::lock is being held in non-exclusive mode. */
BTR_MODIFY_LEAF_ALREADY_LATCHED = BTR_MODIFY_LEAF
| BTR_ALREADY_S_LATCHED,
/** Attempt to delete-mark a secondary index record. */
BTR_DELETE_MARK_LEAF = BTR_MODIFY_LEAF | BTR_DELETE_MARK,
/** Attempt to delete-mark a secondary index record
while holding the dict_index_t::lock S-latch. */
BTR_DELETE_MARK_LEAF_ALREADY_S_LATCHED = BTR_DELETE_MARK_LEAF
| BTR_ALREADY_S_LATCHED,
/** Attempt to purge a secondary index record. */
BTR_PURGE_LEAF = BTR_MODIFY_LEAF | BTR_DELETE,
/** Attempt to purge a secondary index record
while holding the dict_index_t::lock S-latch. */
BTR_PURGE_LEAF_ALREADY_S_LATCHED = BTR_PURGE_LEAF
| BTR_ALREADY_S_LATCHED,
/** In the case of BTR_MODIFY_TREE, the caller specifies
the intention to delete record only. It is used to optimize
block->lock range.*/
BTR_LATCH_FOR_DELETE = 512,
/** In the case of BTR_MODIFY_TREE, the caller specifies
the intention to delete record only. It is used to optimize
block->lock range.*/
BTR_LATCH_FOR_INSERT = 1024,
/** Attempt to delete a record in the tree. */
BTR_PURGE_TREE = BTR_MODIFY_TREE | BTR_LATCH_FOR_DELETE,
/** Attempt to insert a record into the tree. */
BTR_INSERT_TREE = BTR_MODIFY_TREE | BTR_LATCH_FOR_INSERT,
/** This flag ORed to BTR_INSERT says that we can ignore possible
UNIQUE definition on secondary indexes when we decide if we can use
the insert buffer to speed up inserts */
BTR_IGNORE_SEC_UNIQUE = 2048,
/** Rollback in spatial index */
BTR_RTREE_UNDO_INS = 4096,
/** Try to delete mark a spatial index record */
BTR_RTREE_DELETE_MARK = 8192
};

View File

@ -298,7 +298,7 @@ rtr_store_parent_path(
/*==================*/
const buf_block_t* block, /*!< in: block of the page */
btr_cur_t* btr_cur,/*!< in/out: persistent cursor */
ulint latch_mode,
btr_latch_mode latch_mode,
/*!< in: latch_mode */
ulint level, /*!< in: index level */
mtr_t* mtr); /*!< in: mtr */
@ -310,7 +310,7 @@ bool
rtr_pcur_open(
dict_index_t* index, /*!< in: index */
const dtuple_t* tuple, /*!< in: tuple on which search done */
ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
btr_latch_mode latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
mtr_t* mtr) /*!< in: mtr */
MY_ATTRIBUTE((warn_unused_result));

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2021, MariaDB Corporation.
Copyright (c) 2017, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -78,7 +78,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 */
@ -100,7 +100,7 @@ dberr_t
row_ins_sec_index_entry_low(
/*========================*/
ulint flags, /*!< in: undo logging and locking flags */
ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_INSERT_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 */

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2020, MariaDB Corporation.
Copyright (c) 2016, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -303,13 +303,13 @@ row_build_row_ref_fast(
/***************************************************************//**
Searches the clustered index record for a row, if we have the row
reference.
@return TRUE if found */
ibool
@return true if found */
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 */
@ -321,7 +321,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 */
@ -365,7 +365,7 @@ 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 */

View File

@ -611,7 +611,7 @@ rec_init_offsets(
ulint i = 0;
rec_offs offs;
/* This assertion was relaxed for the btr_cur_open_at_index_side()
/* This assertion was relaxed for the btr_cur_t::open_leaf()
call in btr_cur_instant_init_low(). We cannot invoke
index->is_instant(), because the same assertion would fail there
until btr_cur_instant_init_low() has invoked
@ -839,7 +839,7 @@ rec_get_offsets_func(
bool alter_metadata = false;
ut_ad(index->n_core_fields >= n_core);
/* This assertion was relaxed for the btr_cur_open_at_index_side()
/* This assertion was relaxed for the btr_cur_t::open_leaf()
call in btr_cur_instant_init_low(). We cannot invoke
index->is_instant(), because the same assertion would fail there
until btr_cur_instant_init_low() has invoked

View File

@ -1525,8 +1525,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));
@ -2300,8 +2301,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) {

View File

@ -2522,7 +2522,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 */
@ -2749,8 +2749,8 @@ row_ins_clust_index_entry_low(
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,
@ -2832,7 +2832,7 @@ dberr_t
row_ins_sec_index_entry_low(
/*========================*/
ulint flags, /*!< in: undo logging and locking flags */
ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_INSERT_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 */
@ -2847,7 +2847,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;
@ -2872,9 +2872,6 @@ 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
@ -2916,8 +2913,12 @@ 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(
@ -2998,11 +2999,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)),//???
btr_latch_mode(search_mode
& ~(BTR_INSERT
| BTR_IGNORE_SEC_UNIQUE)),
&cursor, &mtr);
if (err != DB_SUCCESS) {
goto func_exit;

View File

@ -1829,8 +1829,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;

View File

@ -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;

View File

@ -1183,32 +1183,27 @@ 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);
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
btr_pcur_init(pcur);
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
@ -1222,25 +1217,12 @@ row_search_on_row_ref(
ut_a(ref->n_fields == index->n_uniq);
if (btr_pcur_open(index, ref, PAGE_CUR_LE, mode, pcur, 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 +1232,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 */
@ -1285,7 +1267,7 @@ 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 */

View File

@ -1436,9 +1436,8 @@ row_sel_open_pcur(
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;
@ -3643,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);
@ -4837,9 +4837,8 @@ row_search_mvcc(
}
}
} 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) {
@ -6213,9 +6212,7 @@ 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);
dberr_t err= prebuilt->pcur->open_leaf(true, index, BTR_SEARCH_LEAF, &mtr);
if (UNIV_UNLIKELY(err != DB_SUCCESS))
{
func_exit:
@ -6888,8 +6885,7 @@ row_search_get_max_rec(
btr_pcur_t pcur;
const rec_t* rec;
/* Open at the high/right end (false), and init cursor */
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) {
return nullptr;
}

View File

@ -253,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 */
@ -268,19 +268,20 @@ row_undo_ins_remove_sec_low(
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_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)) {

View File

@ -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
@ -482,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;
@ -495,12 +495,21 @@ row_undo_mod_del_mark_or_remove_sec_low(
row_mtr_start(&mtr, index, !modify_leaf);
if (!index->is_committed()) {
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_PURGE_TREE);
@ -513,16 +522,6 @@ 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);
@ -651,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 */
@ -667,7 +666,7 @@ 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;
ut_ad(trx->id != 0);
@ -678,7 +677,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:

View File

@ -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,9 +1889,10 @@ 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;
}
@ -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;