~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2008-11-04 15:39:09 UTC
  • mfrom: (575.1.2 devel)
  • Revision ID: brian@tangent.org-20081104153909-c72hn65udxs1ccal
Merge of Monty's work

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