~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Lee Bieber
  • Date: 2010-12-23 02:14:02 UTC
  • mfrom: (2021.1.2 build)
  • Revision ID: kalebral@gmail.com-20101223021402-o4zhdsv3x8s0q6pz
Merge Stewart - Update innobase plugin to be based on innodb 1.1.4 from MySQL 5.5.8 
Merge Marisa - fixed markup in 'administrative.rst', which was throwing an error in the build

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
#include "btr0cur.h"
50
50
#include "btr0pcur.h"
51
51
#include "btr0btr.h"
 
52
#include "row0upd.h"
52
53
#include "sync0sync.h"
53
54
#include "dict0boot.h"
54
55
#include "fut0lst.h"
192
193
/** Operations that can currently be buffered. */
193
194
UNIV_INTERN ibuf_use_t  ibuf_use                = IBUF_USE_ALL;
194
195
 
 
196
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
 
197
/** Flag to control insert buffer debugging. */
 
198
UNIV_INTERN uint        ibuf_debug;
 
199
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
 
200
 
195
201
/** The insert buffer control structure */
196
202
UNIV_INTERN ibuf_t*     ibuf                    = NULL;
197
203
 
1357
1363
        const ulint*    ops)    /*!< in: operation counts */
1358
1364
 
1359
1365
{
 
1366
        ulint   i;
 
1367
 
1360
1368
#ifndef HAVE_ATOMIC_BUILTINS
1361
1369
        ut_ad(mutex_own(&ibuf_mutex));
1362
1370
#endif /* !HAVE_ATOMIC_BUILTINS */
1363
1371
 
1364
 
        ulint   i;
1365
 
 
1366
1372
        for (i = 0; i < IBUF_OP_COUNT; i++) {
1367
1373
#ifdef HAVE_ATOMIC_BUILTINS
1368
1374
                os_atomic_increment_ulint(&arr[i], ops[i]);
2761
2767
 
2762
2768
        switch (ibuf_op) {
2763
2769
        case IBUF_OP_INSERT:
2764
 
                /* Inserts can be done by
2765
 
                btr_cur_set_deleted_flag_for_ibuf().  Because
2766
 
                delete-mark and insert operations can be pointing to
 
2770
                /* Inserts can be done by updating a delete-marked record.
 
2771
                Because delete-mark and insert operations can be pointing to
2767
2772
                the same records, we must not count duplicates. */
2768
2773
        case IBUF_OP_DELETE_MARK:
2769
2774
                /* There must be a record to delete-mark.
3748
3753
from the insert buffer. */
3749
3754
static
3750
3755
void
 
3756
ibuf_insert_to_index_page_low(
 
3757
/*==========================*/
 
3758
        const dtuple_t* entry,  /*!< in: buffered entry to insert */
 
3759
        buf_block_t*    block,  /*!< in/out: index page where the buffered
 
3760
                                entry should be placed */
 
3761
        dict_index_t*   index,  /*!< in: record descriptor */
 
3762
        mtr_t*          mtr,    /*!< in/out: mtr */
 
3763
        page_cur_t*     page_cur)/*!< in/out: cursor positioned on the record
 
3764
                                after which to insert the buffered entry */
 
3765
{
 
3766
        const page_t*   page;
 
3767
        ulint           space;
 
3768
        ulint           page_no;
 
3769
        ulint           zip_size;
 
3770
        const page_t*   bitmap_page;
 
3771
        ulint           old_bits;
 
3772
 
 
3773
        if (UNIV_LIKELY
 
3774
            (page_cur_tuple_insert(page_cur, entry, index, 0, mtr) != NULL)) {
 
3775
                return;
 
3776
        }
 
3777
 
 
3778
        /* If the record did not fit, reorganize */
 
3779
 
 
3780
        btr_page_reorganize(block, index, mtr);
 
3781
        page_cur_search(block, index, entry, PAGE_CUR_LE, page_cur);
 
3782
 
 
3783
        /* This time the record must fit */
 
3784
 
 
3785
        if (UNIV_LIKELY
 
3786
            (page_cur_tuple_insert(page_cur, entry, index, 0, mtr) != NULL)) {
 
3787
                return;
 
3788
        }
 
3789
 
 
3790
        page = buf_block_get_frame(block);
 
3791
 
 
3792
        ut_print_timestamp(stderr);
 
3793
 
 
3794
        fprintf(stderr,
 
3795
                "  InnoDB: Error: Insert buffer insert fails;"
 
3796
                " page free %lu, dtuple size %lu\n",
 
3797
                (ulong) page_get_max_insert_size(page, 1),
 
3798
                (ulong) rec_get_converted_size(index, entry, 0));
 
3799
        fputs("InnoDB: Cannot insert index record ", stderr);
 
3800
        dtuple_print(stderr, entry);
 
3801
        fputs("\nInnoDB: The table where this index record belongs\n"
 
3802
              "InnoDB: is now probably corrupt. Please run CHECK TABLE on\n"
 
3803
              "InnoDB: that table.\n", stderr);
 
3804
 
 
3805
        space = page_get_space_id(page);
 
3806
        zip_size = buf_block_get_zip_size(block);
 
3807
        page_no = page_get_page_no(page);
 
3808
 
 
3809
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
 
3810
        old_bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
 
3811
                                             IBUF_BITMAP_FREE, mtr);
 
3812
 
 
3813
        fprintf(stderr,
 
3814
                "InnoDB: space %lu, page %lu, zip_size %lu, bitmap bits %lu\n",
 
3815
                (ulong) space, (ulong) page_no,
 
3816
                (ulong) zip_size, (ulong) old_bits);
 
3817
 
 
3818
        fputs("InnoDB: Submit a detailed bug report"
 
3819
              " to http://bugs.mysql.com\n", stderr);
 
3820
}
 
3821
 
 
3822
/************************************************************************
 
3823
During merge, inserts to an index page a secondary index entry extracted
 
3824
from the insert buffer. */
 
3825
static
 
3826
void
3751
3827
ibuf_insert_to_index_page(
3752
3828
/*======================*/
3753
 
        dtuple_t*       entry,  /*!< in: buffered entry to insert */
 
3829
        const dtuple_t* entry,  /*!< in: buffered entry to insert */
3754
3830
        buf_block_t*    block,  /*!< in/out: index page where the buffered entry
3755
3831
                                should be placed */
3756
3832
        dict_index_t*   index,  /*!< in: record descriptor */
3760
3836
        ulint           low_match;
3761
3837
        page_t*         page            = buf_block_get_frame(block);
3762
3838
        rec_t*          rec;
3763
 
        page_t*         bitmap_page;
3764
 
        ulint           old_bits;
3765
3839
 
3766
3840
        ut_ad(ibuf_inside());
3767
3841
        ut_ad(dtuple_check_typed(entry));
 
3842
        ut_ad(!buf_block_align(page)->is_hashed);
3768
3843
 
3769
3844
        if (UNIV_UNLIKELY(dict_table_is_comp(index->table)
3770
3845
                          != (ibool)!!page_is_comp(page))) {
3810
3885
        low_match = page_cur_search(block, index, entry,
3811
3886
                                    PAGE_CUR_LE, &page_cur);
3812
3887
 
3813
 
        if (low_match == dtuple_get_n_fields(entry)) {
 
3888
        if (UNIV_UNLIKELY(low_match == dtuple_get_n_fields(entry))) {
 
3889
                mem_heap_t*     heap;
 
3890
                upd_t*          update;
 
3891
                ulint*          offsets;
3814
3892
                page_zip_des_t* page_zip;
3815
3893
 
3816
3894
                rec = page_cur_get_rec(&page_cur);
 
3895
 
 
3896
                /* This is based on
 
3897
                row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */
 
3898
                ut_ad(rec_get_deleted_flag(rec, page_is_comp(page)));
 
3899
 
 
3900
                heap = mem_heap_create(1024);
 
3901
 
 
3902
                offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED,
 
3903
                                          &heap);
 
3904
                update = row_upd_build_sec_rec_difference_binary(
 
3905
                        index, entry, rec, NULL, heap);
 
3906
 
3817
3907
                page_zip = buf_block_get_page_zip(block);
3818
3908
 
3819
 
                btr_cur_set_deleted_flag_for_ibuf(rec, page_zip, FALSE, mtr);
 
3909
                if (update->n_fields == 0) {
 
3910
                        /* The records only differ in the delete-mark.
 
3911
                        Clear the delete-mark, like we did before
 
3912
                        Bug #56680 was fixed. */
 
3913
                        btr_cur_set_deleted_flag_for_ibuf(
 
3914
                                rec, page_zip, FALSE, mtr);
 
3915
updated_in_place:
 
3916
                        mem_heap_free(heap);
 
3917
                        return;
 
3918
                }
 
3919
 
 
3920
                /* Copy the info bits. Clear the delete-mark. */
 
3921
                update->info_bits = rec_get_info_bits(rec, page_is_comp(page));
 
3922
                update->info_bits &= ~REC_INFO_DELETED_FLAG;
 
3923
 
 
3924
                /* We cannot invoke btr_cur_optimistic_update() here,
 
3925
                because we do not have a btr_cur_t or que_thr_t,
 
3926
                as the insert buffer merge occurs at a very low level. */
 
3927
                if (!row_upd_changes_field_size_or_external(index, offsets,
 
3928
                                                            update)
 
3929
                    && (!page_zip || btr_cur_update_alloc_zip(
 
3930
                                page_zip, block, index,
 
3931
                                rec_offs_size(offsets), FALSE, mtr))) {
 
3932
                        /* This is the easy case. Do something similar
 
3933
                        to btr_cur_update_in_place(). */
 
3934
                        row_upd_rec_in_place(rec, index, offsets,
 
3935
                                             update, page_zip);
 
3936
                        goto updated_in_place;
 
3937
                }
 
3938
 
 
3939
                /* A collation may identify values that differ in
 
3940
                storage length.
 
3941
                Some examples (1 or 2 bytes):
 
3942
                utf8_turkish_ci: I = U+0131 LATIN SMALL LETTER DOTLESS I
 
3943
                utf8_general_ci: S = U+00DF LATIN SMALL LETTER SHARP S
 
3944
                utf8_general_ci: A = U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
 
3945
 
 
3946
                latin1_german2_ci: SS = U+00DF LATIN SMALL LETTER SHARP S
 
3947
 
 
3948
                Examples of a character (3-byte UTF-8 sequence)
 
3949
                identified with 2 or 4 characters (1-byte UTF-8 sequences):
 
3950
 
 
3951
                utf8_unicode_ci: 'II' = U+2171 SMALL ROMAN NUMERAL TWO
 
3952
                utf8_unicode_ci: '(10)' = U+247D PARENTHESIZED NUMBER TEN
 
3953
                */
 
3954
 
 
3955
                /* Delete the different-length record, and insert the
 
3956
                buffered one. */
 
3957
 
 
3958
                lock_rec_store_on_page_infimum(block, rec);
 
3959
                page_cur_delete_rec(&page_cur, index, offsets, mtr);
 
3960
                page_cur_move_to_prev(&page_cur);
 
3961
                mem_heap_free(heap);
 
3962
 
 
3963
                ibuf_insert_to_index_page_low(entry, block, index, mtr,
 
3964
                                              &page_cur);
 
3965
                lock_rec_restore_from_page_infimum(block, rec, block);
3820
3966
        } else {
3821
 
                rec = page_cur_tuple_insert(&page_cur, entry, index, 0, mtr);
3822
 
 
3823
 
                if (UNIV_LIKELY(rec != NULL)) {
3824
 
                        return;
3825
 
                }
3826
 
 
3827
 
                /* If the record did not fit, reorganize */
3828
 
 
3829
 
                btr_page_reorganize(block, index, mtr);
3830
 
                page_cur_search(block, index, entry, PAGE_CUR_LE, &page_cur);
3831
 
 
3832
 
                /* This time the record must fit */
3833
 
                if (UNIV_UNLIKELY
3834
 
                    (!page_cur_tuple_insert(&page_cur, entry, index,
3835
 
                                            0, mtr))) {
3836
 
                        ulint   space;
3837
 
                        ulint   page_no;
3838
 
                        ulint   zip_size;
3839
 
 
3840
 
                        ut_print_timestamp(stderr);
3841
 
 
3842
 
                        fprintf(stderr,
3843
 
                                "  InnoDB: Error: Insert buffer insert"
3844
 
                                " fails; page free %lu,"
3845
 
                                " dtuple size %lu\n",
3846
 
                                (ulong) page_get_max_insert_size(
3847
 
                                        page, 1),
3848
 
                                (ulong) rec_get_converted_size(
3849
 
                                        index, entry, 0));
3850
 
                        fputs("InnoDB: Cannot insert index record ",
3851
 
                              stderr);
3852
 
                        dtuple_print(stderr, entry);
3853
 
                        fputs("\nInnoDB: The table where"
3854
 
                              " this index record belongs\n"
3855
 
                              "InnoDB: is now probably corrupt."
3856
 
                              " Please run CHECK TABLE on\n"
3857
 
                              "InnoDB: that table.\n", stderr);
3858
 
 
3859
 
                        space = page_get_space_id(page);
3860
 
                        zip_size = buf_block_get_zip_size(block);
3861
 
                        page_no = page_get_page_no(page);
3862
 
 
3863
 
                        bitmap_page = ibuf_bitmap_get_map_page(
3864
 
                                space, page_no, zip_size, mtr);
3865
 
                        old_bits = ibuf_bitmap_page_get_bits(
3866
 
                                bitmap_page, page_no, zip_size,
3867
 
                                IBUF_BITMAP_FREE, mtr);
3868
 
 
3869
 
                        fprintf(stderr,
3870
 
                                "InnoDB: space %lu, page %lu,"
3871
 
                                " zip_size %lu, bitmap bits %lu\n",
3872
 
                                (ulong) space, (ulong) page_no,
3873
 
                                (ulong) zip_size, (ulong) old_bits);
3874
 
 
3875
 
                        fputs("InnoDB: Submit a detailed bug report"
3876
 
                              " to http://bugs.mysql.com\n", stderr);
3877
 
                }
 
3967
                ibuf_insert_to_index_page_low(entry, block, index, mtr,
 
3968
                                              &page_cur);
3878
3969
        }
3879
3970
}
3880
3971
 
3906
3997
                rec = page_cur_get_rec(&page_cur);
3907
3998
                page_zip = page_cur_get_page_zip(&page_cur);
3908
3999
 
3909
 
                btr_cur_set_deleted_flag_for_ibuf(rec, page_zip, TRUE, mtr);
 
4000
                /* Delete mark the old index record. According to a
 
4001
                comment in row_upd_sec_index_entry(), it can already
 
4002
                have been delete marked if a lock wait occurred in
 
4003
                row_ins_index_entry() in a previous invocation of
 
4004
                row_upd_sec_index_entry(). */
 
4005
 
 
4006
                if (UNIV_LIKELY
 
4007
                    (!rec_get_deleted_flag(
 
4008
                            rec, dict_table_is_comp(index->table)))) {
 
4009
                        btr_cur_set_deleted_flag_for_ibuf(rec, page_zip,
 
4010
                                                          TRUE, mtr);
 
4011
                }
3910
4012
        } else {
3911
 
                /* This can happen benignly in some situations. */
 
4013
                ut_print_timestamp(stderr);
 
4014
                fputs("  InnoDB: unable to find a record to delete-mark\n",
 
4015
                      stderr);
 
4016
                fputs("InnoDB: tuple ", stderr);
 
4017
                dtuple_print(stderr, entry);
 
4018
                fputs("\n"
 
4019
                      "InnoDB: record ", stderr);
 
4020
                rec_print(stderr, page_cur_get_rec(&page_cur), index);
 
4021
                putc('\n', stderr);
 
4022
                fputs("\n"
 
4023
                      "InnoDB: Submit a detailed bug report"
 
4024
                      " to http://bugs.mysql.com\n", stderr);
 
4025
                ut_ad(0);
3912
4026
        }
3913
4027
}
3914
4028
 
3983
4097
                        mem_heap_free(heap);
3984
4098
                }
3985
4099
        } else {
3986
 
                /* This can happen benignly in some situations: either when
3987
 
                we crashed at just the right time, or on database startup
3988
 
                when we redo some old log entries (due to worse stored
3989
 
                position granularity on disk than in memory). */
 
4100
                /* The record must have been purged already. */
3990
4101
        }
3991
4102
}
3992
4103