summaryrefslogtreecommitdiff
path: root/storage/innobase/btr/btr0pcur.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/btr/btr0pcur.cc')
-rw-r--r--storage/innobase/btr/btr0pcur.cc103
1 files changed, 33 insertions, 70 deletions
diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc
index e49ef672928..46b8d487850 100644
--- a/storage/innobase/btr/btr0pcur.cc
+++ b/storage/innobase/btr/btr0pcur.cc
@@ -30,25 +30,6 @@ Created 2/23/1996 Heikki Tuuri
#include "trx0trx.h"
/**************************************************************//**
-Allocates memory for a persistent cursor object and initializes the cursor.
-@return own: persistent cursor */
-btr_pcur_t*
-btr_pcur_create_for_mysql(void)
-/*============================*/
-{
- btr_pcur_t* pcur;
- DBUG_ENTER("btr_pcur_create_for_mysql");
-
- pcur = (btr_pcur_t*) ut_malloc_nokey(sizeof(btr_pcur_t));
-
- pcur->btr_cur.index = NULL;
- btr_pcur_init(pcur);
-
- DBUG_PRINT("btr_pcur_create_for_mysql", ("pcur: %p", pcur));
- DBUG_RETURN(pcur);
-}
-
-/**************************************************************//**
Resets a persistent cursor object, freeing ::old_rec_buf if it is
allocated and resetting the other members to their initial values. */
void
@@ -56,35 +37,18 @@ btr_pcur_reset(
/*===========*/
btr_pcur_t* cursor) /*!< in, out: persistent cursor */
{
- btr_pcur_free(cursor);
+ ut_free(cursor->old_rec_buf);
+ memset(&cursor->btr_cur.page_cur, 0, sizeof(page_cur_t));
cursor->old_rec_buf = NULL;
- cursor->btr_cur.index = NULL;
- cursor->btr_cur.page_cur.rec = NULL;
cursor->old_rec = NULL;
cursor->old_n_core_fields = 0;
cursor->old_n_fields = 0;
- cursor->old_stored = false;
cursor->latch_mode = BTR_NO_LATCHES;
cursor->pos_state = BTR_PCUR_NOT_POSITIONED;
}
/**************************************************************//**
-Frees the memory for a persistent cursor object. */
-void
-btr_pcur_free_for_mysql(
-/*====================*/
- btr_pcur_t* cursor) /*!< in, own: persistent cursor */
-{
- DBUG_ENTER("btr_pcur_free_for_mysql");
- DBUG_PRINT("btr_pcur_free_for_mysql", ("pcur: %p", cursor));
-
- btr_pcur_free(cursor);
- ut_free(cursor);
- DBUG_VOID_RETURN;
-}
-
-/**************************************************************//**
The position of the cursor is stored by taking an initial segment of the
record the cursor is positioned on, before, or after, and copying it to the
cursor data structure, or just setting a flag if the cursor id before the
@@ -125,8 +89,6 @@ btr_pcur_store_position(
&& mtr->memo_contains_flagged(&index->lock, MTR_MEMO_X_LOCK
| MTR_MEMO_SX_LOCK)));
- cursor->old_stored = true;
-
if (page_is_empty(block->page.frame)) {
/* It must be an empty index tree; NOTE that in this case
we do not store the modify_clock, but always do a search
@@ -256,11 +218,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
{
@@ -292,7 +255,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;
@@ -301,7 +264,6 @@ btr_pcur_t::restore_position(ulint restore_latch_mode, mtr_t *mtr)
mem_heap_t* heap;
ut_ad(mtr->is_active());
- //ut_ad(cursor->old_stored);
ut_ad(pos_state == BTR_PCUR_WAS_POSITIONED
|| pos_state == BTR_PCUR_IS_POSITIONED);
@@ -313,10 +275,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;
}
@@ -333,9 +294,10 @@ btr_pcur_t::restore_position(ulint restore_latch_mode, mtr_t *mtr)
ut_a(old_n_core_fields <= index->n_core_fields);
ut_a(old_n_fields);
- switch (restore_latch_mode) {
- case BTR_SEARCH_LEAF:
- case BTR_MODIFY_LEAF:
+ static_assert(BTR_SEARCH_PREV == (4 | BTR_SEARCH_LEAF), "");
+ static_assert(BTR_MODIFY_PREV == (4 | BTR_MODIFY_LEAF), "");
+
+ switch (restore_latch_mode | 4) {
case BTR_SEARCH_PREV:
case BTR_MODIFY_PREV:
/* Try optimistic restoration. */
@@ -420,7 +382,7 @@ btr_pcur_t::restore_position(ulint restore_latch_mode, mtr_t *mtr)
mode = PAGE_CUR_UNSUPP;
}
- if (btr_pcur_open_with_no_init(index, tuple, mode, restore_latch_mode,
+ if (btr_pcur_open_with_no_init(tuple, mode, restore_latch_mode,
this, mtr) != DB_SUCCESS) {
mem_heap_free(heap);
return restore_status::CORRUPTED;
@@ -450,7 +412,6 @@ btr_pcur_t::restore_position(ulint restore_latch_mode, mtr_t *mtr)
block_when_stored.store(btr_pcur_get_block(this));
modify_clock= buf_block_get_modify_clock(
block_when_stored.block());
- old_stored= true;
mem_heap_free(heap);
@@ -487,7 +448,7 @@ btr_pcur_move_to_next_page(
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
ut_ad(btr_pcur_is_after_last_on_page(cursor));
- cursor->old_stored = false;
+ cursor->old_rec = nullptr;
const page_t* page = btr_pcur_get_page(cursor);
const uint32_t next_page_no = btr_page_get_next(page);
@@ -515,7 +476,7 @@ btr_pcur_move_to_next_page(
dberr_t err;
buf_block_t* next_block = btr_block_get(
- *btr_pcur_get_btr_cur(cursor)->index, next_page_no, mode,
+ *cursor->index(), next_page_no, mode,
page_is_leaf(page), mtr, &err);
if (UNIV_UNLIKELY(!next_block)) {
@@ -529,12 +490,13 @@ btr_pcur_move_to_next_page(
return DB_CORRUPTION;
}
- btr_leaf_page_release(btr_pcur_get_block(cursor), mode, mtr);
-
page_cur_set_before_first(next_block, btr_pcur_get_page_cur(cursor));
ut_d(page_check_dir(next_page));
- return err;
+
+ const auto s = mtr->get_savepoint();
+ mtr->rollback_to_savepoint(s - 2, s - 1);
+ return DB_SUCCESS;
}
MY_ATTRIBUTE((nonnull,warn_unused_result))
@@ -558,7 +520,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);
@@ -570,31 +532,32 @@ 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;
}
- buf_block_t* prev_block = btr_pcur_get_btr_cur(cursor)->left_block;
+ buf_block_t* release_block = nullptr;
if (!page_has_prev(btr_pcur_get_page(cursor))) {
} else if (btr_pcur_is_before_first_on_page(cursor)) {
- btr_leaf_page_release(btr_pcur_get_block(cursor),
- latch_mode, mtr);
-
- page_cur_set_after_last(prev_block,
+ release_block = btr_pcur_get_block(cursor);
+ page_cur_set_after_last(cursor->btr_cur.left_block,
btr_pcur_get_page_cur(cursor));
} else {
/* The repositioned cursor did not end on an infimum
record on a page. Cursor repositioning acquired a latch
also on the previous page, but we do not need the latch:
release it. */
- prev_block = btr_pcur_get_btr_cur(cursor)->left_block;
- btr_leaf_page_release(prev_block, latch_mode, mtr);
+ release_block = cursor->btr_cur.left_block;
}
cursor->latch_mode = latch_mode;
- cursor->old_stored = false;
+ cursor->old_rec = nullptr;
+ if (release_block) {
+ mtr->release(*release_block);
+ }
return false;
}
@@ -612,7 +575,7 @@ btr_pcur_move_to_prev(
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
- cursor->old_stored = false;
+ cursor->old_rec = nullptr;
if (btr_pcur_is_before_first_on_page(cursor)) {
return (!btr_pcur_is_before_first_in_tree(cursor)