~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/btr/btr0cur.c

  • Committer: Monty Taylor
  • Date: 2010-11-26 22:50:54 UTC
  • mfrom: (1953.1.6 build)
  • Revision ID: mordred@inaugust.com-20101126225054-sg90svw8579t5p3i
Stewart - InnoDB 1.1.1
Monty - Fixed some autoconf tests which were returning false positives.

Show diffs side-by-side

added added

removed removed

Lines of Context:
57
57
#include "buf0lru.h"
58
58
#include "btr0btr.h"
59
59
#include "btr0sea.h"
 
60
#include "row0purge.h"
 
61
#include "row0upd.h"
60
62
#include "trx0rec.h"
61
63
#include "trx0roll.h" /* trx_is_recv() */
62
64
#include "que0que.h"
66
68
#include "lock0lock.h"
67
69
#include "zlib.h"
68
70
 
 
71
/** Buffered B-tree operation types, introduced as part of delete buffering. */
 
72
typedef enum btr_op_enum {
 
73
        BTR_NO_OP = 0,                  /*!< Not buffered */
 
74
        BTR_INSERT_OP,                  /*!< Insert, do not ignore UNIQUE */
 
75
        BTR_INSERT_IGNORE_UNIQUE_OP,    /*!< Insert, ignoring UNIQUE */
 
76
        BTR_DELETE_OP,                  /*!< Purge a delete-marked record */
 
77
        BTR_DELMARK_OP                  /*!< Mark a record for deletion */
 
78
} btr_op_t;
 
79
 
69
80
#ifdef UNIV_DEBUG
70
81
/** If the following is set to TRUE, this module prints a lot of
71
82
trace information of individual record operations */
328
339
                                Inserts should always be made using
329
340
                                PAGE_CUR_LE to search the position! */
330
341
        ulint           latch_mode, /*!< in: BTR_SEARCH_LEAF, ..., ORed with
331
 
                                BTR_INSERT and BTR_ESTIMATE;
 
342
                                at most one of BTR_INSERT, BTR_DELETE_MARK,
 
343
                                BTR_DELETE, or BTR_ESTIMATE;
332
344
                                cursor->left_block is used to store a pointer
333
345
                                to the left neighbor page, in the cases
334
346
                                BTR_SEARCH_PREV and BTR_MODIFY_PREV;
346
358
        ulint           line,   /*!< in: line where called */
347
359
        mtr_t*          mtr)    /*!< in: mtr */
348
360
{
349
 
        page_cur_t*     page_cursor;
350
361
        page_t*         page;
 
362
        buf_block_t*    block;
 
363
        ulint           space;
351
364
        buf_block_t*    guess;
352
 
        rec_t*          node_ptr;
 
365
        ulint           height;
353
366
        ulint           page_no;
354
 
        ulint           space;
355
367
        ulint           up_match;
356
368
        ulint           up_bytes;
357
369
        ulint           low_match;
358
370
        ulint           low_bytes;
359
 
        ulint           height;
360
371
        ulint           savepoint;
 
372
        ulint           rw_latch;
361
373
        ulint           page_mode;
362
 
        ulint           insert_planned;
 
374
        ulint           buf_mode;
363
375
        ulint           estimate;
364
 
        ulint           ignore_sec_unique;
 
376
        ulint           zip_size;
 
377
        page_cur_t*     page_cursor;
 
378
        btr_op_t        btr_op;
365
379
        ulint           root_height = 0; /* remove warning */
 
380
 
366
381
#ifdef BTR_CUR_ADAPT
367
382
        btr_search_t*   info;
368
383
#endif
382
397
        cursor->up_match = ULINT_UNDEFINED;
383
398
        cursor->low_match = ULINT_UNDEFINED;
384
399
#endif
385
 
        insert_planned = latch_mode & BTR_INSERT;
 
400
 
 
401
        /* These flags are mutually exclusive, they are lumped together
 
402
        with the latch mode for historical reasons. It's possible for
 
403
        none of the flags to be set. */
 
404
        switch (UNIV_EXPECT(latch_mode
 
405
                            & (BTR_INSERT | BTR_DELETE | BTR_DELETE_MARK),
 
406
                            0)) {
 
407
        case 0:
 
408
                btr_op = BTR_NO_OP;
 
409
                break;
 
410
        case BTR_INSERT:
 
411
                btr_op = (latch_mode & BTR_IGNORE_SEC_UNIQUE)
 
412
                        ? BTR_INSERT_IGNORE_UNIQUE_OP
 
413
                        : BTR_INSERT_OP;
 
414
                break;
 
415
        case BTR_DELETE:
 
416
                btr_op = BTR_DELETE_OP;
 
417
                ut_a(cursor->purge_node);
 
418
                break;
 
419
        case BTR_DELETE_MARK:
 
420
                btr_op = BTR_DELMARK_OP;
 
421
                break;
 
422
        default:
 
423
                /* only one of BTR_INSERT, BTR_DELETE, BTR_DELETE_MARK
 
424
                should be specified at a time */
 
425
                ut_error;
 
426
        }
 
427
 
 
428
        /* Operations on the insert buffer tree cannot be buffered. */
 
429
        ut_ad(btr_op == BTR_NO_OP || !dict_index_is_ibuf(index));
 
430
        /* Operations on the clustered index cannot be buffered. */
 
431
        ut_ad(btr_op == BTR_NO_OP || !dict_index_is_clust(index));
 
432
 
386
433
        estimate = latch_mode & BTR_ESTIMATE;
387
 
        ignore_sec_unique = latch_mode & BTR_IGNORE_SEC_UNIQUE;
388
 
        latch_mode = latch_mode & ~(BTR_INSERT | BTR_ESTIMATE
389
 
                                    | BTR_IGNORE_SEC_UNIQUE);
390
434
 
391
 
        ut_ad(!insert_planned || (mode == PAGE_CUR_LE));
 
435
        /* Turn the flags unrelated to the latch mode off. */
 
436
        latch_mode &= ~(BTR_INSERT
 
437
                        | BTR_DELETE_MARK
 
438
                        | BTR_DELETE
 
439
                        | BTR_ESTIMATE
 
440
                        | BTR_IGNORE_SEC_UNIQUE);
392
441
 
393
442
        cursor->flag = BTR_CUR_BINARY;
394
443
        cursor->index = index;
395
444
 
 
445
        cursor->ibuf_cnt = ULINT_UNDEFINED;
 
446
 
396
447
#ifndef BTR_CUR_ADAPT
397
448
        guess = NULL;
398
449
#else
406
457
        info->n_searches++;
407
458
#endif
408
459
        if (rw_lock_get_writer(&btr_search_latch) == RW_LOCK_NOT_LOCKED
409
 
            && latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ
 
460
            && latch_mode <= BTR_MODIFY_LEAF
 
461
            && info->last_hash_succ
410
462
            && !estimate
411
463
#ifdef PAGE_CUR_LE_OR_EXTENDS
412
464
            && mode != PAGE_CUR_LE_OR_EXTENDS
495
547
 
496
548
        /* Loop and search until we arrive at the desired level */
497
549
 
498
 
        for (;;) {
499
 
                ulint           zip_size;
500
 
                buf_block_t*    block;
501
 
                ulint           rw_latch;
502
 
                ulint           buf_mode;
503
 
 
504
 
                zip_size = dict_table_zip_size(index->table);
505
 
                rw_latch = RW_NO_LATCH;
506
 
                buf_mode = BUF_GET;
507
 
 
508
 
                if (height == 0 && latch_mode <= BTR_MODIFY_LEAF) {
509
 
 
510
 
                        rw_latch = latch_mode;
511
 
 
512
 
                        if (insert_planned
513
 
                            && ibuf_should_try(index, ignore_sec_unique)) {
514
 
 
515
 
                                /* Try insert to the insert buffer if the
516
 
                                page is not in the buffer pool */
517
 
 
518
 
                                buf_mode = BUF_GET_IF_IN_POOL;
519
 
                        }
 
550
search_loop:
 
551
        buf_mode = BUF_GET;
 
552
        rw_latch = RW_NO_LATCH;
 
553
 
 
554
        if (height != 0) {
 
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;
 
558
 
 
559
                if (btr_op != BTR_NO_OP
 
560
                    && ibuf_should_try(index, btr_op != BTR_INSERT_OP)) {
 
561
 
 
562
                        /* Try to buffer the operation if the leaf
 
563
                        page is not in the buffer pool. */
 
564
 
 
565
                        buf_mode = btr_op == BTR_DELETE_OP
 
566
                                ? BUF_GET_IF_IN_POOL_OR_WATCH
 
567
                                : BUF_GET_IF_IN_POOL;
520
568
                }
 
569
        }
 
570
 
 
571
        zip_size = dict_table_zip_size(index->table);
521
572
 
522
573
retry_page_get:
523
 
                block = buf_page_get_gen(space, zip_size, page_no,
524
 
                                         rw_latch, guess, buf_mode,
525
 
                                         file, line, mtr);
526
 
                if (block == NULL) {
527
 
                        /* This must be a search to perform an insert;
528
 
                        try insert to the insert buffer */
529
 
 
530
 
                        ut_ad(buf_mode == BUF_GET_IF_IN_POOL);
531
 
                        ut_ad(insert_planned);
532
 
                        ut_ad(cursor->thr);
533
 
 
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,
 
576
                file, line, mtr);
 
577
 
 
578
        if (block == NULL) {
 
579
                /* This must be a search to perform an insert/delete
 
580
                mark/ delete; try using the insert/delete buffer */
 
581
 
 
582
                ut_ad(height == 0);
 
583
                ut_ad(cursor->thr);
 
584
 
 
585
                switch (btr_op) {
 
586
                case BTR_INSERT_OP:
 
587
                case BTR_INSERT_IGNORE_UNIQUE_OP:
 
588
                        ut_ad(buf_mode == BUF_GET_IF_IN_POOL);
 
589
 
 
590
                        if (ibuf_insert(IBUF_OP_INSERT, tuple, index,
 
591
                                        space, zip_size, page_no,
 
592
                                        cursor->thr)) {
 
593
 
 
594
                                cursor->flag = BTR_CUR_INSERT_TO_IBUF;
 
595
 
 
596
                                goto func_exit;
 
597
                        }
 
598
                        break;
 
599
 
 
600
                case BTR_DELMARK_OP:
 
601
                        ut_ad(buf_mode == BUF_GET_IF_IN_POOL);
 
602
 
 
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)) {
539
 
                                        mem_heap_free(heap);
540
 
                                }
 
606
 
 
607
                                cursor->flag = BTR_CUR_DEL_MARK_IBUF;
 
608
 
541
609
                                goto func_exit;
542
610
                        }
543
611
 
544
 
                        /* Insert to the insert buffer did not succeed:
545
 
                        retry page get */
 
612
                        break;
 
613
 
 
614
                case BTR_DELETE_OP:
 
615
                        ut_ad(buf_mode == BUF_GET_IF_IN_POOL_OR_WATCH);
 
616
 
 
617
                        if (!row_purge_poss_sec(cursor->purge_node,
 
618
                                                index, tuple)) {
 
619
 
 
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,
 
624
                                               page_no,
 
625
                                               cursor->thr)) {
 
626
 
 
627
                                /* The purge was buffered. */
 
628
                                cursor->flag = BTR_CUR_DELETE_IBUF;
 
629
                        } else {
 
630
                                /* The purge could not be buffered. */
 
631
                                buf_pool_watch_unset(space, page_no);
 
632
                                break;
 
633
                        }
 
634
 
 
635
                        buf_pool_watch_unset(space, page_no);
 
636
                        goto func_exit;
 
637
 
 
638
                default:
 
639
                        ut_error;
 
640
                }
 
641
 
 
642
                /* Insert to the insert/delete buffer did not succeed, we
 
643
                must read the page from disk. */
 
644
 
 
645
                buf_mode = BUF_GET;
 
646
 
 
647
                goto retry_page_get;
 
648
        }
 
649
 
 
650
        block->check_index_page_at_flush = TRUE;
 
651
        page = buf_block_get_frame(block);
 
652
 
 
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 */
 
659
 
 
660
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
 
661
        }
 
662
 
 
663
        ut_ad(0 == ut_dulint_cmp(index->id, btr_page_get_index_id(page)));
 
664
 
 
665
        if (UNIV_UNLIKELY(height == ULINT_UNDEFINED)) {
 
666
                /* We are in the root node */
 
667
 
 
668
                height = btr_page_get_level(page, mtr);
 
669
                root_height = height;
 
670
                cursor->tree_height = root_height + 1;
 
671
 
 
672
#ifdef BTR_CUR_ADAPT
 
673
                if (block != guess) {
 
674
                        info->root_guess = block;
 
675
                }
 
676
#endif
 
677
        }
 
678
 
 
679
        if (height == 0) {
 
680
                if (rw_latch == RW_NO_LATCH) {
 
681
 
 
682
                        btr_cur_latch_leaves(
 
683
                                page, space, zip_size, page_no, latch_mode,
 
684
                                cursor, mtr);
 
685
                }
 
686
 
 
687
                if (latch_mode != BTR_MODIFY_TREE
 
688
                    && latch_mode != BTR_CONT_MODIFY_TREE) {
 
689
 
 
690
                        /* Release the tree s-latch */
 
691
 
 
692
                        mtr_release_s_latch_at_savepoint(
 
693
                                mtr, savepoint, dict_index_get_lock(index));
 
694
                }
 
695
 
 
696
                page_mode = mode;
 
697
        }
 
698
 
 
699
        page_cur_search_with_match(
 
700
                block, index, tuple, page_mode, &up_match, &up_bytes,
 
701
                &low_match, &low_bytes, page_cursor);
 
702
 
 
703
        if (estimate) {
 
704
                btr_cur_add_path_info(cursor, height, root_height);
 
705
        }
 
706
 
 
707
        /* If this is the desired level, leave the loop */
 
708
 
 
709
        ut_ad(height == btr_page_get_level(page_cur_get_page(page_cursor),
 
710
                                           mtr));
 
711
 
 
712
        if (level != height) {
 
713
 
 
714
                const rec_t*    node_ptr;
 
715
                ut_ad(height > 0);
 
716
 
 
717
                height--;
 
718
                guess = NULL;
 
719
 
 
720
                node_ptr = page_cur_get_rec(page_cursor);
 
721
 
 
722
                offsets = rec_get_offsets(
 
723
                        node_ptr, index, offsets, ULINT_UNDEFINED, &heap);
 
724
 
 
725
                /* Go to the child node */
 
726
                page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
 
727
 
 
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. */
 
731
 
 
732
                        ulint   is_min_rec;
 
733
 
 
734
                        ut_ad(level == 0);
 
735
 
 
736
                        is_min_rec = rec_get_info_bits(node_ptr, 0)
 
737
                                & REC_INFO_MIN_REC_FLAG;
 
738
 
 
739
                        if (!is_min_rec) {
 
740
                                cursor->ibuf_cnt
 
741
                                        = ibuf_rec_get_counter(node_ptr);
 
742
 
 
743
                                ut_a(cursor->ibuf_cnt <= 0xFFFF
 
744
                                     || cursor->ibuf_cnt == ULINT_UNDEFINED);
 
745
                        }
546
746
 
547
747
                        buf_mode = BUF_GET;
548
 
 
 
748
                        rw_latch = RW_NO_LATCH;
549
749
                        goto retry_page_get;
550
750
                }
551
751
 
552
 
                page = buf_block_get_frame(block);
553
 
 
554
 
                block->check_index_page_at_flush = TRUE;
555
 
 
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 */
562
 
 
563
 
                        buf_block_dbg_add_level(block, SYNC_TREE_NODE);
564
 
                }
565
 
 
566
 
                ut_ad(0 == ut_dulint_cmp(index->id,
567
 
                                         btr_page_get_index_id(page)));
568
 
 
569
 
                if (UNIV_UNLIKELY(height == ULINT_UNDEFINED)) {
570
 
                        /* We are in the root node */
571
 
 
572
 
                        height = btr_page_get_level(page, mtr);
573
 
                        root_height = height;
574
 
                        cursor->tree_height = root_height + 1;
575
 
#ifdef BTR_CUR_ADAPT
576
 
                        if (block != guess) {
577
 
                                info->root_guess = block;
578
 
                        }
579
 
#endif
580
 
                }
581
 
 
582
 
                if (height == 0) {
583
 
                        if (rw_latch == RW_NO_LATCH) {
584
 
 
585
 
                                btr_cur_latch_leaves(page, space, zip_size,
586
 
                                                     page_no, latch_mode,
587
 
                                                     cursor, mtr);
588
 
                        }
589
 
 
590
 
                        if ((latch_mode != BTR_MODIFY_TREE)
591
 
                            && (latch_mode != BTR_CONT_MODIFY_TREE)) {
592
 
 
593
 
                                /* Release the tree s-latch */
594
 
 
595
 
                                mtr_release_s_latch_at_savepoint(
596
 
                                        mtr, savepoint,
597
 
                                        dict_index_get_lock(index));
598
 
                        }
599
 
 
600
 
                        page_mode = mode;
601
 
                }
602
 
 
603
 
                page_cur_search_with_match(block, index, tuple, page_mode,
604
 
                                           &up_match, &up_bytes,
605
 
                                           &low_match, &low_bytes,
606
 
                                           page_cursor);
607
 
 
608
 
                if (estimate) {
609
 
                        btr_cur_add_path_info(cursor, height, root_height);
610
 
                }
611
 
 
612
 
                /* If this is the desired level, leave the loop */
613
 
 
614
 
                ut_ad(height == btr_page_get_level(
615
 
                              page_cur_get_page(page_cursor), mtr));
616
 
 
617
 
                if (level == height) {
618
 
 
619
 
                        if (level > 0) {
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));
625
 
                        }
626
 
 
627
 
                        break;
628
 
                }
629
 
 
630
 
                ut_ad(height > 0);
631
 
 
632
 
                height--;
633
 
 
634
 
                guess = NULL;
635
 
 
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);
641
 
        }
642
 
 
643
 
        if (UNIV_LIKELY_NULL(heap)) {
644
 
                mem_heap_free(heap);
645
 
        }
646
 
 
647
 
        if (level == 0) {
 
752
                goto search_loop;
 
753
        }
 
754
 
 
755
        if (level != 0) {
 
756
                /* x-latch the page */
 
757
                page = btr_page_get(
 
758
                        space, zip_size, page_no, RW_X_LATCH, mtr);
 
759
 
 
760
                ut_a((ibool)!!page_is_comp(page)
 
761
                     == dict_table_is_comp(index->table));
 
762
        } else {
648
763
                cursor->low_match = low_match;
649
764
                cursor->low_bytes = low_bytes;
650
765
                cursor->up_match = up_match;
669
784
        }
670
785
 
671
786
func_exit:
 
787
 
 
788
        if (UNIV_LIKELY_NULL(heap)) {
 
789
                mem_heap_free(heap);
 
790
        }
 
791
 
672
792
        if (has_search_latch) {
673
793
 
674
794
                rw_lock_s_lock(&btr_search_latch);
1959
2079
        err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
1960
2080
                                        thr, mtr, &roll_ptr);
1961
2081
        if (err != DB_SUCCESS) {
1962
 
err_exit:
1963
 
                mem_heap_free(heap);
1964
 
                return(err);
 
2082
 
 
2083
                goto err_exit;
1965
2084
        }
1966
2085
 
1967
2086
        /* Ok, we may do the replacement. Store on the page infimum the
2007
2126
 
2008
2127
        page_cur_move_to_next(page_cursor);
2009
2128
 
 
2129
        err = DB_SUCCESS;
 
2130
err_exit:
2010
2131
        mem_heap_free(heap);
2011
 
 
2012
 
        return(DB_SUCCESS);
 
2132
        return(err);
2013
2133
}
2014
2134
 
2015
2135
/*************************************************************//**
2722
2842
}
2723
2843
 
2724
2844
/***********************************************************//**
2725
 
Clear a secondary index record's delete mark.  This function is only
2726
 
used by the insert buffer insert merge mechanism. */
 
2845
Sets a secondary index record's delete mark to the given value. This
 
2846
function is only used by the insert buffer merge mechanism. */
2727
2847
UNIV_INTERN
2728
2848
void
2729
 
btr_cur_del_unmark_for_ibuf(
2730
 
/*========================*/
2731
 
        rec_t*          rec,            /*!< in/out: record to delete unmark */
 
2849
btr_cur_set_deleted_flag_for_ibuf(
 
2850
/*==============================*/
 
2851
        rec_t*          rec,            /*!< in/out: record */
2732
2852
        page_zip_des_t* page_zip,       /*!< in/out: compressed page
2733
2853
                                        corresponding to rec, or NULL
2734
2854
                                        when the tablespace is
2735
2855
                                        uncompressed */
 
2856
        ibool           val,            /*!< in: value to set */
2736
2857
        mtr_t*          mtr)            /*!< in: mtr */
2737
2858
{
2738
2859
        /* We do not need to reserve btr_search_latch, as the page has just
2739
2860
        been read to the buffer pool and there cannot be a hash index to it. */
2740
2861
 
2741
 
        btr_rec_set_deleted_flag(rec, page_zip, FALSE);
 
2862
        btr_rec_set_deleted_flag(rec, page_zip, val);
2742
2863
 
2743
 
        btr_cur_del_mark_set_sec_rec_log(rec, FALSE, mtr);
 
2864
        btr_cur_del_mark_set_sec_rec_log(rec, val, mtr);
2744
2865
}
2745
2866
 
2746
2867
/*==================== B-TREE RECORD REMOVE =========================*/
3752
3873
                                if there is one */
3753
3874
        mtr_t*          mtr)    /*!< in: mini-transaction to commit */
3754
3875
{
3755
 
        ulint   space   = buf_block_get_space(block);
3756
 
        ulint   page_no = buf_block_get_page_no(block);
 
3876
        buf_pool_t*     buf_pool = buf_pool_from_block(block);
 
3877
        ulint           space   = buf_block_get_space(block);
 
3878
        ulint           page_no = buf_block_get_page_no(block);
3757
3879
 
3758
3880
        ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3759
3881
 
3760
3882
        mtr_commit(mtr);
3761
3883
 
3762
 
        buf_pool_mutex_enter();
 
3884
        buf_pool_mutex_enter(buf_pool);
3763
3885
        mutex_enter(&block->mutex);
3764
3886
 
3765
3887
        /* Only free the block if it is still allocated to
3780
3902
                }
3781
3903
        }
3782
3904
 
3783
 
        buf_pool_mutex_exit();
 
3905
        buf_pool_mutex_exit(buf_pool);
3784
3906
        mutex_exit(&block->mutex);
3785
3907
}
3786
3908