summaryrefslogtreecommitdiffstats
path: root/storage/innobase/btr/btr0cur.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/btr/btr0cur.cc')
-rw-r--r--storage/innobase/btr/btr0cur.cc77
1 files changed, 48 insertions, 29 deletions
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index e736f338..46afb73b 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -1156,6 +1156,19 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
mtr_s_lock_index(index(), mtr);
}
+ dberr_t err;
+
+ if (!index()->table->space)
+ {
+ corrupted:
+ ut_ad("corrupted" == 0); // FIXME: remove this
+ err= DB_CORRUPTION;
+ func_exit:
+ if (UNIV_LIKELY_NULL(heap))
+ mem_heap_free(heap);
+ return err;
+ }
+
const ulint zip_size= index()->table->space->zip_size();
/* Start with the root page. */
@@ -1169,7 +1182,6 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
low_bytes= 0;
ulint buf_mode= BUF_GET;
search_loop:
- dberr_t err;
auto block_savepoint= mtr->get_savepoint();
buf_block_t *block=
buf_page_get_gen(page_id, zip_size, rw_latch, guess, buf_mode, mtr,
@@ -1181,10 +1193,7 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
btr_decryption_failed(*index());
/* fall through */
default:
- func_exit:
- if (UNIV_LIKELY_NULL(heap))
- mem_heap_free(heap);
- return err;
+ goto func_exit;
case DB_SUCCESS:
/* This must be a search to perform an insert, delete mark, or delete;
try using the change buffer */
@@ -1251,16 +1260,11 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
btr_page_get_index_id(block->page.frame) != index()->id ||
fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE ||
!fil_page_index_page_check(block->page.frame))
- {
- corrupted:
- ut_ad("corrupted" == 0); // FIXME: remove this
- err= DB_CORRUPTION;
- goto func_exit;
- }
+ goto corrupted;
page_cur.block= block;
ut_ad(block == mtr->at_savepoint(block_savepoint));
- ut_ad(rw_latch != RW_NO_LATCH);
+ const bool not_first_access{buf_page_make_young_if_needed(&block->page)};
#ifdef UNIV_ZIP_DEBUG
if (const page_zip_des_t *page_zip= buf_block_get_page_zip(block))
ut_a(page_zip_validate(page_zip, block->page.frame, index()));
@@ -1539,6 +1543,9 @@ release_tree:
case BTR_SEARCH_PREV: /* btr_pcur_move_to_prev() */
ut_ad(rw_latch == RW_S_LATCH || rw_latch == RW_X_LATCH);
+ if (!not_first_access)
+ buf_read_ahead_linear(page_id, zip_size, false);
+
if (page_has_prev(block->page.frame) &&
page_rec_is_first(page_cur.rec, block->page.frame))
{
@@ -1578,6 +1585,8 @@ release_tree:
buf_mode= btr_op == BTR_DELETE_OP
? BUF_GET_IF_IN_POOL_OR_WATCH
: BUF_GET_IF_IN_POOL;
+ else if (!not_first_access)
+ buf_read_ahead_linear(page_id, zip_size, false);
break;
case BTR_MODIFY_TREE:
ut_ad(rw_latch == RW_X_LATCH);
@@ -1611,6 +1620,14 @@ ATTRIBUTE_COLD void mtr_t::index_lock_upgrade()
slot.type= MTR_MEMO_X_LOCK;
}
+/** Mark a non-leaf page "least recently used", but avoid invoking
+buf_page_t::set_accessed(), because we do not want linear read-ahead */
+static void btr_cur_nonleaf_make_young(buf_page_t *bpage)
+{
+ if (UNIV_UNLIKELY(buf_page_peek_if_too_old(bpage)))
+ buf_page_make_young(bpage);
+}
+
ATTRIBUTE_COLD
dberr_t btr_cur_t::pessimistic_search_leaf(const dtuple_t *tuple,
page_cur_mode_t mode, mtr_t *mtr)
@@ -1713,6 +1730,8 @@ dberr_t btr_cur_t::pessimistic_search_leaf(const dtuple_t *tuple,
if (height != btr_page_get_level(block->page.frame))
goto corrupted;
+ btr_cur_nonleaf_make_young(&block->page);
+
#ifdef UNIV_ZIP_DEBUG
const page_zip_des_t *page_zip= buf_block_get_page_zip(block);
ut_a(!page_zip || page_zip_validate(page_zip, block->page.frame, index()));
@@ -1799,6 +1818,8 @@ search_loop:
btr_decryption_failed(*index);
goto func_exit;
}
+ else
+ btr_cur_nonleaf_make_young(&block->page);
#ifdef UNIV_ZIP_DEBUG
if (const page_zip_des_t *page_zip= buf_block_get_page_zip(block))
@@ -1934,18 +1955,15 @@ index_locked:
ut_ad(n_blocks < BTR_MAX_LEVELS);
ut_ad(savepoint + n_blocks == mtr->get_savepoint());
+ bool first_access= false;
buf_block_t* block=
btr_block_get(*index, page,
height ? upper_rw_latch : root_leaf_rw_latch,
- !height, mtr, &err);
+ !height, mtr, &err, &first_access);
ut_ad(!block == (err != DB_SUCCESS));
if (!block)
- {
- if (err == DB_DECRYPTION_FAILED)
- btr_decryption_failed(*index);
break;
- }
if (first)
page_cur_set_before_first(block, &page_cur);
@@ -2029,10 +2047,16 @@ index_locked:
offsets= rec_get_offsets(page_cur.rec, index, offsets, 0, ULINT_UNDEFINED,
&heap);
+ page= btr_node_ptr_get_child_page_no(page_cur.rec, offsets);
ut_ad(latch_mode != BTR_MODIFY_TREE || upper_rw_latch == RW_X_LATCH);
- if (latch_mode != BTR_MODIFY_TREE);
+ if (latch_mode != BTR_MODIFY_TREE)
+ {
+ if (!height && first && first_access)
+ buf_read_ahead_linear(page_id_t(block->page.id().space(), page),
+ block->page.zip_size(), false);
+ }
else if (btr_cur_need_opposite_intention(block->page, index->is_clust(),
lock_intention,
node_ptr_max_size, compress_limit,
@@ -2070,7 +2094,6 @@ index_locked:
}
/* Go to the child node */
- page= btr_node_ptr_get_child_page_no(page_cur.rec, offsets);
n_blocks++;
}
@@ -3837,22 +3860,14 @@ btr_cur_pess_upd_restore_supremum(
const page_id_t block_id{block->page.id()};
const page_id_t prev_id(block_id.space(), prev_page_no);
- dberr_t err;
buf_block_t* prev_block
- = buf_page_get_gen(prev_id, 0, RW_NO_LATCH, nullptr,
- BUF_PEEK_IF_IN_POOL, mtr, &err);
- /* Since we already held an x-latch on prev_block, it must
- be available and not be corrupted unless the buffer pool got
- corrupted somehow. */
+ = mtr->get_already_latched(prev_id, MTR_MEMO_PAGE_X_FIX);
if (UNIV_UNLIKELY(!prev_block)) {
- return err;
+ return DB_CORRUPTION;
}
ut_ad(!memcmp_aligned<4>(prev_block->page.frame + FIL_PAGE_NEXT,
block->page.frame + FIL_PAGE_OFFSET, 4));
- /* We must already have an x-latch on prev_block! */
- ut_ad(mtr->memo_contains_flagged(prev_block, MTR_MEMO_PAGE_X_FIX));
-
lock_rec_reset_and_inherit_gap_locks(*prev_block, block_id,
PAGE_HEAP_NO_SUPREMUM,
page_rec_get_heap_no(rec));
@@ -6660,6 +6675,10 @@ btr_copy_blob_prefix(
mtr.commit();
return copied_len;
}
+ if (!buf_page_make_young_if_needed(&block->page)) {
+ buf_read_ahead_linear(id, 0, false);
+ }
+
page = buf_block_get_frame(block);
blob_header = page + offset;