~ubuntu-branches/ubuntu/maverick/mysql-5.1/maverick-proposed

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 14:16:05 UTC
  • mto: This revision was merged to the branch mainline in revision 20.
  • Revision ID: package-import@ubuntu.com-20120222141605-nxlu9yzc6attylc2
Tags: upstream-5.1.61
ImportĀ upstreamĀ versionĀ 5.1.61

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include "btr0cur.h"
23
23
#include "btr0pcur.h"
24
24
#include "btr0btr.h"
 
25
#include "row0upd.h"
25
26
#include "sync0sync.h"
26
27
#include "dict0boot.h"
27
28
#include "fut0lst.h"
137
138
/* Buffer pool size per the maximum insert buffer size */
138
139
#define IBUF_POOL_SIZE_PER_MAX_SIZE     2
139
140
 
 
141
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
 
142
/* Flag to control insert buffer debugging. */
 
143
uint    ibuf_debug;
 
144
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
 
145
 
140
146
/* The insert buffer control structure */
141
147
ibuf_t* ibuf                    = NULL;
142
148
 
1677
1683
 
1678
1684
        page = buf_page_get(space, page_no, RW_X_LATCH, &mtr);
1679
1685
 
 
1686
        ibuf_enter();
 
1687
 
 
1688
        mutex_enter(&ibuf_mutex);
 
1689
 
 
1690
        root = ibuf_tree_root_get(ibuf_data, space, &mtr);
 
1691
 
1680
1692
#ifdef UNIV_SYNC_DEBUG
1681
1693
        buf_page_dbg_add_level(page, SYNC_TREE_NODE_NEW);
1682
1694
#endif /* UNIV_SYNC_DEBUG */
1683
1695
 
1684
 
        ibuf_enter();
1685
 
 
1686
 
        mutex_enter(&ibuf_mutex);
1687
 
 
1688
 
        root = ibuf_tree_root_get(ibuf_data, space, &mtr);
1689
 
 
1690
1696
        /* Add the page to the free list and update the ibuf size data */
1691
1697
 
1692
1698
        flst_add_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
2824
2830
from the insert buffer. */
2825
2831
static
2826
2832
void
 
2833
ibuf_insert_to_index_page_low(
 
2834
/*==========================*/
 
2835
        dtuple_t*       entry,  /* in: buffered entry to insert */
 
2836
        page_t*         page,   /* in: index page where the buffered entry
 
2837
                                should be placed */
 
2838
        dict_index_t*   index,  /* in: record descriptor */
 
2839
        mtr_t*          mtr,    /* in: mtr */
 
2840
        page_cur_t*     page_cur)/* in: cursor positioned on the record
 
2841
                                after which to insert the buffered entry */
 
2842
{
 
2843
        ulint   space;
 
2844
        ulint   page_no;
 
2845
        page_t* bitmap_page;
 
2846
        ulint   old_bits;
 
2847
 
 
2848
        if (UNIV_LIKELY
 
2849
            (page_cur_tuple_insert(page_cur, entry, index, mtr) != NULL)) {
 
2850
                return;
 
2851
        }
 
2852
 
 
2853
        /* If the record did not fit, reorganize */
 
2854
 
 
2855
        btr_page_reorganize(page, index, mtr);
 
2856
 
 
2857
        page_cur_search(page, index, entry, PAGE_CUR_LE, page_cur);
 
2858
 
 
2859
        /* This time the record must fit */
 
2860
 
 
2861
        if (UNIV_LIKELY
 
2862
            (page_cur_tuple_insert(page_cur, entry, index, mtr) != NULL)) {
 
2863
                return;
 
2864
        }
 
2865
 
 
2866
        ut_print_timestamp(stderr);
 
2867
 
 
2868
        fprintf(stderr,
 
2869
                "  InnoDB: Error: Insert buffer insert fails;"
 
2870
                " page free %lu, dtuple size %lu\n",
 
2871
                (ulong) page_get_max_insert_size(page, 1),
 
2872
                (ulong) rec_get_converted_size(index, entry));
 
2873
        fputs("InnoDB: Cannot insert index record ", stderr);
 
2874
        dtuple_print(stderr, entry);
 
2875
        fputs("\nInnoDB: The table where this index record belongs\n"
 
2876
              "InnoDB: is now probably corrupt. Please run CHECK TABLE on\n"
 
2877
              "InnoDB: that table.\n", stderr);
 
2878
 
 
2879
        space = buf_frame_get_space_id(page);
 
2880
        page_no = buf_frame_get_page_no(page);
 
2881
 
 
2882
        bitmap_page = ibuf_bitmap_get_map_page(space, page_no, mtr);
 
2883
        old_bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no,
 
2884
                                             IBUF_BITMAP_FREE, mtr);
 
2885
 
 
2886
        fprintf(stderr,
 
2887
                "InnoDB: space %lu, page %lu, bitmap bits %lu\n",
 
2888
                (ulong) space, (ulong) page_no, (ulong) old_bits);
 
2889
 
 
2890
        fputs("InnoDB: Submit a detailed bug report"
 
2891
              " to http://bugs.mysql.com\n", stderr);
 
2892
}
 
2893
 
 
2894
/************************************************************************
 
2895
During merge, inserts to an index page a secondary index entry extracted
 
2896
from the insert buffer. */
 
2897
static
 
2898
void
2827
2899
ibuf_insert_to_index_page(
2828
2900
/*======================*/
2829
2901
        dtuple_t*       entry,  /* in: buffered entry to insert */
2835
2907
        page_cur_t      page_cur;
2836
2908
        ulint           low_match;
2837
2909
        rec_t*          rec;
2838
 
        page_t*         bitmap_page;
2839
 
        ulint           old_bits;
2840
2910
 
2841
2911
        ut_ad(ibuf_inside());
2842
2912
        ut_ad(dtuple_check_typed(entry));
 
2913
        ut_ad(!buf_block_align(page)->is_hashed);
2843
2914
 
2844
2915
        if (UNIV_UNLIKELY(dict_table_is_comp(index->table)
2845
2916
                          != (ibool)!!page_is_comp(page))) {
2877
2948
        low_match = page_cur_search(page, index, entry,
2878
2949
                                    PAGE_CUR_LE, &page_cur);
2879
2950
 
2880
 
        if (low_match == dtuple_get_n_fields(entry)) {
 
2951
        if (UNIV_UNLIKELY(low_match == dtuple_get_n_fields(entry))) {
 
2952
                mem_heap_t*     heap;
 
2953
                upd_t*          update;
 
2954
                ulint*          offsets;
 
2955
 
2881
2956
                rec = page_cur_get_rec(&page_cur);
2882
2957
 
2883
 
                btr_cur_del_unmark_for_ibuf(rec, mtr);
 
2958
                /* This is based on
 
2959
                row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */
 
2960
                ut_ad(rec_get_deleted_flag(rec, page_is_comp(page)));
 
2961
 
 
2962
                heap = mem_heap_create(1024);
 
2963
 
 
2964
                offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED,
 
2965
                                          &heap);
 
2966
                update = row_upd_build_sec_rec_difference_binary(
 
2967
                        index, entry, rec, NULL, heap);
 
2968
 
 
2969
                if (update->n_fields == 0) {
 
2970
                        /* The records only differ in the delete-mark.
 
2971
                        Clear the delete-mark, like we did before
 
2972
                        Bug #56680 was fixed. */
 
2973
                        btr_cur_del_unmark_for_ibuf(rec, mtr);
 
2974
updated_in_place:
 
2975
                        mem_heap_free(heap);
 
2976
                        return;
 
2977
                }
 
2978
 
 
2979
                /* Copy the info bits. Clear the delete-mark. */
 
2980
                update->info_bits = rec_get_info_bits(rec, page_is_comp(page));
 
2981
                update->info_bits &= ~REC_INFO_DELETED_FLAG;
 
2982
 
 
2983
                /* We cannot invoke btr_cur_optimistic_update() here,
 
2984
                because we do not have a btr_cur_t or que_thr_t,
 
2985
                as the insert buffer merge occurs at a very low level. */
 
2986
                if (!row_upd_changes_field_size_or_external(index, offsets,
 
2987
                                                            update)) {
 
2988
                        /* This is the easy case. Do something similar
 
2989
                        to btr_cur_update_in_place(). */
 
2990
                        row_upd_rec_in_place(rec, offsets, update);
 
2991
                        goto updated_in_place;
 
2992
                }
 
2993
 
 
2994
                /* A collation may identify values that differ in
 
2995
                storage length.
 
2996
                Some examples (1 or 2 bytes):
 
2997
                utf8_turkish_ci: I = U+0131 LATIN SMALL LETTER DOTLESS I
 
2998
                utf8_general_ci: S = U+00DF LATIN SMALL LETTER SHARP S
 
2999
                utf8_general_ci: A = U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
 
3000
 
 
3001
                latin1_german2_ci: SS = U+00DF LATIN SMALL LETTER SHARP S
 
3002
 
 
3003
                Examples of a character (3-byte UTF-8 sequence)
 
3004
                identified with 2 or 4 characters (1-byte UTF-8 sequences):
 
3005
 
 
3006
                utf8_unicode_ci: 'II' = U+2171 SMALL ROMAN NUMERAL TWO
 
3007
                utf8_unicode_ci: '(10)' = U+247D PARENTHESIZED NUMBER TEN
 
3008
                */
 
3009
 
 
3010
                /* Delete the different-length record, and insert the
 
3011
                buffered one. */
 
3012
 
 
3013
                lock_rec_store_on_page_infimum(page, rec);
 
3014
                page_cur_delete_rec(&page_cur, index, offsets, mtr);
 
3015
                page_cur_move_to_prev(&page_cur);
 
3016
                mem_heap_free(heap);
 
3017
 
 
3018
                ibuf_insert_to_index_page_low(entry, page, index, mtr,
 
3019
                                              &page_cur);
 
3020
                lock_rec_restore_from_page_infimum(rec, page);
2884
3021
        } 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
 
                        }
2934
 
                }
 
3022
                ibuf_insert_to_index_page_low(entry, page, index, mtr,
 
3023
                                              &page_cur);
2935
3024
        }
2936
3025
}
2937
3026