~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/ibuf/ibuf0ibuf.c

  • Committer: Monty Taylor
  • Date: 2008-08-04 19:37:18 UTC
  • mto: (261.2.2 codestyle)
  • mto: This revision was merged to the branch mainline in revision 262.
  • Revision ID: monty@inaugust.com-20080804193718-f0rz13uli4429ozb
Changed gettext_noop() to N_()

Show diffs side-by-side

added added

removed removed

Lines of Context:
138
138
#define IBUF_POOL_SIZE_PER_MAX_SIZE     2
139
139
 
140
140
/* The insert buffer control structure */
141
 
UNIV_INTERN ibuf_t*     ibuf                    = NULL;
142
 
 
143
 
static ulint ibuf_rnd                           = 986058871;
144
 
 
145
 
UNIV_INTERN ulint       ibuf_flush_count        = 0;
146
 
 
147
 
#ifdef UNIV_IBUF_COUNT_DEBUG
 
141
ibuf_t* ibuf                    = NULL;
 
142
 
 
143
static ulint ibuf_rnd           = 986058871;
 
144
 
 
145
ulint   ibuf_flush_count        = 0;
 
146
 
 
147
#ifdef UNIV_IBUF_DEBUG
148
148
/* Dimensions for the ibuf_count array */
149
149
#define IBUF_COUNT_N_SPACES     500
150
150
#define IBUF_COUNT_N_PAGES      2000
166
166
        }
167
167
 
168
168
        fprintf(stderr,
169
 
                "InnoDB: UNIV_IBUF_COUNT_DEBUG limits space_id and page_no\n"
 
169
                "InnoDB: UNIV_IBUF_DEBUG limits space_id and page_no\n"
170
170
                "InnoDB: and breaks crash recovery.\n"
171
171
                "InnoDB: space_id=%lu, should be 0<=space_id<%lu\n"
172
172
                "InnoDB: page_no=%lu, should be 0<=page_no<%lu\n",
230
230
still physically like the index page even if the index would have been
231
231
dropped! So, there seems to be no problem. */
232
232
 
233
 
#ifdef UNIV_DEBUG
234
233
/**********************************************************************
235
234
Validates the ibuf data structures when the caller owns ibuf_mutex. */
236
 
static
 
235
 
237
236
ibool
238
237
ibuf_validate_low(void);
239
238
/*===================*/
240
239
                        /* out: TRUE if ok */
241
 
#endif /* UNIV_DEBUG */
 
240
 
242
241
/**********************************************************************
243
242
Sets the flag in the current OS thread local storage denoting that it is
244
243
inside an insert buffer routine. */
276
275
/**********************************************************************
277
276
Returns TRUE if the current OS thread is performing an insert buffer
278
277
routine. */
279
 
UNIV_INTERN
 
278
 
280
279
ibool
281
280
ibuf_inside(void)
282
281
/*=============*/
296
295
        ulint   space,  /* in: space id */
297
296
        mtr_t*  mtr)    /* in: mtr */
298
297
{
299
 
        buf_block_t*    block;
 
298
        page_t* page;
300
299
 
301
300
        ut_a(space == 0);
302
301
 
303
302
        ut_ad(!ibuf_inside());
304
303
 
305
 
        block = buf_page_get(space, 0, FSP_IBUF_HEADER_PAGE_NO,
306
 
                             RW_X_LATCH, mtr);
 
304
        page = buf_page_get(space, FSP_IBUF_HEADER_PAGE_NO, RW_X_LATCH, mtr);
307
305
 
308
306
#ifdef UNIV_SYNC_DEBUG
309
 
        buf_block_dbg_add_level(block, SYNC_IBUF_HEADER);
 
307
        buf_page_dbg_add_level(page, SYNC_IBUF_HEADER);
310
308
#endif /* UNIV_SYNC_DEBUG */
311
309
 
312
 
        return(buf_block_get_frame(block));
 
310
        return(page);
313
311
}
314
312
 
315
313
/**********************************************************************
323
321
        ulint           space,  /* in: space id */
324
322
        mtr_t*          mtr)    /* in: mtr */
325
323
{
326
 
        buf_block_t*    block;
 
324
        page_t* page;
327
325
 
328
326
        ut_a(space == 0);
329
327
        ut_ad(ibuf_inside());
330
328
 
331
329
        mtr_x_lock(dict_index_get_lock(data->index), mtr);
332
330
 
333
 
        block = buf_page_get(space, 0, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH,
334
 
                             mtr);
 
331
        page = buf_page_get(space, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH,
 
332
                            mtr);
335
333
#ifdef UNIV_SYNC_DEBUG
336
 
        buf_block_dbg_add_level(block, SYNC_TREE_NODE);
 
334
        buf_page_dbg_add_level(page, SYNC_TREE_NODE);
337
335
#endif /* UNIV_SYNC_DEBUG */
338
336
 
339
 
        return(buf_block_get_frame(block));
 
337
        return(page);
340
338
}
341
339
 
342
 
#ifdef UNIV_IBUF_COUNT_DEBUG
 
340
#ifdef UNIV_IBUF_DEBUG
343
341
/**********************************************************************
344
342
Gets the ibuf count for a given page. */
345
 
UNIV_INTERN
 
343
 
346
344
ulint
347
345
ibuf_count_get(
348
346
/*===========*/
376
374
/**********************************************************************
377
375
Creates the insert buffer data structure at a database startup and initializes
378
376
the data structures for the insert buffer. */
379
 
UNIV_INTERN
 
377
 
380
378
void
381
379
ibuf_init_at_db_start(void)
382
380
/*=======================*/
412
410
ibuf_data_sizes_update(
413
411
/*===================*/
414
412
        ibuf_data_t*    data,   /* in: ibuf data struct */
415
 
        const page_t*   root,   /* in: ibuf tree root */
 
413
        page_t*         root,   /* in: ibuf tree root */
416
414
        mtr_t*          mtr)    /* in: mtr */
417
415
{
418
416
        ulint   old_size;
452
450
root page of the insert buffer tree in the tablespace. This function can
453
451
be called only after the dictionary system has been initialized, as this
454
452
creates also the insert buffer table and index into this tablespace. */
455
 
UNIV_INTERN
 
453
 
456
454
ibuf_data_t*
457
455
ibuf_data_init_for_space(
458
456
/*=====================*/
469
467
        dict_table_t*   table;
470
468
        dict_index_t*   index;
471
469
        ulint           n_used;
472
 
        ulint           error;
473
470
 
474
471
        ut_a(space == 0);
475
472
 
481
478
 
482
479
        mutex_enter(&ibuf_mutex);
483
480
 
484
 
        mtr_x_lock(fil_space_get_latch(space, NULL), &mtr);
 
481
        mtr_x_lock(fil_space_get_latch(space), &mtr);
485
482
 
486
483
        header_page = ibuf_header_page_get(space, &mtr);
487
484
 
493
490
 
494
491
        data->seg_size = n_used;
495
492
 
496
 
        {
497
 
                buf_block_t*    block = buf_page_get(
498
 
                        space, 0, FSP_IBUF_TREE_ROOT_PAGE_NO,
499
 
                        RW_X_LATCH, &mtr);
 
493
        root = buf_page_get(space, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH,
 
494
                            &mtr);
500
495
#ifdef UNIV_SYNC_DEBUG
501
 
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
 
496
        buf_page_dbg_add_level(root, SYNC_TREE_NODE);
502
497
#endif /* UNIV_SYNC_DEBUG */
503
 
                root = buf_block_get_frame(block);
504
 
        }
505
498
 
506
499
        data->size = 0;
507
500
        data->n_inserts = 0;
548
541
 
549
542
        index->id = ut_dulint_add(DICT_IBUF_ID_MIN, space);
550
543
 
551
 
        error = dict_index_add_to_cache(table, index,
552
 
                                        FSP_IBUF_TREE_ROOT_PAGE_NO);
553
 
        ut_a(error == DB_SUCCESS);
 
544
        dict_index_add_to_cache(table, index, FSP_IBUF_TREE_ROOT_PAGE_NO);
554
545
 
555
546
        data->index = dict_table_get_first_index(table);
556
547
 
565
556
 
566
557
/*************************************************************************
567
558
Initializes an ibuf bitmap page. */
568
 
UNIV_INTERN
 
559
 
569
560
void
570
561
ibuf_bitmap_page_init(
571
562
/*==================*/
572
 
        buf_block_t*    block,  /* in: bitmap page */
573
 
        mtr_t*          mtr)    /* in: mtr */
 
563
        page_t* page,   /* in: bitmap page */
 
564
        mtr_t*  mtr)    /* in: mtr */
574
565
{
575
 
        page_t* page;
 
566
        ulint   bit_offset;
576
567
        ulint   byte_offset;
577
 
        ulint   zip_size = buf_block_get_zip_size(block);
578
 
 
579
 
        ut_a(ut_is_2pow(zip_size));
580
 
 
581
 
        page = buf_block_get_frame(block);
 
568
 
 
569
        /* Write all zeros to the bitmap */
 
570
 
 
571
        bit_offset = XDES_DESCRIBED_PER_PAGE * IBUF_BITS_PER_PAGE;
 
572
 
 
573
        byte_offset = bit_offset / 8 + 1;
 
574
        /* better: byte_offset = UT_BITS_IN_BYTES(bit_offset); */
 
575
 
582
576
        fil_page_set_type(page, FIL_PAGE_IBUF_BITMAP);
583
577
 
584
 
        /* Write all zeros to the bitmap */
585
 
 
586
 
        if (!zip_size) {
587
 
                byte_offset = UT_BITS_IN_BYTES(UNIV_PAGE_SIZE
588
 
                                               * IBUF_BITS_PER_PAGE);
589
 
        } else {
590
 
                byte_offset = UT_BITS_IN_BYTES(zip_size * IBUF_BITS_PER_PAGE);
591
 
        }
592
 
 
593
578
        memset(page + IBUF_BITMAP, 0, byte_offset);
594
579
 
595
580
        /* The remaining area (up to the page trailer) is uninitialized. */
599
584
 
600
585
/*************************************************************************
601
586
Parses a redo log record of an ibuf bitmap page init. */
602
 
UNIV_INTERN
 
587
 
603
588
byte*
604
589
ibuf_parse_bitmap_init(
605
590
/*===================*/
606
 
                                /* out: end of log record or NULL */
607
 
        byte*           ptr,    /* in: buffer */
608
 
        byte*           end_ptr __attribute__((unused)), /* in: buffer end */
609
 
        buf_block_t*    block,  /* in: block or NULL */
610
 
        mtr_t*          mtr)    /* in: mtr or NULL */
 
591
                        /* out: end of log record or NULL */
 
592
        byte*   ptr,    /* in: buffer */
 
593
        byte*   end_ptr __attribute__((unused)), /* in: buffer end */
 
594
        page_t* page,   /* in: page or NULL */
 
595
        mtr_t*  mtr)    /* in: mtr or NULL */
611
596
{
612
597
        ut_ad(ptr && end_ptr);
613
598
 
614
 
        if (block) {
615
 
                ibuf_bitmap_page_init(block, mtr);
 
599
        if (page) {
 
600
                ibuf_bitmap_page_init(page, mtr);
616
601
        }
617
602
 
618
603
        return(ptr);
624
609
ulint
625
610
ibuf_bitmap_page_get_bits(
626
611
/*======================*/
627
 
                                /* out: value of bits */
628
 
        const page_t*   page,   /* in: bitmap page */
629
 
        ulint           page_no,/* in: page whose bits to get */
630
 
        ulint           zip_size,/* in: compressed page size in bytes;
631
 
                                0 for uncompressed pages */
632
 
        ulint           bit,    /* in: IBUF_BITMAP_FREE,
633
 
                                IBUF_BITMAP_BUFFERED, ... */
634
 
        mtr_t*          mtr __attribute__((unused)))
635
 
                                /* in: mtr containing an
636
 
                                x-latch to the bitmap page */
 
612
                        /* out: value of bits */
 
613
        page_t* page,   /* in: bitmap page */
 
614
        ulint   page_no,/* in: page whose bits to get */
 
615
        ulint   bit,    /* in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */
 
616
        mtr_t*  mtr __attribute__((unused)))    /* in: mtr containing an
 
617
                                                x-latch to the bitmap
 
618
                                                page */
637
619
{
638
620
        ulint   byte_offset;
639
621
        ulint   bit_offset;
644
626
#if IBUF_BITS_PER_PAGE % 2
645
627
# error "IBUF_BITS_PER_PAGE % 2 != 0"
646
628
#endif
647
 
        ut_ad(ut_is_2pow(zip_size));
648
 
        ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
 
629
        ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
 
630
                                MTR_MEMO_PAGE_X_FIX));
649
631
 
650
 
        if (!zip_size) {
651
 
                bit_offset = (page_no % UNIV_PAGE_SIZE) * IBUF_BITS_PER_PAGE
652
 
                        + bit;
653
 
        } else {
654
 
                bit_offset = (page_no & (zip_size - 1)) * IBUF_BITS_PER_PAGE
655
 
                        + bit;
656
 
        }
 
632
        bit_offset = (page_no % XDES_DESCRIBED_PER_PAGE) * IBUF_BITS_PER_PAGE
 
633
                + bit;
657
634
 
658
635
        byte_offset = bit_offset / 8;
659
636
        bit_offset = bit_offset % 8;
681
658
/*======================*/
682
659
        page_t* page,   /* in: bitmap page */
683
660
        ulint   page_no,/* in: page whose bits to set */
684
 
        ulint   zip_size,/* in: compressed page size in bytes;
685
 
                        0 for uncompressed pages */
686
661
        ulint   bit,    /* in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */
687
662
        ulint   val,    /* in: value to set */
688
663
        mtr_t*  mtr)    /* in: mtr containing an x-latch to the bitmap page */
695
670
#if IBUF_BITS_PER_PAGE % 2
696
671
# error "IBUF_BITS_PER_PAGE % 2 != 0"
697
672
#endif
698
 
        ut_ad(ut_is_2pow(zip_size));
699
 
        ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
700
 
#ifdef UNIV_IBUF_COUNT_DEBUG
 
673
        ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
 
674
                                MTR_MEMO_PAGE_X_FIX));
 
675
#ifdef UNIV_IBUF_DEBUG
701
676
        ut_a((bit != IBUF_BITMAP_BUFFERED) || (val != FALSE)
702
 
             || (0 == ibuf_count_get(page_get_space_id(page),
 
677
             || (0 == ibuf_count_get(buf_frame_get_space_id(page),
703
678
                                     page_no)));
704
679
#endif
705
 
        if (!zip_size) {
706
 
                bit_offset = (page_no % UNIV_PAGE_SIZE) * IBUF_BITS_PER_PAGE
707
 
                        + bit;
708
 
        } else {
709
 
                bit_offset = (page_no & (zip_size - 1)) * IBUF_BITS_PER_PAGE
710
 
                        + bit;
711
 
        }
 
680
        bit_offset = (page_no % XDES_DESCRIBED_PER_PAGE) * IBUF_BITS_PER_PAGE
 
681
                + bit;
712
682
 
713
683
        byte_offset = bit_offset / 8;
714
684
        bit_offset = bit_offset % 8;
740
710
/*=====================*/
741
711
                                /* out: the bitmap page number where
742
712
                                the file page is mapped */
743
 
        ulint   zip_size,       /* in: compressed page size in bytes;
744
 
                                0 for uncompressed pages */
745
713
        ulint   page_no)        /* in: tablespace page number */
746
714
{
747
 
        ut_ad(ut_is_2pow(zip_size));
748
 
 
749
 
        if (!zip_size) {
750
 
                return(FSP_IBUF_BITMAP_OFFSET
751
 
                       + (page_no & ~(UNIV_PAGE_SIZE - 1)));
752
 
        } else {
753
 
                return(FSP_IBUF_BITMAP_OFFSET
754
 
                       + (page_no & ~(zip_size - 1)));
755
 
        }
 
715
        return(FSP_IBUF_BITMAP_OFFSET
 
716
               + XDES_DESCRIBED_PER_PAGE
 
717
               * (page_no / XDES_DESCRIBED_PER_PAGE));
756
718
}
757
719
 
758
720
/************************************************************************
768
730
                        x-latched */
769
731
        ulint   space,  /* in: space id of the file page */
770
732
        ulint   page_no,/* in: page number of the file page */
771
 
        ulint   zip_size,/* in: compressed page size in bytes;
772
 
                        0 for uncompressed pages */
773
733
        mtr_t*  mtr)    /* in: mtr */
774
734
{
775
 
        buf_block_t*    block;
 
735
        page_t* page;
776
736
 
777
 
        block = buf_page_get(space, zip_size,
778
 
                             ibuf_bitmap_page_no_calc(zip_size, page_no),
779
 
                             RW_X_LATCH, mtr);
 
737
        page = buf_page_get(space, ibuf_bitmap_page_no_calc(page_no),
 
738
                            RW_X_LATCH, mtr);
780
739
#ifdef UNIV_SYNC_DEBUG
781
 
        buf_block_dbg_add_level(block, SYNC_IBUF_BITMAP);
 
740
        buf_page_dbg_add_level(page, SYNC_IBUF_BITMAP);
782
741
#endif /* UNIV_SYNC_DEBUG */
783
742
 
784
 
        return(buf_block_get_frame(block));
 
743
        return(page);
785
744
}
786
745
 
787
746
/****************************************************************************
793
752
void
794
753
ibuf_set_free_bits_low(
795
754
/*===================*/
796
 
        ulint                   zip_size,/* in: compressed page size in bytes;
797
 
                                        0 for uncompressed pages */
798
 
        const buf_block_t*      block,  /* in: index page; free bits are set if
799
 
                                        the index is non-clustered and page
800
 
                                        level is 0 */
801
 
        ulint                   val,    /* in: value to set: < 4 */
802
 
        mtr_t*                  mtr)    /* in/out: mtr */
 
755
        ulint   type,   /* in: index type */
 
756
        page_t* page,   /* in: index page; free bit is set if the index is
 
757
                        non-clustered and page level is 0 */
 
758
        ulint   val,    /* in: value to set: < 4 */
 
759
        mtr_t*  mtr)    /* in: mtr */
803
760
{
804
761
        page_t* bitmap_page;
805
 
        ulint   space;
806
 
        ulint   page_no;
807
 
 
808
 
        if (!page_is_leaf(buf_block_get_frame(block))) {
809
 
 
810
 
                return;
811
 
        }
812
 
 
813
 
        space = buf_block_get_space(block);
814
 
        page_no = buf_block_get_page_no(block);
815
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
 
762
 
 
763
        if (type & DICT_CLUSTERED) {
 
764
 
 
765
                return;
 
766
        }
 
767
 
 
768
        if (btr_page_get_level_low(page) != 0) {
 
769
 
 
770
                return;
 
771
        }
 
772
 
 
773
        bitmap_page = ibuf_bitmap_get_map_page(
 
774
                buf_frame_get_space_id(page),
 
775
                buf_frame_get_page_no(page), mtr);
816
776
#ifdef UNIV_IBUF_DEBUG
817
777
# if 0
818
778
        fprintf(stderr,
819
 
                "Setting space %lu page %lu free bits to %lu should be %lu\n",
820
 
                space, page_no, val,
821
 
                ibuf_index_page_calc_free(zip_size, block));
 
779
                "Setting page no %lu free bits to %lu should be %lu\n",
 
780
                buf_frame_get_page_no(page), val,
 
781
                ibuf_index_page_calc_free(page));
822
782
# endif
823
783
 
824
 
        ut_a(val <= ibuf_index_page_calc_free(zip_size, block));
 
784
        ut_a(val <= ibuf_index_page_calc_free(page));
825
785
#endif /* UNIV_IBUF_DEBUG */
826
 
        ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
 
786
        ibuf_bitmap_page_set_bits(bitmap_page, buf_frame_get_page_no(page),
827
787
                                  IBUF_BITMAP_FREE, val, mtr);
 
788
 
828
789
}
829
790
 
830
791
/****************************************************************************
832
793
mini-transaction, hence this operation does not restrict further work to only
833
794
ibuf bitmap operations, which would result if the latch to the bitmap page
834
795
were kept. */
835
 
UNIV_INTERN
 
796
 
836
797
void
837
 
ibuf_set_free_bits_func(
838
 
/*====================*/
839
 
        buf_block_t*    block,  /* in: index page of a non-clustered index;
840
 
                                free bit is reset if page level is 0 */
841
 
#ifdef UNIV_IBUF_DEBUG
842
 
        ulint           max_val,/* in: ULINT_UNDEFINED or a maximum
843
 
                                value which the bits must have before
844
 
                                setting; this is for debugging */
845
 
#endif /* UNIV_IBUF_DEBUG */
846
 
        ulint           val)    /* in: value to set: < 4 */
 
798
ibuf_set_free_bits(
 
799
/*===============*/
 
800
        ulint   type,   /* in: index type */
 
801
        page_t* page,   /* in: index page; free bit is set if the index is
 
802
                        non-clustered and page level is 0 */
 
803
        ulint   val,    /* in: value to set: < 4 */
 
804
        ulint   max_val)/* in: ULINT_UNDEFINED or a maximum value which
 
805
                        the bits must have before setting; this is for
 
806
                        debugging */
847
807
{
848
808
        mtr_t   mtr;
849
 
        page_t* page;
850
809
        page_t* bitmap_page;
851
 
        ulint   space;
852
 
        ulint   page_no;
853
 
        ulint   zip_size;
854
 
 
855
 
        page = buf_block_get_frame(block);
856
 
 
857
 
        if (!page_is_leaf(page)) {
 
810
 
 
811
        if (type & DICT_CLUSTERED) {
 
812
 
 
813
                return;
 
814
        }
 
815
 
 
816
        if (btr_page_get_level_low(page) != 0) {
858
817
 
859
818
                return;
860
819
        }
861
820
 
862
821
        mtr_start(&mtr);
863
822
 
864
 
        space = buf_block_get_space(block);
865
 
        page_no = buf_block_get_page_no(block);
866
 
        zip_size = buf_block_get_zip_size(block);
867
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, &mtr);
 
823
        bitmap_page = ibuf_bitmap_get_map_page(
 
824
                buf_frame_get_space_id(page), buf_frame_get_page_no(page),
 
825
                &mtr);
868
826
 
869
 
#ifdef UNIV_IBUF_DEBUG
870
827
        if (max_val != ULINT_UNDEFINED) {
 
828
#ifdef UNIV_IBUF_DEBUG
871
829
                ulint   old_val;
872
830
 
873
831
                old_val = ibuf_bitmap_page_get_bits(
874
 
                        bitmap_page, page_no, zip_size,
 
832
                        bitmap_page, buf_frame_get_page_no(page),
875
833
                        IBUF_BITMAP_FREE, &mtr);
876
834
# if 0
877
835
                if (old_val != max_val) {
878
836
                        fprintf(stderr,
879
837
                                "Ibuf: page %lu old val %lu max val %lu\n",
880
 
                                page_get_page_no(page),
 
838
                                buf_frame_get_page_no(page),
881
839
                                old_val, max_val);
882
840
                }
883
841
# endif
884
842
 
885
843
                ut_a(old_val <= max_val);
 
844
#endif
886
845
        }
 
846
#ifdef UNIV_IBUF_DEBUG
887
847
# if 0
888
848
        fprintf(stderr, "Setting page no %lu free bits to %lu should be %lu\n",
889
 
                page_get_page_no(page), val,
890
 
                ibuf_index_page_calc_free(zip_size, block));
 
849
                buf_frame_get_page_no(page), val,
 
850
                ibuf_index_page_calc_free(page));
891
851
# endif
892
852
 
893
 
        ut_a(val <= ibuf_index_page_calc_free(zip_size, block));
894
 
#endif /* UNIV_IBUF_DEBUG */
895
 
        ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
 
853
        ut_a(val <= ibuf_index_page_calc_free(page));
 
854
#endif
 
855
        ibuf_bitmap_page_set_bits(bitmap_page, buf_frame_get_page_no(page),
896
856
                                  IBUF_BITMAP_FREE, val, &mtr);
897
857
        mtr_commit(&mtr);
898
858
}
902
862
separate mini-transaction, hence this operation does not restrict further
903
863
work to only ibuf bitmap operations, which would result if the latch to the
904
864
bitmap page were kept. */
905
 
UNIV_INTERN
 
865
 
 
866
void
 
867
ibuf_reset_free_bits_with_type(
 
868
/*===========================*/
 
869
        ulint   type,   /* in: index type */
 
870
        page_t* page)   /* in: index page; free bits are set to 0 if the index
 
871
                        is non-clustered and non-unique and the page level is
 
872
                        0 */
 
873
{
 
874
        ibuf_set_free_bits(type, page, 0, ULINT_UNDEFINED);
 
875
}
 
876
 
 
877
/****************************************************************************
 
878
Resets the free bits of the page in the ibuf bitmap. This is done in a
 
879
separate mini-transaction, hence this operation does not restrict further
 
880
work to solely ibuf bitmap operations, which would result if the latch to
 
881
the bitmap page were kept. */
 
882
 
906
883
void
907
884
ibuf_reset_free_bits(
908
885
/*=================*/
909
 
        buf_block_t*    block)  /* in: index page; free bits are set to 0
910
 
                                if the index is a non-clustered
911
 
                                non-unique, and page level is 0 */
 
886
        dict_index_t*   index,  /* in: index */
 
887
        page_t*         page)   /* in: index page; free bits are set to 0 if
 
888
                                the index is non-clustered and non-unique and
 
889
                                the page level is 0 */
912
890
{
913
 
        ibuf_set_free_bits(block, 0, ULINT_UNDEFINED);
 
891
        ibuf_set_free_bits(index->type, page, 0, ULINT_UNDEFINED);
914
892
}
915
893
 
916
894
/**************************************************************************
917
 
Updates the free bits for an uncompressed page to reflect the present state.
918
 
Does this in the mtr given, which means that the latching order rules virtually
919
 
prevent any further operations for this OS thread until mtr is committed. */
920
 
UNIV_INTERN
 
895
Updates the free bits for a page to reflect the present state. Does this
 
896
in the mtr given, which means that the latching order rules virtually prevent
 
897
any further operations for this OS thread until mtr is committed. */
 
898
 
921
899
void
922
900
ibuf_update_free_bits_low(
923
901
/*======================*/
924
 
        const buf_block_t*      block,          /* in: index page */
925
 
        ulint                   max_ins_size,   /* in: value of
926
 
                                                maximum insert size
927
 
                                                with reorganize before
928
 
                                                the latest operation
929
 
                                                performed to the page */
930
 
        mtr_t*                  mtr)            /* in/out: mtr */
 
902
        dict_index_t*   index,          /* in: index */
 
903
        page_t*         page,           /* in: index page */
 
904
        ulint           max_ins_size,   /* in: value of maximum insert size
 
905
                                        with reorganize before the latest
 
906
                                        operation performed to the page */
 
907
        mtr_t*          mtr)            /* in: mtr */
931
908
{
932
909
        ulint   before;
933
910
        ulint   after;
934
911
 
935
 
        ut_a(!buf_block_get_page_zip(block));
936
 
 
937
 
        before = ibuf_index_page_calc_free_bits(0, max_ins_size);
938
 
 
939
 
        after = ibuf_index_page_calc_free(0, block);
940
 
 
941
 
        /* This approach cannot be used on compressed pages, since the
942
 
        computed value of "before" often does not match the current
943
 
        state of the bitmap.  This is because the free space may
944
 
        increase or decrease when a compressed page is reorganized. */
 
912
        before = ibuf_index_page_calc_free_bits(max_ins_size);
 
913
 
 
914
        after = ibuf_index_page_calc_free(page);
 
915
 
945
916
        if (before != after) {
946
 
                ibuf_set_free_bits_low(0, block, after, mtr);
947
 
        }
948
 
}
949
 
 
950
 
/**************************************************************************
951
 
Updates the free bits for a compressed page to reflect the present state.
952
 
Does this in the mtr given, which means that the latching order rules virtually
953
 
prevent any further operations for this OS thread until mtr is committed. */
954
 
UNIV_INTERN
955
 
void
956
 
ibuf_update_free_bits_zip(
957
 
/*======================*/
958
 
        buf_block_t*    block,  /* in/out: index page */
959
 
        mtr_t*          mtr)    /* in/out: mtr */
960
 
{
961
 
        page_t* bitmap_page;
962
 
        ulint   space;
963
 
        ulint   page_no;
964
 
        ulint   zip_size;
965
 
        ulint   after;
966
 
 
967
 
        space = buf_block_get_space(block);
968
 
        page_no = buf_block_get_page_no(block);
969
 
        zip_size = buf_block_get_zip_size(block);
970
 
 
971
 
        ut_a(page_is_leaf(buf_block_get_frame(block)));
972
 
        ut_a(zip_size);
973
 
 
974
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
975
 
 
976
 
        after = ibuf_index_page_calc_free_zip(zip_size, block);
977
 
 
978
 
        if (after == 0) {
979
 
                /* We move the page to the front of the buffer pool LRU list:
980
 
                the purpose of this is to prevent those pages to which we
981
 
                cannot make inserts using the insert buffer from slipping
982
 
                out of the buffer pool */
983
 
 
984
 
                buf_page_make_young(&block->page);
985
 
        }
986
 
 
987
 
        ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
988
 
                                  IBUF_BITMAP_FREE, after, mtr);
 
917
                ibuf_set_free_bits_low(index->type, page, after, mtr);
 
918
        }
989
919
}
990
920
 
991
921
/**************************************************************************
992
922
Updates the free bits for the two pages to reflect the present state. Does
993
923
this in the mtr given, which means that the latching order rules virtually
994
924
prevent any further operations until mtr is committed. */
995
 
UNIV_INTERN
 
925
 
996
926
void
997
927
ibuf_update_free_bits_for_two_pages_low(
998
928
/*====================================*/
999
 
        ulint           zip_size,/* in: compressed page size in bytes;
1000
 
                                0 for uncompressed pages */
1001
 
        buf_block_t*    block1, /* in: index page */
1002
 
        buf_block_t*    block2, /* in: index page */
 
929
        dict_index_t*   index,  /* in: index */
 
930
        page_t*         page1,  /* in: index page */
 
931
        page_t*         page2,  /* in: index page */
1003
932
        mtr_t*          mtr)    /* in: mtr */
1004
933
{
1005
934
        ulint   state;
1010
939
 
1011
940
        mutex_enter(&ibuf_bitmap_mutex);
1012
941
 
1013
 
        state = ibuf_index_page_calc_free(zip_size, block1);
1014
 
 
1015
 
        ibuf_set_free_bits_low(zip_size, block1, state, mtr);
1016
 
 
1017
 
        state = ibuf_index_page_calc_free(zip_size, block2);
1018
 
 
1019
 
        ibuf_set_free_bits_low(zip_size, block2, state, mtr);
 
942
        state = ibuf_index_page_calc_free(page1);
 
943
 
 
944
        ibuf_set_free_bits_low(index->type, page1, state, mtr);
 
945
 
 
946
        state = ibuf_index_page_calc_free(page2);
 
947
 
 
948
        ibuf_set_free_bits_low(index->type, page2, state, mtr);
1020
949
 
1021
950
        mutex_exit(&ibuf_bitmap_mutex);
1022
951
}
1029
958
/*=================*/
1030
959
                        /* out: TRUE if a fixed address ibuf i/o page */
1031
960
        ulint   space,  /* in: space id */
1032
 
        ulint   zip_size,/* in: compressed page size in bytes;
1033
 
                        0 for uncompressed pages */
1034
961
        ulint   page_no)/* in: page number */
1035
962
{
1036
963
        return((space == 0 && page_no == IBUF_TREE_ROOT_PAGE_NO)
1037
 
               || ibuf_bitmap_page(zip_size, page_no));
 
964
               || ibuf_bitmap_page(page_no));
1038
965
}
1039
966
 
1040
967
/***************************************************************************
1041
968
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages. */
1042
 
UNIV_INTERN
 
969
 
1043
970
ibool
1044
971
ibuf_page(
1045
972
/*======*/
1046
973
                        /* out: TRUE if level 2 or level 3 page */
1047
974
        ulint   space,  /* in: space id */
1048
 
        ulint   zip_size,/* in: compressed page size in bytes, or 0 */
1049
975
        ulint   page_no)/* in: page number */
1050
976
{
1051
977
        page_t* bitmap_page;
1059
985
                return(FALSE);
1060
986
        }
1061
987
 
1062
 
        if (ibuf_fixed_addr_page(space, zip_size, page_no)) {
 
988
        if (ibuf_fixed_addr_page(space, page_no)) {
1063
989
 
1064
990
                return(TRUE);
1065
991
        }
1074
1000
 
1075
1001
        mtr_start(&mtr);
1076
1002
 
1077
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, &mtr);
 
1003
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr);
1078
1004
 
1079
 
        ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
1080
 
                                        IBUF_BITMAP_IBUF, &mtr);
 
1005
        ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,
 
1006
                                        &mtr);
1081
1007
        mtr_commit(&mtr);
1082
1008
 
1083
1009
        return(ret);
1085
1011
 
1086
1012
/***************************************************************************
1087
1013
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages. */
1088
 
UNIV_INTERN
 
1014
 
1089
1015
ibool
1090
1016
ibuf_page_low(
1091
1017
/*==========*/
1092
1018
                        /* out: TRUE if level 2 or level 3 page */
1093
1019
        ulint   space,  /* in: space id */
1094
 
        ulint   zip_size,/* in: compressed page size in bytes, or 0 */
1095
1020
        ulint   page_no,/* in: page number */
1096
1021
        mtr_t*  mtr)    /* in: mtr which will contain an x-latch to the
1097
1022
                        bitmap page if the page is not one of the fixed
1098
1023
                        address ibuf pages */
1099
1024
{
1100
1025
        page_t* bitmap_page;
 
1026
        ibool   ret;
1101
1027
 
1102
 
        if (ibuf_fixed_addr_page(space, zip_size, page_no)) {
 
1028
        if (ibuf_fixed_addr_page(space, page_no)) {
1103
1029
 
1104
1030
                return(TRUE);
1105
1031
        }
1106
1032
 
1107
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
 
1033
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, mtr);
1108
1034
 
1109
 
        return(ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
1110
 
                                         IBUF_BITMAP_IBUF, mtr));
 
1035
        ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,
 
1036
                                        mtr);
 
1037
        return(ret);
1111
1038
}
1112
1039
 
1113
1040
/************************************************************************
1116
1043
ulint
1117
1044
ibuf_rec_get_page_no(
1118
1045
/*=================*/
1119
 
                                /* out: page number */
1120
 
        const rec_t*    rec)    /* in: ibuf record */
 
1046
                        /* out: page number */
 
1047
        rec_t*  rec)    /* in: ibuf record */
1121
1048
{
1122
 
        const byte*     field;
1123
 
        ulint           len;
 
1049
        byte*   field;
 
1050
        ulint   len;
1124
1051
 
1125
1052
        ut_ad(ibuf_inside());
1126
1053
        ut_ad(rec_get_n_fields_old(rec) > 2);
1151
1078
ulint
1152
1079
ibuf_rec_get_space(
1153
1080
/*===============*/
1154
 
                                /* out: space id */
1155
 
        const rec_t*    rec)    /* in: ibuf record */
 
1081
                        /* out: space id */
 
1082
        rec_t*  rec)    /* in: ibuf record */
1156
1083
{
1157
 
        const byte*     field;
1158
 
        ulint           len;
 
1084
        byte*   field;
 
1085
        ulint   len;
1159
1086
 
1160
1087
        ut_ad(ibuf_inside());
1161
1088
        ut_ad(rec_get_n_fields_old(rec) > 2);
1213
1140
ibuf_dummy_index_add_col(
1214
1141
/*=====================*/
1215
1142
        dict_index_t*   index,  /* in: dummy index */
1216
 
        const dtype_t*  type,   /* in: the data type of the column */
 
1143
        dtype_t*        type,   /* in: the data type of the column */
1217
1144
        ulint           len)    /* in: length of the column */
1218
1145
{
1219
1146
        ulint   i       = index->table->n_def;
1221
1148
                               dtype_get_mtype(type),
1222
1149
                               dtype_get_prtype(type),
1223
1150
                               dtype_get_len(type));
1224
 
        dict_index_add_col(index, index->table,
 
1151
        dict_index_add_col(index, index->table, (dict_col_t*)
1225
1152
                           dict_table_get_nth_col(index->table, i), len);
1226
1153
}
1227
1154
/************************************************************************
1252
1179
                                        ibuf_rec, the caller must hold a
1253
1180
                                        latch to the ibuf_rec page as long
1254
1181
                                        as the entry is used! */
1255
 
        const rec_t*    ibuf_rec,       /* in: record in an insert buffer */
 
1182
        rec_t*          ibuf_rec,       /* in: record in an insert buffer */
1256
1183
        mem_heap_t*     heap,           /* in: heap where built */
1257
1184
        dict_index_t**  pindex)         /* out, own: dummy index that
1258
1185
                                        describes the entry */
1260
1187
        dtuple_t*       tuple;
1261
1188
        dfield_t*       field;
1262
1189
        ulint           n_fields;
1263
 
        const byte*     types;
 
1190
        byte*           types;
1264
1191
        const byte*     data;
1265
1192
        ulint           len;
1266
1193
        ulint           i;
1335
1262
                ibuf_dummy_index_add_col(index, dfield_get_type(field), len);
1336
1263
        }
1337
1264
 
1338
 
        /* Prevent an ut_ad() failure in page_zip_write_rec() by
1339
 
        adding system columns to the dummy table pointed to by the
1340
 
        dummy secondary index.  The insert buffer is only used for
1341
 
        secondary indexes, whose records never contain any system
1342
 
        columns, such as DB_TRX_ID. */
1343
 
        ut_d(dict_table_add_system_columns(index->table, index->table->heap));
1344
 
 
1345
1265
        *pindex = index;
1346
1266
        return(tuple);
1347
1267
}
1353
1273
ulint
1354
1274
ibuf_rec_get_volume(
1355
1275
/*================*/
1356
 
                                /* out: size of index record in bytes
1357
 
                                + an upper limit of the space taken in the
1358
 
                                page directory */
1359
 
        const rec_t*    ibuf_rec)/* in: ibuf record */
 
1276
                        /* out: size of index record in bytes + an upper
 
1277
                        limit of the space taken in the page directory */
 
1278
        rec_t*  ibuf_rec)/* in: ibuf record */
1360
1279
{
1361
 
        dtype_t         dtype;
1362
 
        ibool           new_format      = FALSE;
1363
 
        ulint           data_size       = 0;
1364
 
        ulint           n_fields;
1365
 
        const byte*     types;
1366
 
        const byte*     data;
1367
 
        ulint           len;
1368
 
        ulint           i;
 
1280
        dtype_t dtype;
 
1281
        ibool   new_format      = FALSE;
 
1282
        ulint   data_size       = 0;
 
1283
        ulint   n_fields;
 
1284
        byte*   types;
 
1285
        byte*   data;
 
1286
        ulint   len;
 
1287
        ulint   i;
1369
1288
 
1370
1289
        ut_ad(ibuf_inside());
1371
1290
        ut_ad(rec_get_n_fields_old(ibuf_rec) > 2);
1399
1318
                        mem_heap_t*     heap = mem_heap_create(500);
1400
1319
                        dtuple_t*       entry = ibuf_build_entry_from_ibuf_rec(
1401
1320
                                ibuf_rec, heap, &dummy_index);
1402
 
                        volume = rec_get_converted_size(dummy_index, entry, 0);
 
1321
                        volume = rec_get_converted_size(dummy_index, entry);
1403
1322
                        ibuf_dummy_index_free(dummy_index);
1404
1323
                        mem_heap_free(heap);
1405
1324
                        return(volume + page_dir_calc_reserved_space(1));
1432
1351
                }
1433
1352
        }
1434
1353
 
1435
 
        return(data_size + rec_get_converted_extra_size(data_size, n_fields, 0)
 
1354
        return(data_size + rec_get_converted_extra_size(data_size, n_fields)
1436
1355
               + page_dir_calc_reserved_space(1));
1437
1356
}
1438
1357
 
1448
1367
                                must be kept because we copy pointers to its
1449
1368
                                fields */
1450
1369
        dict_index_t*   index,  /* in: non-clustered index */
1451
 
        const dtuple_t* entry,  /* in: entry for a non-clustered index */
 
1370
        dtuple_t*       entry,  /* in: entry for a non-clustered index */
1452
1371
        ulint           space,  /* in: space id */
1453
1372
        ulint           page_no,/* in: index page number where entry should
1454
1373
                                be inserted */
1456
1375
{
1457
1376
        dtuple_t*       tuple;
1458
1377
        dfield_t*       field;
1459
 
        const dfield_t* entry_field;
 
1378
        dfield_t*       entry_field;
1460
1379
        ulint           n_fields;
1461
1380
        byte*           buf;
1462
1381
        byte*           buf2;
1542
1461
#ifdef UNIV_DEBUG
1543
1462
                if (fixed_len) {
1544
1463
                        /* dict_index_add_col() should guarantee these */
1545
 
                        ut_ad(fixed_len <= (ulint)
1546
 
                              dfield_get_type(entry_field)->len);
 
1464
                        ut_ad(fixed_len <= (ulint) entry_field->type.len);
1547
1465
                        if (ifield->prefix_len) {
1548
1466
                                ut_ad(ifield->prefix_len == fixed_len);
1549
1467
                        } else {
1550
 
                                ut_ad(fixed_len == (ulint)
1551
 
                                      dfield_get_type(entry_field)->len);
 
1468
                                ut_ad(fixed_len
 
1469
                                      == (ulint) entry_field->type.len);
1552
1470
                        }
1553
1471
                }
1554
1472
#endif /* UNIV_DEBUG */
1686
1604
        inserts buffered for pages that we read to the buffer pool, without
1687
1605
        any risk of running out of free space in the insert buffer. */
1688
1606
 
1689
 
        return(data->free_list_len >= data->size / 2 + 3 * data->height);
 
1607
        if (data->free_list_len >= data->size / 2 + 3 * data->height) {
 
1608
 
 
1609
                return(TRUE);
 
1610
        }
 
1611
 
 
1612
        return(FALSE);
1690
1613
}
1691
1614
 
1692
1615
/*************************************************************************
1718
1641
{
1719
1642
        mtr_t   mtr;
1720
1643
        page_t* header_page;
1721
 
        ulint   flags;
1722
 
        ulint   zip_size;
1723
1644
        ulint   page_no;
1724
1645
        page_t* page;
1725
1646
        page_t* root;
1731
1652
 
1732
1653
        /* Acquire the fsp latch before the ibuf header, obeying the latching
1733
1654
        order */
1734
 
        mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
1735
 
        zip_size = dict_table_flags_to_zip_size(flags);
 
1655
        mtr_x_lock(fil_space_get_latch(space), &mtr);
1736
1656
 
1737
1657
        header_page = ibuf_header_page_get(space, &mtr);
1738
1658
 
1755
1675
                return(DB_STRONG_FAIL);
1756
1676
        }
1757
1677
 
1758
 
        {
1759
 
                buf_block_t*    block = buf_page_get(
1760
 
                        space, 0, page_no, RW_X_LATCH, &mtr);
 
1678
        page = buf_page_get(space, page_no, RW_X_LATCH, &mtr);
 
1679
 
1761
1680
#ifdef UNIV_SYNC_DEBUG
1762
 
                buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
 
1681
        buf_page_dbg_add_level(page, SYNC_TREE_NODE_NEW);
1763
1682
#endif /* UNIV_SYNC_DEBUG */
1764
 
                page = buf_block_get_frame(block);
1765
 
        }
1766
1683
 
1767
1684
        ibuf_enter();
1768
1685
 
1784
1701
        /* Set the bit indicating that this page is now an ibuf tree page
1785
1702
        (level 2 page) */
1786
1703
 
1787
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, &mtr);
 
1704
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr);
1788
1705
 
1789
 
        ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
1790
 
                                  IBUF_BITMAP_IBUF, TRUE, &mtr);
 
1706
        ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,
 
1707
                                  TRUE, &mtr);
1791
1708
        mtr_commit(&mtr);
1792
1709
 
1793
1710
        mutex_exit(&ibuf_mutex);
1809
1726
        mtr_t   mtr;
1810
1727
        mtr_t   mtr2;
1811
1728
        page_t* header_page;
1812
 
        ulint   flags;
1813
 
        ulint   zip_size;
1814
1729
        ulint   page_no;
1815
1730
        page_t* page;
1816
1731
        page_t* root;
1822
1737
 
1823
1738
        /* Acquire the fsp latch before the ibuf header, obeying the latching
1824
1739
        order */
1825
 
        mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
1826
 
        zip_size = dict_table_flags_to_zip_size(flags);
 
1740
        mtr_x_lock(fil_space_get_latch(space), &mtr);
1827
1741
 
1828
1742
        header_page = ibuf_header_page_get(space, &mtr);
1829
1743
 
1885
1799
                                       + PAGE_BTR_IBUF_FREE_LIST, &mtr)
1886
1800
              .page);
1887
1801
 
1888
 
        {
1889
 
                buf_block_t*    block = buf_page_get(
1890
 
                        space, 0, page_no, RW_X_LATCH, &mtr);
 
1802
        page = buf_page_get(space, page_no, RW_X_LATCH, &mtr);
 
1803
 
1891
1804
#ifdef UNIV_SYNC_DEBUG
1892
 
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
 
1805
        buf_page_dbg_add_level(page, SYNC_TREE_NODE);
1893
1806
#endif /* UNIV_SYNC_DEBUG */
1894
 
                page = buf_block_get_frame(block);
1895
 
        }
1896
1807
 
1897
1808
        /* Remove the page from the free list and update the ibuf size data */
1898
1809
 
1907
1818
        /* Set the bit indicating that this page is no more an ibuf tree page
1908
1819
        (level 2 page) */
1909
1820
 
1910
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, &mtr);
 
1821
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr);
1911
1822
 
1912
 
        ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
1913
 
                                  IBUF_BITMAP_IBUF, FALSE, &mtr);
 
1823
        ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,
 
1824
                                  FALSE, &mtr);
1914
1825
#ifdef UNIV_DEBUG_FILE_ACCESSES
1915
1826
        buf_page_set_file_page_was_freed(space, page_no);
1916
1827
#endif
1925
1836
Frees excess pages from the ibuf free list. This function is called when an OS
1926
1837
thread calls fsp services to allocate a new file segment, or a new page to a
1927
1838
file segment, and the thread did not own the fsp latch before this call. */
1928
 
UNIV_INTERN
 
1839
 
1929
1840
void
1930
1841
ibuf_free_excess_pages(
1931
1842
/*===================*/
1932
 
        ulint   space)  /* in: compressed page size in bytes, or 0 */
 
1843
        ulint   space)  /* in: space id */
1933
1844
{
1934
1845
        ibuf_data_t*    ibuf_data;
1935
1846
        ulint           i;
1942
1853
        }
1943
1854
 
1944
1855
#ifdef UNIV_SYNC_DEBUG
1945
 
        ut_ad(rw_lock_own(fil_space_get_latch(space, NULL), RW_LOCK_EX));
 
1856
        ut_ad(rw_lock_own(fil_space_get_latch(space), RW_LOCK_EX));
1946
1857
#endif /* UNIV_SYNC_DEBUG */
1947
 
        ut_ad(rw_lock_get_x_lock_count(fil_space_get_latch(space, NULL)) == 1);
 
1858
        ut_ad(rw_lock_get_x_lock_count(fil_space_get_latch(space)) == 1);
1948
1859
        ut_ad(!ibuf_inside());
1949
1860
 
1950
1861
        /* NOTE: We require that the thread did not own the latch before,
1999
1910
        rec_t*          rec,    /* in: record from which we read up and down
2000
1911
                                in the chain of records */
2001
1912
        ulint*          space_ids,/* in/out: space id's of the pages */
2002
 
        ib_int64_t*     space_versions,/* in/out: tablespace version
 
1913
        ib_longlong*    space_versions,/* in/out: tablespace version
2003
1914
                                timestamps; used to prevent reading in old
2004
1915
                                pages after DISCARD + IMPORT tablespace */
2005
1916
        ulint*          page_nos,/* in/out: buffer for at least
2178
2089
        ibool           all_trees_empty;
2179
2090
        ulint           page_nos[IBUF_MAX_N_PAGES_MERGED];
2180
2091
        ulint           space_ids[IBUF_MAX_N_PAGES_MERGED];
2181
 
        ib_int64_t      space_versions[IBUF_MAX_N_PAGES_MERGED];
 
2092
        ib_longlong     space_versions[IBUF_MAX_N_PAGES_MERGED];
2182
2093
        ulint           n_stored;
2183
2094
        ulint           sum_sizes;
2184
2095
        mtr_t           mtr;
2280
2191
 
2281
2192
/*************************************************************************
2282
2193
Contracts insert buffer trees by reading pages to the buffer pool. */
2283
 
UNIV_INTERN
 
2194
 
2284
2195
ulint
2285
2196
ibuf_contract(
2286
2197
/*==========*/
2298
2209
 
2299
2210
/*************************************************************************
2300
2211
Contracts insert buffer trees by reading pages to the buffer pool. */
2301
 
UNIV_INTERN
 
2212
 
2302
2213
ulint
2303
2214
ibuf_contract_for_n_pages(
2304
2215
/*======================*/
2375
2286
/*************************************************************************
2376
2287
Gets an upper limit for the combined size of entries buffered in the insert
2377
2288
buffer for a given page. */
2378
 
UNIV_INLINE
2379
 
ulint
 
2289
 
 
2290
static ulint
2380
2291
ibuf_get_volume_buffered(
2381
2292
/*=====================*/
2382
2293
                                /* out: upper limit for the volume of
2412
2323
        volume = 0;
2413
2324
 
2414
2325
        rec = btr_pcur_get_rec(pcur);
2415
 
        page = page_align(rec);
 
2326
 
 
2327
        page = buf_frame_align(rec);
2416
2328
 
2417
2329
        if (page_rec_is_supremum(rec)) {
2418
2330
                rec = page_rec_get_prev(rec);
2444
2356
                goto count_later;
2445
2357
        }
2446
2358
 
2447
 
        {
2448
 
                buf_block_t*    block = buf_page_get(
2449
 
                        0, 0, prev_page_no, RW_X_LATCH, mtr);
2450
 
#ifdef UNIV_SYNC_DEBUG
2451
 
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
2452
 
#endif /* UNIV_SYNC_DEBUG */
2453
 
                prev_page = buf_block_get_frame(block);
2454
 
        }
 
2359
        prev_page = buf_page_get(0, prev_page_no, RW_X_LATCH, mtr);
2455
2360
#ifdef UNIV_BTR_DEBUG
2456
2361
        ut_a(btr_page_get_next(prev_page, mtr)
2457
 
             == page_get_page_no(page));
 
2362
             == buf_frame_get_page_no(page));
2458
2363
#endif /* UNIV_BTR_DEBUG */
2459
2364
 
 
2365
#ifdef UNIV_SYNC_DEBUG
 
2366
        buf_page_dbg_add_level(prev_page, SYNC_TREE_NODE);
 
2367
#endif /* UNIV_SYNC_DEBUG */
 
2368
 
2460
2369
        rec = page_get_supremum_rec(prev_page);
2461
2370
        rec = page_rec_get_prev(rec);
2462
2371
 
2514
2423
                return(volume);
2515
2424
        }
2516
2425
 
2517
 
        {
2518
 
                buf_block_t*    block = buf_page_get(
2519
 
                        0, 0, next_page_no, RW_X_LATCH, mtr);
2520
 
#ifdef UNIV_SYNC_DEBUG
2521
 
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
2522
 
#endif /* UNIV_SYNC_DEBUG */
2523
 
                next_page = buf_block_get_frame(block);
2524
 
        }
 
2426
        next_page = buf_page_get(0, next_page_no, RW_X_LATCH, mtr);
2525
2427
#ifdef UNIV_BTR_DEBUG
2526
2428
        ut_a(btr_page_get_prev(next_page, mtr)
2527
 
             == page_get_page_no(page));
 
2429
             == buf_frame_get_page_no(page));
2528
2430
#endif /* UNIV_BTR_DEBUG */
2529
2431
 
 
2432
#ifdef UNIV_SYNC_DEBUG
 
2433
        buf_page_dbg_add_level(next_page, SYNC_TREE_NODE);
 
2434
#endif /* UNIV_SYNC_DEBUG */
 
2435
 
2530
2436
        rec = page_get_infimum_rec(next_page);
2531
2437
        rec = page_rec_get_next(rec);
2532
2438
 
2553
2459
/*************************************************************************
2554
2460
Reads the biggest tablespace id from the high end of the insert buffer
2555
2461
tree and updates the counter in fil_system. */
2556
 
UNIV_INTERN
 
2462
 
2557
2463
void
2558
2464
ibuf_update_max_tablespace_id(void)
2559
2465
/*===============================*/
2560
2466
{
2561
2467
        ulint           max_space_id;
2562
 
        const rec_t*    rec;
2563
 
        const byte*     field;
 
2468
        rec_t*          rec;
 
2469
        byte*           field;
2564
2470
        ulint           len;
2565
2471
        ibuf_data_t*    ibuf_data;
2566
2472
        dict_index_t*   ibuf_index;
2580
2486
                                    &pcur, TRUE, &mtr);
2581
2487
        btr_pcur_move_to_prev(&pcur, &mtr);
2582
2488
 
2583
 
        if (btr_pcur_is_before_first_on_page(&pcur)) {
 
2489
        if (btr_pcur_is_before_first_on_page(&pcur, &mtr)) {
2584
2490
                /* The tree is empty */
2585
2491
 
2586
2492
                max_space_id = 0;
2611
2517
/*============*/
2612
2518
                                /* out: DB_SUCCESS, DB_FAIL, DB_STRONG_FAIL */
2613
2519
        ulint           mode,   /* in: BTR_MODIFY_PREV or BTR_MODIFY_TREE */
2614
 
        const dtuple_t* entry,  /* in: index entry to insert */
2615
 
        ulint           entry_size,
2616
 
                                /* in: rec_get_converted_size(index, entry) */
 
2520
        dtuple_t*       entry,  /* in: index entry to insert */
2617
2521
        dict_index_t*   index,  /* in: index where to insert; must not be
2618
2522
                                unique or clustered */
2619
2523
        ulint           space,  /* in: space id where to insert */
2620
 
        ulint           zip_size,/* in: compressed page size in bytes, or 0 */
2621
2524
        ulint           page_no,/* in: page number where to insert */
2622
2525
        que_thr_t*      thr)    /* in: query thread */
2623
2526
{
2624
2527
        big_rec_t*      dummy_big_rec;
 
2528
        ulint           entry_size;
2625
2529
        btr_pcur_t      pcur;
2626
2530
        btr_cur_t*      cursor;
2627
2531
        dtuple_t*       ibuf_entry;
2636
2540
        ulint           err;
2637
2541
        ibool           do_merge;
2638
2542
        ulint           space_ids[IBUF_MAX_N_PAGES_MERGED];
2639
 
        ib_int64_t      space_versions[IBUF_MAX_N_PAGES_MERGED];
 
2543
        ib_longlong     space_versions[IBUF_MAX_N_PAGES_MERGED];
2640
2544
        ulint           page_nos[IBUF_MAX_N_PAGES_MERGED];
2641
2545
        ulint           n_stored;
2642
2546
        ulint           bits;
2643
2547
        mtr_t           mtr;
2644
2548
        mtr_t           bitmap_mtr;
2645
2549
 
2646
 
        ut_a(!dict_index_is_clust(index));
 
2550
        ut_a(!(index->type & DICT_CLUSTERED));
2647
2551
        ut_ad(dtuple_check_typed(entry));
2648
 
        ut_ad(ut_is_2pow(zip_size));
2649
2552
 
2650
2553
        ut_a(trx_sys_multiple_tablespace_format);
2651
2554
 
2709
2612
                ibuf_enter();
2710
2613
        }
2711
2614
 
 
2615
        entry_size = rec_get_converted_size(index, entry);
 
2616
 
2712
2617
        heap = mem_heap_create(512);
2713
2618
 
2714
2619
        /* Build the entry which contains the space id and the page number as
2729
2634
        page */
2730
2635
        buffered = ibuf_get_volume_buffered(&pcur, space, page_no, &mtr);
2731
2636
 
2732
 
#ifdef UNIV_IBUF_COUNT_DEBUG
 
2637
#ifdef UNIV_IBUF_DEBUG
2733
2638
        ut_a((buffered == 0) || ibuf_count_get(space, page_no));
2734
2639
#endif
2735
2640
        mtr_start(&bitmap_mtr);
2736
2641
 
2737
 
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
2738
 
                                               zip_size, &bitmap_mtr);
 
2642
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &bitmap_mtr);
2739
2643
 
2740
2644
        /* We check if the index page is suitable for buffered entries */
2741
2645
 
2748
2652
                goto function_exit;
2749
2653
        }
2750
2654
 
2751
 
        bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
 
2655
        bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no,
2752
2656
                                         IBUF_BITMAP_FREE, &bitmap_mtr);
2753
2657
 
2754
2658
        if (buffered + entry_size + page_dir_calc_reserved_space(1)
2755
 
            > ibuf_index_page_calc_free_from_bits(zip_size, bits)) {
 
2659
            > ibuf_index_page_calc_free_from_bits(bits)) {
2756
2660
                mtr_commit(&bitmap_mtr);
2757
2661
 
2758
2662
                /* It may not fit */
2769
2673
        /* Set the bitmap bit denoting that the insert buffer contains
2770
2674
        buffered entries for this index page, if the bit is not set yet */
2771
2675
 
2772
 
        old_bit_value = ibuf_bitmap_page_get_bits(
2773
 
                bitmap_page, page_no, zip_size,
2774
 
                IBUF_BITMAP_BUFFERED, &bitmap_mtr);
 
2676
        old_bit_value = ibuf_bitmap_page_get_bits(bitmap_page, page_no,
 
2677
                                                  IBUF_BITMAP_BUFFERED,
 
2678
                                                  &bitmap_mtr);
2775
2679
        if (!old_bit_value) {
2776
 
                ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
 
2680
                ibuf_bitmap_page_set_bits(bitmap_page, page_no,
2777
2681
                                          IBUF_BITMAP_BUFFERED, TRUE,
2778
2682
                                          &bitmap_mtr);
2779
2683
        }
2785
2689
        if (mode == BTR_MODIFY_PREV) {
2786
2690
                err = btr_cur_optimistic_insert(BTR_NO_LOCKING_FLAG, cursor,
2787
2691
                                                ibuf_entry, &ins_rec,
2788
 
                                                &dummy_big_rec, 0, thr, &mtr);
 
2692
                                                &dummy_big_rec, thr,
 
2693
                                                &mtr);
2789
2694
                if (err == DB_SUCCESS) {
2790
2695
                        /* Update the page max trx id field */
2791
 
                        page_update_max_trx_id(btr_cur_get_block(cursor), NULL,
 
2696
                        page_update_max_trx_id(buf_frame_align(ins_rec),
2792
2697
                                               thr_get_trx(thr)->id);
2793
2698
                }
2794
2699
        } else {
2805
2710
                                                 | BTR_NO_UNDO_LOG_FLAG,
2806
2711
                                                 cursor,
2807
2712
                                                 ibuf_entry, &ins_rec,
2808
 
                                                 &dummy_big_rec, 0, thr, &mtr);
 
2713
                                                 &dummy_big_rec, thr,
 
2714
                                                 &mtr);
2809
2715
                if (err == DB_SUCCESS) {
2810
2716
                        /* Update the page max trx id field */
2811
 
                        page_update_max_trx_id(btr_cur_get_block(cursor), NULL,
 
2717
                        page_update_max_trx_id(buf_frame_align(ins_rec),
2812
2718
                                               thr_get_trx(thr)->id);
2813
2719
                }
2814
2720
 
2816
2722
        }
2817
2723
 
2818
2724
function_exit:
2819
 
#ifdef UNIV_IBUF_COUNT_DEBUG
 
2725
#ifdef UNIV_IBUF_DEBUG
2820
2726
        if (err == DB_SUCCESS) {
2821
2727
                fprintf(stderr,
2822
2728
                        "Incrementing ibuf count of space %lu page %lu\n"
2868
2774
Makes an index insert to the insert buffer, instead of directly to the disk
2869
2775
page, if this is possible. Does not do insert if the index is clustered
2870
2776
or unique. */
2871
 
UNIV_INTERN
 
2777
 
2872
2778
ibool
2873
2779
ibuf_insert(
2874
2780
/*========*/
2875
2781
                                /* out: TRUE if success */
2876
 
        const dtuple_t* entry,  /* in: index entry to insert */
 
2782
        dtuple_t*       entry,  /* in: index entry to insert */
2877
2783
        dict_index_t*   index,  /* in: index where to insert */
2878
2784
        ulint           space,  /* in: space id where to insert */
2879
 
        ulint           zip_size,/* in: compressed page size in bytes, or 0 */
2880
2785
        ulint           page_no,/* in: page number where to insert */
2881
2786
        que_thr_t*      thr)    /* in: query thread */
2882
2787
{
2883
2788
        ulint   err;
2884
 
        ulint   entry_size;
2885
2789
 
2886
2790
        ut_a(trx_sys_multiple_tablespace_format);
2887
2791
        ut_ad(dtuple_check_typed(entry));
2888
 
        ut_ad(ut_is_2pow(zip_size));
2889
 
 
2890
 
        ut_a(!dict_index_is_clust(index));
2891
 
 
2892
 
        entry_size = rec_get_converted_size(index, entry, 0);
2893
 
 
2894
 
        if (entry_size
 
2792
 
 
2793
        ut_a(!(index->type & DICT_CLUSTERED));
 
2794
 
 
2795
        if (rec_get_converted_size(index, entry)
2895
2796
            >= (page_get_free_space_of_empty(dict_table_is_comp(index->table))
2896
2797
                / 2)) {
2897
2798
                return(FALSE);
2898
2799
        }
2899
2800
 
2900
 
        err = ibuf_insert_low(BTR_MODIFY_PREV, entry, entry_size,
2901
 
                              index, space, zip_size, page_no, thr);
 
2801
        err = ibuf_insert_low(BTR_MODIFY_PREV, entry, index, space, page_no,
 
2802
                              thr);
2902
2803
        if (err == DB_FAIL) {
2903
 
                err = ibuf_insert_low(BTR_MODIFY_TREE, entry, entry_size,
2904
 
                                      index, space, zip_size, page_no, thr);
 
2804
                err = ibuf_insert_low(BTR_MODIFY_TREE, entry, index, space,
 
2805
                                      page_no, thr);
2905
2806
        }
2906
2807
 
2907
2808
        if (err == DB_SUCCESS) {
2926
2827
ibuf_insert_to_index_page(
2927
2828
/*======================*/
2928
2829
        dtuple_t*       entry,  /* in: buffered entry to insert */
2929
 
        buf_block_t*    block,  /* in/out: index page where the buffered entry
 
2830
        page_t*         page,   /* in: index page where the buffered entry
2930
2831
                                should be placed */
2931
2832
        dict_index_t*   index,  /* in: record descriptor */
2932
2833
        mtr_t*          mtr)    /* in: mtr */
2933
2834
{
2934
2835
        page_cur_t      page_cur;
2935
2836
        ulint           low_match;
2936
 
        page_t*         page            = buf_block_get_frame(block);
2937
2837
        rec_t*          rec;
2938
2838
        page_t*         bitmap_page;
2939
2839
        ulint           old_bits;
2959
2859
                      "InnoDB: but the number of fields does not match!\n",
2960
2860
                      stderr);
2961
2861
dump:
2962
 
                buf_page_print(page, 0);
 
2862
                buf_page_print(page);
2963
2863
 
2964
2864
                dtuple_print(stderr, entry);
2965
2865
 
2974
2874
                return;
2975
2875
        }
2976
2876
 
2977
 
        low_match = page_cur_search(block, index, entry,
 
2877
        low_match = page_cur_search(page, index, entry,
2978
2878
                                    PAGE_CUR_LE, &page_cur);
2979
2879
 
2980
2880
        if (low_match == dtuple_get_n_fields(entry)) {
2981
 
                buf_block_t*    block;
2982
 
                page_zip_des_t* page_zip;
2983
 
 
2984
2881
                rec = page_cur_get_rec(&page_cur);
2985
 
                block = page_cur_get_block(&page_cur);
2986
 
                page_zip = buf_block_get_page_zip(block);
2987
2882
 
2988
 
                btr_cur_del_unmark_for_ibuf(rec, page_zip, mtr);
 
2883
                btr_cur_del_unmark_for_ibuf(rec, mtr);
2989
2884
        } else {
2990
 
                rec = page_cur_tuple_insert(&page_cur, entry, index, 0, mtr);
2991
 
 
2992
 
                if (UNIV_LIKELY(rec != NULL)) {
2993
 
                        return;
2994
 
                }
2995
 
 
2996
 
                /* If the record did not fit, reorganize */
2997
 
 
2998
 
                btr_page_reorganize(block, index, mtr);
2999
 
                page_cur_search(block, index, entry, PAGE_CUR_LE, &page_cur);
3000
 
 
3001
 
                /* This time the record must fit */
3002
 
                if (UNIV_UNLIKELY
3003
 
                    (!page_cur_tuple_insert(&page_cur, entry, index,
3004
 
                                            0, mtr))) {
3005
 
                        ulint   space;
3006
 
                        ulint   page_no;
3007
 
                        ulint   zip_size;
3008
 
 
3009
 
                        ut_print_timestamp(stderr);
3010
 
 
3011
 
                        fprintf(stderr,
3012
 
                                "  InnoDB: Error: Insert buffer insert"
3013
 
                                " fails; page free %lu,"
3014
 
                                " dtuple size %lu\n",
3015
 
                                (ulong) page_get_max_insert_size(
3016
 
                                        page, 1),
3017
 
                                (ulong) rec_get_converted_size(
3018
 
                                        index, entry, 0));
3019
 
                        fputs("InnoDB: Cannot insert index record ",
3020
 
                              stderr);
3021
 
                        dtuple_print(stderr, entry);
3022
 
                        fputs("\nInnoDB: The table where"
3023
 
                              " this index record belongs\n"
3024
 
                              "InnoDB: is now probably corrupt."
3025
 
                              " Please run CHECK TABLE on\n"
3026
 
                              "InnoDB: that table.\n", stderr);
3027
 
 
3028
 
                        space = page_get_space_id(page);
3029
 
                        zip_size = buf_block_get_zip_size(block);
3030
 
                        page_no = page_get_page_no(page);
3031
 
 
3032
 
                        bitmap_page = ibuf_bitmap_get_map_page(
3033
 
                                space, page_no, zip_size, mtr);
3034
 
                        old_bits = ibuf_bitmap_page_get_bits(
3035
 
                                bitmap_page, page_no, zip_size,
3036
 
                                IBUF_BITMAP_FREE, mtr);
3037
 
 
3038
 
                        fprintf(stderr,
3039
 
                                "InnoDB: space %lu, page %lu,"
3040
 
                                " zip_size %lu, bitmap bits %lu\n",
3041
 
                                (ulong) space, (ulong) page_no,
3042
 
                                (ulong) zip_size, (ulong) old_bits);
3043
 
 
3044
 
                        fputs("InnoDB: Submit a detailed bug report"
3045
 
                              " to http://bugs.mysql.com\n", stderr);
 
2885
                rec = page_cur_tuple_insert(&page_cur, entry, index, mtr);
 
2886
 
 
2887
                if (rec == NULL) {
 
2888
                        /* If the record did not fit, reorganize */
 
2889
 
 
2890
                        btr_page_reorganize(page, index, mtr);
 
2891
 
 
2892
                        page_cur_search(page, index, entry,
 
2893
                                        PAGE_CUR_LE, &page_cur);
 
2894
 
 
2895
                        /* This time the record must fit */
 
2896
                        if (UNIV_UNLIKELY(!page_cur_tuple_insert(
 
2897
                                                  &page_cur, entry, index,
 
2898
                                                  mtr))) {
 
2899
 
 
2900
                                ut_print_timestamp(stderr);
 
2901
 
 
2902
                                fprintf(stderr,
 
2903
                                        "  InnoDB: Error: Insert buffer insert"
 
2904
                                        " fails; page free %lu,"
 
2905
                                        " dtuple size %lu\n",
 
2906
                                        (ulong) page_get_max_insert_size(
 
2907
                                                page, 1),
 
2908
                                        (ulong) rec_get_converted_size(
 
2909
                                                index, entry));
 
2910
                                fputs("InnoDB: Cannot insert index record ",
 
2911
                                      stderr);
 
2912
                                dtuple_print(stderr, entry);
 
2913
                                fputs("\nInnoDB: The table where"
 
2914
                                      " this index record belongs\n"
 
2915
                                      "InnoDB: is now probably corrupt."
 
2916
                                      " Please run CHECK TABLE on\n"
 
2917
                                      "InnoDB: that table.\n", stderr);
 
2918
 
 
2919
                                bitmap_page = ibuf_bitmap_get_map_page(
 
2920
                                        buf_frame_get_space_id(page),
 
2921
                                        buf_frame_get_page_no(page),
 
2922
                                        mtr);
 
2923
                                old_bits = ibuf_bitmap_page_get_bits(
 
2924
                                        bitmap_page,
 
2925
                                        buf_frame_get_page_no(page),
 
2926
                                        IBUF_BITMAP_FREE, mtr);
 
2927
 
 
2928
                                fprintf(stderr, "InnoDB: Bitmap bits %lu\n",
 
2929
                                        (ulong) old_bits);
 
2930
 
 
2931
                                fputs("InnoDB: Submit a detailed bug report"
 
2932
                                      " to http://bugs.mysql.com\n", stderr);
 
2933
                        }
3046
2934
                }
3047
2935
        }
3048
2936
}
3062
2950
                                should belong */
3063
2951
        btr_pcur_t*     pcur,   /* in: pcur positioned on the record to
3064
2952
                                delete, having latch mode BTR_MODIFY_LEAF */
3065
 
        const dtuple_t* search_tuple,
 
2953
        dtuple_t*       search_tuple,
3066
2954
                                /* in: search tuple for entries of page_no */
3067
2955
        mtr_t*          mtr)    /* in: mtr */
3068
2956
{
3076
2964
        success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur), mtr);
3077
2965
 
3078
2966
        if (success) {
3079
 
#ifdef UNIV_IBUF_COUNT_DEBUG
 
2967
#ifdef UNIV_IBUF_DEBUG
3080
2968
                fprintf(stderr,
3081
2969
                        "Decrementing ibuf count of space %lu page %lu\n"
3082
2970
                        "from %lu by 1\n", space, page_no,
3143
3031
                                   FALSE, mtr);
3144
3032
        ut_a(err == DB_SUCCESS);
3145
3033
 
3146
 
#ifdef UNIV_IBUF_COUNT_DEBUG
 
3034
#ifdef UNIV_IBUF_DEBUG
3147
3035
        ibuf_count_set(space, page_no, ibuf_count_get(space, page_no) - 1);
3148
3036
#else
3149
3037
        UT_NOT_USED(space);
3168
3056
created in the buffer pool, this function deletes its buffered entries from
3169
3057
the insert buffer; there can exist entries for such a page if the page
3170
3058
belonged to an index which subsequently was dropped. */
3171
 
UNIV_INTERN
 
3059
 
3172
3060
void
3173
3061
ibuf_merge_or_delete_for_page(
3174
3062
/*==========================*/
3175
 
        buf_block_t*    block,  /* in: if page has been read from
3176
 
                                disk, pointer to the page x-latched,
3177
 
                                else NULL */
3178
 
        ulint           space,  /* in: space id of the index page */
3179
 
        ulint           page_no,/* in: page number of the index page */
3180
 
        ulint           zip_size,/* in: compressed page size in bytes,
3181
 
                                or 0 */
3182
 
        ibool           update_ibuf_bitmap)/* in: normally this is set
3183
 
                                to TRUE, but if we have deleted or are
3184
 
                                deleting the tablespace, then we
3185
 
                                naturally do not want to update a
3186
 
                                non-existent bitmap page */
 
3063
        page_t* page,   /* in: if page has been read from disk, pointer to
 
3064
                        the page x-latched, else NULL */
 
3065
        ulint   space,  /* in: space id of the index page */
 
3066
        ulint   page_no,/* in: page number of the index page */
 
3067
        ibool   update_ibuf_bitmap)/* in: normally this is set to TRUE, but if
 
3068
                        we have deleted or are deleting the tablespace, then we
 
3069
                        naturally do not want to update a non-existent bitmap
 
3070
                        page */
3187
3071
{
3188
3072
        mem_heap_t*     heap;
3189
3073
        btr_pcur_t      pcur;
3190
3074
        dtuple_t*       entry;
3191
3075
        dtuple_t*       search_tuple;
3192
3076
        rec_t*          ibuf_rec;
 
3077
        buf_block_t*    block;
3193
3078
        page_t*         bitmap_page;
3194
3079
        ibuf_data_t*    ibuf_data;
3195
3080
        ulint           n_inserts;
3196
3081
#ifdef UNIV_IBUF_DEBUG
3197
3082
        ulint           volume;
3198
3083
#endif
3199
 
        page_zip_des_t* page_zip                = NULL;
3200
3084
        ibool           tablespace_being_deleted = FALSE;
3201
3085
        ibool           corruption_noticed      = FALSE;
3202
3086
        mtr_t           mtr;
3203
3087
 
3204
 
        ut_ad(!block || buf_block_get_space(block) == space);
3205
 
        ut_ad(!block || buf_block_get_page_no(block) == page_no);
3206
 
        ut_ad(!block || buf_block_get_zip_size(block) == zip_size);
3207
 
 
3208
3088
        if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
3209
3089
 
3210
3090
                return;
3211
3091
        }
3212
3092
 
3213
 
        if (trx_sys_hdr_page(space, page_no)) {
3214
 
                return;
3215
 
        }
3216
 
 
3217
 
        /* The following assumes that the uncompressed page size
3218
 
        is a power-of-2 multiple of zip_size. */
3219
 
        if (ibuf_fixed_addr_page(space, 0, page_no)
3220
 
            || fsp_descr_page(0, page_no)) {
3221
 
                return;
3222
 
        }
3223
 
 
3224
 
        if (UNIV_LIKELY(update_ibuf_bitmap)) {
3225
 
                ut_a(ut_is_2pow(zip_size));
3226
 
 
3227
 
                if (ibuf_fixed_addr_page(space, zip_size, page_no)
3228
 
                    || fsp_descr_page(zip_size, page_no)) {
3229
 
                        return;
3230
 
                }
3231
 
 
 
3093
        if (ibuf_fixed_addr_page(space, page_no) || fsp_descr_page(page_no)
 
3094
            || trx_sys_hdr_page(space, page_no)) {
 
3095
                return;
 
3096
        }
 
3097
 
 
3098
        if (update_ibuf_bitmap) {
3232
3099
                /* If the following returns FALSE, we get the counter
3233
3100
                incremented, and must decrement it when we leave this
3234
3101
                function. When the counter is > 0, that prevents tablespace
3236
3103
 
3237
3104
                tablespace_being_deleted = fil_inc_pending_ibuf_merges(space);
3238
3105
 
3239
 
                if (UNIV_UNLIKELY(tablespace_being_deleted)) {
 
3106
                if (tablespace_being_deleted) {
3240
3107
                        /* Do not try to read the bitmap page from space;
3241
3108
                        just delete the ibuf records for the page */
3242
3109
 
3243
 
                        block = NULL;
 
3110
                        page = NULL;
3244
3111
                        update_ibuf_bitmap = FALSE;
3245
 
                } else {
3246
 
                        mtr_start(&mtr);
3247
 
                        bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
3248
 
                                                               zip_size, &mtr);
3249
 
 
3250
 
                        if (!ibuf_bitmap_page_get_bits(bitmap_page, page_no,
3251
 
                                                       zip_size,
3252
 
                                                       IBUF_BITMAP_BUFFERED,
3253
 
                                                       &mtr)) {
3254
 
                                /* No inserts buffered for this page */
3255
 
                                mtr_commit(&mtr);
3256
 
 
3257
 
                                if (!tablespace_being_deleted) {
3258
 
                                        fil_decr_pending_ibuf_merges(space);
3259
 
                                }
3260
 
 
3261
 
                                return;
 
3112
                }
 
3113
        }
 
3114
 
 
3115
        if (update_ibuf_bitmap) {
 
3116
                mtr_start(&mtr);
 
3117
                bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr);
 
3118
 
 
3119
                if (!ibuf_bitmap_page_get_bits(bitmap_page, page_no,
 
3120
                                               IBUF_BITMAP_BUFFERED, &mtr)) {
 
3121
                        /* No inserts buffered for this page */
 
3122
                        mtr_commit(&mtr);
 
3123
 
 
3124
                        if (!tablespace_being_deleted) {
 
3125
                                fil_decr_pending_ibuf_merges(space);
3262
3126
                        }
3263
 
                        mtr_commit(&mtr);
3264
 
                }
3265
 
        } else if (block) {
3266
 
                if (ibuf_fixed_addr_page(space, zip_size, page_no)
3267
 
                    || fsp_descr_page(zip_size, page_no)) {
 
3127
 
3268
3128
                        return;
3269
3129
                }
 
3130
                mtr_commit(&mtr);
3270
3131
        }
3271
3132
 
3272
3133
        /* Currently the insert buffer of space 0 takes care of inserts to all
3286
3147
                                                           heap);
3287
3148
        }
3288
3149
 
3289
 
        if (block) {
 
3150
        if (page) {
3290
3151
                /* Move the ownership of the x-latch on the page to this OS
3291
3152
                thread, so that we can acquire a second x-latch on it. This
3292
3153
                is needed for the insert operations to the index page to pass
3293
3154
                the debug checks. */
3294
3155
 
 
3156
                block = buf_block_align(page);
3295
3157
                rw_lock_x_lock_move_ownership(&(block->lock));
3296
 
                page_zip = buf_block_get_page_zip(block);
3297
3158
 
3298
 
                if (UNIV_UNLIKELY(fil_page_get_type(block->frame)
3299
 
                                  != FIL_PAGE_INDEX)) {
 
3159
                if (fil_page_get_type(page) != FIL_PAGE_INDEX) {
3300
3160
 
3301
3161
                        corruption_noticed = TRUE;
3302
3162
 
3308
3168
                              stderr);
3309
3169
 
3310
3170
                        bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
3311
 
                                                               zip_size, &mtr);
3312
 
                        buf_page_print(bitmap_page, 0);
 
3171
                                                               &mtr);
 
3172
                        buf_page_print(bitmap_page);
3313
3173
 
3314
3174
                        mtr_commit(&mtr);
3315
3175
 
3316
3176
                        fputs("\nInnoDB: Dump of the page:\n", stderr);
3317
3177
 
3318
 
                        buf_page_print(block->frame, 0);
 
3178
                        buf_page_print(page);
3319
3179
 
3320
3180
                        fprintf(stderr,
3321
3181
                                "InnoDB: Error: corruption in the tablespace."
3333
3193
                                "InnoDB: Please submit a detailed bug report"
3334
3194
                                " to http://bugs.mysql.com\n\n",
3335
3195
                                (ulong) page_no,
3336
 
                                (ulong)
3337
 
                                fil_page_get_type(block->frame));
 
3196
                                (ulong) fil_page_get_type(page));
3338
3197
                }
3339
3198
        }
3340
3199
 
3345
3204
loop:
3346
3205
        mtr_start(&mtr);
3347
3206
 
3348
 
        if (block) {
3349
 
                ibool success = buf_page_get_known_nowait(RW_X_LATCH, block,
 
3207
        if (page) {
 
3208
                ibool success = buf_page_get_known_nowait(RW_X_LATCH, page,
3350
3209
                                                          BUF_KEEP_OLD,
3351
3210
                                                          __FILE__, __LINE__,
3352
3211
                                                          &mtr);
3353
3212
                ut_a(success);
3354
3213
#ifdef UNIV_SYNC_DEBUG
3355
 
                buf_block_dbg_add_level(block, SYNC_TREE_NODE);
 
3214
                buf_page_dbg_add_level(page, SYNC_TREE_NODE);
3356
3215
#endif /* UNIV_SYNC_DEBUG */
3357
3216
        }
3358
3217
 
3360
3219
        index page */
3361
3220
        btr_pcur_open_on_user_rec(ibuf_data->index, search_tuple, PAGE_CUR_GE,
3362
3221
                                  BTR_MODIFY_LEAF, &pcur, &mtr);
3363
 
        if (!btr_pcur_is_on_user_rec(&pcur)) {
 
3222
        if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) {
3364
3223
                ut_ad(btr_pcur_is_after_last_in_tree(&pcur, &mtr));
3365
3224
 
3366
3225
                goto reset_bit;
3367
3226
        }
3368
3227
 
3369
3228
        for (;;) {
3370
 
                ut_ad(btr_pcur_is_on_user_rec(&pcur));
 
3229
                ut_ad(btr_pcur_is_on_user_rec(&pcur, &mtr));
3371
3230
 
3372
3231
                ibuf_rec = btr_pcur_get_rec(&pcur);
3373
3232
 
3374
3233
                /* Check if the entry is for this index page */
3375
3234
                if (ibuf_rec_get_page_no(ibuf_rec) != page_no
3376
3235
                    || ibuf_rec_get_space(ibuf_rec) != space) {
3377
 
                        if (block) {
3378
 
                                page_header_reset_last_insert(
3379
 
                                        block->frame, page_zip, &mtr);
 
3236
                        if (page) {
 
3237
                                page_header_reset_last_insert(page, &mtr);
3380
3238
                        }
3381
3239
                        goto reset_bit;
3382
3240
                }
3383
3241
 
3384
 
                if (UNIV_UNLIKELY(corruption_noticed)) {
 
3242
                if (corruption_noticed) {
3385
3243
                        fputs("InnoDB: Discarding record\n ", stderr);
3386
3244
                        rec_print_old(stderr, ibuf_rec);
3387
 
                        fputs("\nInnoDB: from the insert buffer!\n\n", stderr);
3388
 
                } else if (block) {
 
3245
                        fputs("\n from the insert buffer!\n\n", stderr);
 
3246
                } else if (page) {
3389
3247
                        /* Now we have at pcur a record which should be
3390
3248
                        inserted to the index page; NOTE that the call below
3391
3249
                        copies pointers to fields in ibuf_rec, and we must
3393
3251
                        insertion is finished! */
3394
3252
                        dict_index_t*   dummy_index;
3395
3253
                        dulint          max_trx_id = page_get_max_trx_id(
3396
 
                                page_align(ibuf_rec));
3397
 
                        page_update_max_trx_id(block, page_zip, max_trx_id);
 
3254
                                buf_frame_align(ibuf_rec));
 
3255
                        page_update_max_trx_id(page, max_trx_id);
3398
3256
 
3399
3257
                        entry = ibuf_build_entry_from_ibuf_rec(
3400
3258
                                ibuf_rec, heap, &dummy_index);
3401
3259
#ifdef UNIV_IBUF_DEBUG
3402
 
                        volume += rec_get_converted_size(dummy_index, entry, 0)
 
3260
                        volume += rec_get_converted_size(dummy_index, entry)
3403
3261
                                + page_dir_calc_reserved_space(1);
3404
3262
                        ut_a(volume <= 4 * UNIV_PAGE_SIZE
3405
3263
                             / IBUF_PAGE_SIZE_PER_FREE_SPACE);
3406
3264
#endif
3407
 
                        ibuf_insert_to_index_page(entry, block,
 
3265
                        ibuf_insert_to_index_page(entry, page,
3408
3266
                                                  dummy_index, &mtr);
3409
3267
                        ibuf_dummy_index_free(dummy_index);
3410
3268
                }
3420
3278
                        goto loop;
3421
3279
                }
3422
3280
 
3423
 
                if (btr_pcur_is_after_last_on_page(&pcur)) {
 
3281
                if (btr_pcur_is_after_last_on_page(&pcur, &mtr)) {
3424
3282
                        mtr_commit(&mtr);
3425
3283
                        btr_pcur_close(&pcur);
3426
3284
 
3429
3287
        }
3430
3288
 
3431
3289
reset_bit:
3432
 
#ifdef UNIV_IBUF_COUNT_DEBUG
 
3290
#ifdef UNIV_IBUF_DEBUG
3433
3291
        if (ibuf_count_get(space, page_no) > 0) {
3434
3292
                /* btr_print_tree(ibuf_data->index->tree, 100);
3435
3293
                ibuf_print(); */
3436
3294
        }
3437
3295
#endif
3438
 
        if (UNIV_LIKELY(update_ibuf_bitmap)) {
3439
 
                bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
3440
 
                                                       zip_size, &mtr);
3441
 
                ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
 
3296
        if (update_ibuf_bitmap) {
 
3297
                bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr);
 
3298
                ibuf_bitmap_page_set_bits(bitmap_page, page_no,
3442
3299
                                          IBUF_BITMAP_BUFFERED, FALSE, &mtr);
3443
 
                if (block) {
 
3300
                if (page) {
3444
3301
                        ulint old_bits = ibuf_bitmap_page_get_bits(
3445
 
                                bitmap_page, page_no, zip_size,
3446
 
                                IBUF_BITMAP_FREE, &mtr);
3447
 
                        ulint new_bits = ibuf_index_page_calc_free(
3448
 
                                zip_size, block);
 
3302
                                bitmap_page, page_no, IBUF_BITMAP_FREE, &mtr);
 
3303
                        ulint new_bits = ibuf_index_page_calc_free(page);
3449
3304
#if 0 /* defined UNIV_IBUF_DEBUG */
3450
3305
                        fprintf(stderr, "Old bits %lu new bits %lu"
3451
3306
                                " max size %lu\n",
3455
3310
#endif
3456
3311
                        if (old_bits != new_bits) {
3457
3312
                                ibuf_bitmap_page_set_bits(bitmap_page, page_no,
3458
 
                                                          zip_size,
3459
3313
                                                          IBUF_BITMAP_FREE,
3460
3314
                                                          new_bits, &mtr);
3461
3315
                        }
3484
3338
        }
3485
3339
 
3486
3340
        ibuf_exit();
3487
 
#ifdef UNIV_IBUF_COUNT_DEBUG
 
3341
#ifdef UNIV_IBUF_DEBUG
3488
3342
        ut_a(ibuf_count_get(space, page_no) == 0);
3489
3343
#endif
3490
3344
}
3494
3348
in DISCARD TABLESPACE and IMPORT TABLESPACE.
3495
3349
NOTE: this does not update the page free bitmaps in the space. The space will
3496
3350
become CORRUPT when you call this function! */
3497
 
UNIV_INTERN
 
3351
 
3498
3352
void
3499
3353
ibuf_delete_for_discarded_space(
3500
3354
/*============================*/
3532
3386
        space */
3533
3387
        btr_pcur_open_on_user_rec(ibuf_data->index, search_tuple, PAGE_CUR_GE,
3534
3388
                                  BTR_MODIFY_LEAF, &pcur, &mtr);
3535
 
        if (!btr_pcur_is_on_user_rec(&pcur)) {
 
3389
        if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) {
3536
3390
                ut_ad(btr_pcur_is_after_last_in_tree(&pcur, &mtr));
3537
3391
 
3538
3392
                goto leave_loop;
3539
3393
        }
3540
3394
 
3541
3395
        for (;;) {
3542
 
                ut_ad(btr_pcur_is_on_user_rec(&pcur));
 
3396
                ut_ad(btr_pcur_is_on_user_rec(&pcur, &mtr));
3543
3397
 
3544
3398
                ibuf_rec = btr_pcur_get_rec(&pcur);
3545
3399
 
3565
3419
                        goto loop;
3566
3420
                }
3567
3421
 
3568
 
                if (btr_pcur_is_after_last_on_page(&pcur)) {
 
3422
                if (btr_pcur_is_after_last_on_page(&pcur, &mtr)) {
3569
3423
                        mtr_commit(&mtr);
3570
3424
                        btr_pcur_close(&pcur);
3571
3425
 
3596
3450
        mem_heap_free(heap);
3597
3451
}
3598
3452
 
3599
 
#ifdef UNIV_DEBUG
 
3453
 
3600
3454
/**********************************************************************
3601
3455
Validates the ibuf data structures when the caller owns ibuf_mutex. */
3602
 
static
 
3456
 
3603
3457
ibool
3604
3458
ibuf_validate_low(void)
3605
3459
/*===================*/
3624
3478
 
3625
3479
        return(TRUE);
3626
3480
}
3627
 
#endif /* UNIV_DEBUG */
3628
3481
 
3629
3482
/**********************************************************************
3630
3483
Looks if the insert buffer is empty. */
3631
 
UNIV_INTERN
 
3484
 
3632
3485
ibool
3633
3486
ibuf_is_empty(void)
3634
3487
/*===============*/
3636
3489
{
3637
3490
        ibuf_data_t*    data;
3638
3491
        ibool           is_empty;
3639
 
        const page_t*   root;
 
3492
        page_t*         root;
3640
3493
        mtr_t           mtr;
3641
3494
 
3642
3495
        ibuf_enter();
3680
3533
 
3681
3534
/**********************************************************************
3682
3535
Prints info of ibuf. */
3683
 
UNIV_INTERN
 
3536
 
3684
3537
void
3685
3538
ibuf_print(
3686
3539
/*=======*/
3687
3540
        FILE*   file)   /* in: file where to print */
3688
3541
{
3689
3542
        ibuf_data_t*    data;
3690
 
#ifdef UNIV_IBUF_COUNT_DEBUG
 
3543
#ifdef UNIV_IBUF_DEBUG
3691
3544
        ulint           i;
3692
3545
#endif
3693
3546
 
3705
3558
                        (ulong) data->n_inserts,
3706
3559
                        (ulong) data->n_merged_recs,
3707
3560
                        (ulong) data->n_merges);
3708
 
#ifdef UNIV_IBUF_COUNT_DEBUG
 
3561
#ifdef UNIV_IBUF_DEBUG
3709
3562
                for (i = 0; i < IBUF_COUNT_N_PAGES; i++) {
3710
3563
                        if (ibuf_count_get(data->space, i) > 0) {
3711
3564