mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
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:
parent
6b2d6a81d4
commit
89ec4b53ac
28 changed files with 627 additions and 452 deletions
|
@ -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 */
|
||||
{
|
||||
|
|
|
@ -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 @@ unreadable:
|
|||
/* 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 @@ func_exit:
|
|||
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,20 +2842,15 @@ 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,
|
||||
can release upper blocks. */
|
||||
for (; n_releases < n_blocks; n_releases++) {
|
||||
mtr_release_block_at_savepoint(
|
||||
mtr,
|
||||
tree_savepoints[n_releases],
|
||||
tree_blocks[n_releases]);
|
||||
}
|
||||
ut_ad(mtr->memo_contains(index->lock,
|
||||
MTR_MEMO_SX_LOCK));
|
||||
/* because has sx-latch of index,
|
||||
can release upper blocks. */
|
||||
for (; n_releases < n_blocks; n_releases++) {
|
||||
mtr_release_block_at_savepoint(
|
||||
mtr,
|
||||
tree_savepoints[n_releases],
|
||||
tree_blocks[n_releases]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 @@ public:
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -253,11 +253,12 @@ 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)
|
||||
:cursor(cursor), latch_mode(latch_mode), mtr(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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1560,6 +1560,25 @@ empty_table:
|
|||
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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 =
|
||||
rtr_store_parent_path(
|
||||
block, btr_cur,
|
||||
rw_latch, level, mtr);
|
||||
ut_ad(num_stored > 0);
|
||||
#else
|
||||
ut_d(ulint num_stored =)
|
||||
rtr_store_parent_path(
|
||||
block, btr_cur, rw_latch,
|
||||
block, btr_cur,
|
||||
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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 @@ add_all_virtual:
|
|||
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();
|
||||
|
|
|
@ -466,9 +466,8 @@ err_exit:
|
|||
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 */
|
||||
|
|
|
@ -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)))
|
||||
#define BTR_LATCH_MODE_WITHOUT_INTENTION(latch_mode) \
|
||||
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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,100 +341,105 @@ enum pcur_pos_t {
|
|||
/* The persistent B-tree cursor structure. This is used mainly for SQL
|
||||
selects, updates, and deletes. */
|
||||
|
||||
struct btr_pcur_t{
|
||||
/** Return value of restore_position() */
|
||||
enum restore_status {
|
||||
/** cursor position on user rec and points on the record with
|
||||
the same field values as in the stored record */
|
||||
SAME_ALL,
|
||||
/** cursor position is on user rec and points on the record with
|
||||
the same unique field values as in the stored record */
|
||||
SAME_UNIQ,
|
||||
/** cursor position is not on user rec or points on the record
|
||||
with not the same uniq field values as in the stored record */
|
||||
NOT_SAME,
|
||||
/** the index tree is corrupted */
|
||||
CORRUPTED
|
||||
};
|
||||
/** a B-tree cursor */
|
||||
btr_cur_t btr_cur;
|
||||
/** see TODO note below!
|
||||
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;
|
||||
/** 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;
|
||||
/** btr_cur.index->n_core_fields when old_rec was copied */
|
||||
uint16 old_n_core_fields;
|
||||
/** number of fields in old_rec */
|
||||
uint16 old_n_fields;
|
||||
/** 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;
|
||||
/** 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;
|
||||
/** 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;
|
||||
/** 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! */
|
||||
struct btr_pcur_t
|
||||
{
|
||||
/** Return value of restore_position() */
|
||||
enum restore_status {
|
||||
/** cursor position on user rec and points on the record with
|
||||
the same field values as in the stored record */
|
||||
SAME_ALL,
|
||||
/** cursor position is on user rec and points on the record with
|
||||
the same unique field values as in the stored record */
|
||||
SAME_UNIQ,
|
||||
/** cursor position is not on user rec or points on the record
|
||||
with not the same uniq field values as in the stored record */
|
||||
NOT_SAME,
|
||||
/** the index tree is corrupted */
|
||||
CORRUPTED
|
||||
};
|
||||
/** a B-tree cursor */
|
||||
btr_cur_t btr_cur;
|
||||
/** @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 */
|
||||
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= nullptr;
|
||||
/** btr_cur.index->n_core_fields when old_rec was copied */
|
||||
uint16 old_n_core_fields= 0;
|
||||
/** number of fields in old_rec */
|
||||
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 */
|
||||
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= 0;
|
||||
/** btr_pcur_store_position() and btr_pcur_restore_position() state. */
|
||||
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= 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() { btr_cur.init(); }
|
||||
|
||||
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();
|
||||
}
|
||||
/** Return the index of this persistent cursor */
|
||||
dict_index_t *index() const { return(btr_cur.index); }
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result))
|
||||
/** Restores the stored position of a persistent cursor bufferfixing
|
||||
the page and obtaining the specified latches. If the cursor position
|
||||
was saved when the
|
||||
(1) cursor was positioned on a user record: this function restores the
|
||||
position to the last record LESS OR EQUAL to the stored record;
|
||||
(2) cursor was positioned on a page infimum record: restores the
|
||||
position to the last record LESS than the user record which was the
|
||||
successor of the page infimum;
|
||||
(3) cursor was positioned on the page supremum: restores to the first
|
||||
record GREATER than the user record which was the predecessor of the
|
||||
supremum.
|
||||
(4) cursor was positioned before the first or after the last in an
|
||||
empty tree: restores to before first or after the last in the tree.
|
||||
@param restore_latch_mode BTR_SEARCH_LEAF, ...
|
||||
@param mtr mtr
|
||||
@retval SAME_ALL cursor position on user rec and points on
|
||||
the record with the same field values as in the stored record,
|
||||
@retval SAME_UNIQ cursor position is on user rec and points on the
|
||||
record with the same unique field values as in the stored record,
|
||||
@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(btr_latch_mode latch_mode, mtr_t *mtr);
|
||||
|
||||
/** Return the index of this persistent cursor */
|
||||
dict_index_t* index() const { return(btr_cur.index); }
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result))
|
||||
/** Restores the stored position of a persistent cursor bufferfixing
|
||||
the page and obtaining the specified latches. If the cursor position
|
||||
was saved when the
|
||||
(1) cursor was positioned on a user record: this function restores the
|
||||
position to the last record LESS OR EQUAL to the stored record;
|
||||
(2) cursor was positioned on a page infimum record: restores the
|
||||
position to the last record LESS than the user record which was the
|
||||
successor of the page infimum;
|
||||
(3) cursor was positioned on the page supremum: restores to the first
|
||||
record GREATER than the user record which was the predecessor of the
|
||||
supremum.
|
||||
(4) cursor was positioned before the first or after the last in an
|
||||
empty tree: restores to before first or after the last in the tree.
|
||||
@param restore_latch_mode BTR_SEARCH_LEAF, ...
|
||||
@param mtr mtr
|
||||
@retval SAME_ALL cursor position on user rec and points on
|
||||
the record with the same field values as in the stored record,
|
||||
@retval SAME_UNIQ cursor position is on user rec and points on the
|
||||
record with the same unique field values as in the stored record,
|
||||
@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);
|
||||
/** 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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 @@ 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,
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 @@ 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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue