496
548
/* Loop and search until we arrive at the desired level */
504
zip_size = dict_table_zip_size(index->table);
505
rw_latch = RW_NO_LATCH;
508
if (height == 0 && latch_mode <= BTR_MODIFY_LEAF) {
510
rw_latch = latch_mode;
513
&& ibuf_should_try(index, ignore_sec_unique)) {
515
/* Try insert to the insert buffer if the
516
page is not in the buffer pool */
518
buf_mode = BUF_GET_IF_IN_POOL;
552
rw_latch = RW_NO_LATCH;
555
/* We are about to fetch the root or a non-leaf page. */
556
} else if (latch_mode <= BTR_MODIFY_LEAF) {
557
rw_latch = latch_mode;
559
if (btr_op != BTR_NO_OP
560
&& ibuf_should_try(index, btr_op != BTR_INSERT_OP)) {
562
/* Try to buffer the operation if the leaf
563
page is not in the buffer pool. */
565
buf_mode = btr_op == BTR_DELETE_OP
566
? BUF_GET_IF_IN_POOL_OR_WATCH
567
: BUF_GET_IF_IN_POOL;
571
zip_size = dict_table_zip_size(index->table);
523
block = buf_page_get_gen(space, zip_size, page_no,
524
rw_latch, guess, buf_mode,
527
/* This must be a search to perform an insert;
528
try insert to the insert buffer */
530
ut_ad(buf_mode == BUF_GET_IF_IN_POOL);
531
ut_ad(insert_planned);
534
if (ibuf_insert(tuple, index, space, zip_size,
574
block = buf_page_get_gen(
575
space, zip_size, page_no, rw_latch, guess, buf_mode,
579
/* This must be a search to perform an insert/delete
580
mark/ delete; try using the insert/delete buffer */
587
case BTR_INSERT_IGNORE_UNIQUE_OP:
588
ut_ad(buf_mode == BUF_GET_IF_IN_POOL);
590
if (ibuf_insert(IBUF_OP_INSERT, tuple, index,
591
space, zip_size, page_no,
594
cursor->flag = BTR_CUR_INSERT_TO_IBUF;
601
ut_ad(buf_mode == BUF_GET_IF_IN_POOL);
603
if (ibuf_insert(IBUF_OP_DELETE_MARK, tuple,
604
index, space, zip_size,
535
605
page_no, cursor->thr)) {
536
/* Insertion to the insert buffer succeeded */
537
cursor->flag = BTR_CUR_INSERT_TO_IBUF;
538
if (UNIV_LIKELY_NULL(heap)) {
607
cursor->flag = BTR_CUR_DEL_MARK_IBUF;
544
/* Insert to the insert buffer did not succeed:
615
ut_ad(buf_mode == BUF_GET_IF_IN_POOL_OR_WATCH);
617
if (!row_purge_poss_sec(cursor->purge_node,
620
/* The record cannot be purged yet. */
621
cursor->flag = BTR_CUR_DELETE_REF;
622
} else if (ibuf_insert(IBUF_OP_DELETE, tuple,
623
index, space, zip_size,
627
/* The purge was buffered. */
628
cursor->flag = BTR_CUR_DELETE_IBUF;
630
/* The purge could not be buffered. */
631
buf_pool_watch_unset(space, page_no);
635
buf_pool_watch_unset(space, page_no);
642
/* Insert to the insert/delete buffer did not succeed, we
643
must read the page from disk. */
650
block->check_index_page_at_flush = TRUE;
651
page = buf_block_get_frame(block);
653
if (rw_latch != RW_NO_LATCH) {
654
#ifdef UNIV_ZIP_DEBUG
655
const page_zip_des_t* page_zip
656
= buf_block_get_page_zip(block);
657
ut_a(!page_zip || page_zip_validate(page_zip, page));
658
#endif /* UNIV_ZIP_DEBUG */
660
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
663
ut_ad(0 == ut_dulint_cmp(index->id, btr_page_get_index_id(page)));
665
if (UNIV_UNLIKELY(height == ULINT_UNDEFINED)) {
666
/* We are in the root node */
668
height = btr_page_get_level(page, mtr);
669
root_height = height;
670
cursor->tree_height = root_height + 1;
673
if (block != guess) {
674
info->root_guess = block;
680
if (rw_latch == RW_NO_LATCH) {
682
btr_cur_latch_leaves(
683
page, space, zip_size, page_no, latch_mode,
687
if (latch_mode != BTR_MODIFY_TREE
688
&& latch_mode != BTR_CONT_MODIFY_TREE) {
690
/* Release the tree s-latch */
692
mtr_release_s_latch_at_savepoint(
693
mtr, savepoint, dict_index_get_lock(index));
699
page_cur_search_with_match(
700
block, index, tuple, page_mode, &up_match, &up_bytes,
701
&low_match, &low_bytes, page_cursor);
704
btr_cur_add_path_info(cursor, height, root_height);
707
/* If this is the desired level, leave the loop */
709
ut_ad(height == btr_page_get_level(page_cur_get_page(page_cursor),
712
if (level != height) {
714
const rec_t* node_ptr;
720
node_ptr = page_cur_get_rec(page_cursor);
722
offsets = rec_get_offsets(
723
node_ptr, index, offsets, ULINT_UNDEFINED, &heap);
725
/* Go to the child node */
726
page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
728
if (UNIV_UNLIKELY(height == 0 && dict_index_is_ibuf(index))) {
729
/* We're doing a search on an ibuf tree and we're one
730
level above the leaf page. */
736
is_min_rec = rec_get_info_bits(node_ptr, 0)
737
& REC_INFO_MIN_REC_FLAG;
741
= ibuf_rec_get_counter(node_ptr);
743
ut_a(cursor->ibuf_cnt <= 0xFFFF
744
|| cursor->ibuf_cnt == ULINT_UNDEFINED);
547
747
buf_mode = BUF_GET;
748
rw_latch = RW_NO_LATCH;
549
749
goto retry_page_get;
552
page = buf_block_get_frame(block);
554
block->check_index_page_at_flush = TRUE;
556
if (rw_latch != RW_NO_LATCH) {
557
#ifdef UNIV_ZIP_DEBUG
558
const page_zip_des_t* page_zip
559
= buf_block_get_page_zip(block);
560
ut_a(!page_zip || page_zip_validate(page_zip, page));
561
#endif /* UNIV_ZIP_DEBUG */
563
buf_block_dbg_add_level(block, SYNC_TREE_NODE);
566
ut_ad(0 == ut_dulint_cmp(index->id,
567
btr_page_get_index_id(page)));
569
if (UNIV_UNLIKELY(height == ULINT_UNDEFINED)) {
570
/* We are in the root node */
572
height = btr_page_get_level(page, mtr);
573
root_height = height;
574
cursor->tree_height = root_height + 1;
576
if (block != guess) {
577
info->root_guess = block;
583
if (rw_latch == RW_NO_LATCH) {
585
btr_cur_latch_leaves(page, space, zip_size,
590
if ((latch_mode != BTR_MODIFY_TREE)
591
&& (latch_mode != BTR_CONT_MODIFY_TREE)) {
593
/* Release the tree s-latch */
595
mtr_release_s_latch_at_savepoint(
597
dict_index_get_lock(index));
603
page_cur_search_with_match(block, index, tuple, page_mode,
604
&up_match, &up_bytes,
605
&low_match, &low_bytes,
609
btr_cur_add_path_info(cursor, height, root_height);
612
/* If this is the desired level, leave the loop */
614
ut_ad(height == btr_page_get_level(
615
page_cur_get_page(page_cursor), mtr));
617
if (level == height) {
620
/* x-latch the page */
621
page = btr_page_get(space, zip_size,
622
page_no, RW_X_LATCH, mtr);
623
ut_a((ibool)!!page_is_comp(page)
624
== dict_table_is_comp(index->table));
636
node_ptr = page_cur_get_rec(page_cursor);
637
offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
638
ULINT_UNDEFINED, &heap);
639
/* Go to the child node */
640
page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
643
if (UNIV_LIKELY_NULL(heap)) {
756
/* x-latch the page */
758
space, zip_size, page_no, RW_X_LATCH, mtr);
760
ut_a((ibool)!!page_is_comp(page)
761
== dict_table_is_comp(index->table));
648
763
cursor->low_match = low_match;
649
764
cursor->low_bytes = low_bytes;
650
765
cursor->up_match = up_match;