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.cc65
1 files changed, 34 insertions, 31 deletions
diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc
index 6b6158d5892..5a052e58e86 100644
--- a/storage/innobase/btr/btr0pcur.cc
+++ b/storage/innobase/btr/btr0pcur.cc
@@ -29,6 +29,9 @@ Created 2/23/1996 Heikki Tuuri
#include "rem0cmp.h"
#include "trx0trx.h"
+/* FIXME: move this to a proper .h file */
+extern const dtuple_t trx_undo_metadata;
+
/**************************************************************//**
Allocates memory for a persistent cursor object and initializes the cursor.
@return own: persistent cursor */
@@ -177,9 +180,8 @@ btr_pcur_store_position(
if (index->is_ibuf()) {
ut_ad(!index->table->not_redundant());
cursor->old_n_fields = rec_get_n_fields_old(rec);
- } else if (page_rec_is_leaf(rec)) {
- cursor->old_n_fields = dict_index_get_n_unique_in_tree(index);
- } else if (index->is_spatial()) {
+ } else if (UNIV_UNLIKELY(!page_rec_is_leaf(rec)
+ && index->is_spatial())) {
ut_ad(dict_index_get_n_unique_in_tree_nonleaf(index)
== DICT_INDEX_SPATIAL_NODEPTR_SIZE);
/* For R-tree, we have to compare
@@ -252,10 +254,8 @@ btr_pcur_restore_position_func(
mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
- dtuple_t* tuple;
page_cur_mode_t mode;
page_cur_mode_t old_mode;
- mem_heap_t* heap;
ut_ad(mtr->is_active());
//ut_ad(cursor->old_stored);
@@ -326,7 +326,7 @@ btr_pcur_restore_position_func(
const ulint* offsets2;
rec = btr_pcur_get_rec(cursor);
- heap = mem_heap_create(256);
+ mem_heap_t* heap = mem_heap_create(256);
offsets1 = rec_get_offsets(
cursor->old_rec, index, NULL,
REC_FMT_LEAF,
@@ -355,12 +355,34 @@ btr_pcur_restore_position_func(
}
/* If optimistic restoration did not succeed, open the cursor anew */
+ if (UNIV_UNLIKELY(reinterpret_cast<const byte*>(&trx_undo_metadata)
+ == cursor->old_rec)) {
+ btr_pcur_open_at_index_side(true, index, cursor->latch_mode,
+ cursor, true, 0, mtr);
+ ut_ad(btr_pcur_is_before_first_on_page(cursor));
+ btr_pcur_move_to_next_on_page(cursor);
+ /* We have to store the NEW value for the modify clock,
+ since the cursor can now be on a different page! */
+ if (!page_rec_is_metadata(btr_pcur_get_rec(cursor))) {
+not_found:
+ btr_pcur_store_position(cursor, mtr);
+ return(FALSE);
+ }
+found:
+ /* We can retain the value of old_rec */
+ cursor->block_when_stored = btr_pcur_get_block(cursor);
+ cursor->modify_clock = buf_block_get_modify_clock(
+ cursor->block_when_stored);
+ cursor->old_stored = true;
+ cursor->withdraw_clock = buf_withdraw_clock;
+ return(TRUE);
+ }
- heap = mem_heap_create(256);
+ mem_heap_t* heap = mem_heap_create(256);
- tuple = dict_index_build_data_tuple(cursor->old_rec, index,
- REC_FMT_LEAF,
- cursor->old_n_fields, heap);
+ const dtuple_t* tuple = dict_index_build_data_tuple(
+ cursor->old_rec, index, REC_FMT_LEAF,
+ cursor->old_n_fields, heap);
/* Save the old search mode of the cursor */
old_mode = cursor->search_mode;
@@ -404,31 +426,12 @@ btr_pcur_restore_position_func(
? REC_FMT_LEAF
: REC_FMT_LEAF_FLEXIBLE,
ULINT_UNDEFINED, &heap))) {
-
- /* We have to store the NEW value for the modify clock,
- since the cursor can now be on a different page!
- But we can retain the value of old_rec */
-
- cursor->block_when_stored = btr_pcur_get_block(cursor);
- cursor->modify_clock = buf_block_get_modify_clock(
- cursor->block_when_stored);
- cursor->old_stored = true;
- cursor->withdraw_clock = buf_withdraw_clock;
-
mem_heap_free(heap);
-
- return(TRUE);
+ goto found;
}
mem_heap_free(heap);
-
- /* We have to store new position information, modify_clock etc.,
- to the cursor because it can now be on a different page, the record
- under it may have been removed, etc. */
-
- btr_pcur_store_position(cursor, mtr);
-
- return(FALSE);
+ goto not_found;
}
/*********************************************************//**