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

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 08:30:45 UTC
  • mfrom: (1.4.1)
  • Revision ID: package-import@ubuntu.com-20120222083045-2rd53r4bnyx7qus4
Tags: 5.1.61-0ubuntu0.11.04.1
* SECURITY UPDATE: Update to 5.1.61 to fix multiple security issues
  (LP: #937869)
  - http://www.oracle.com/technetwork/topics/security/cpujan2012-366304.html
  - CVE-2011-2262
  - CVE-2012-0075
  - CVE-2012-0112
  - CVE-2012-0113
  - CVE-2012-0114
  - CVE-2012-0115
  - CVE-2012-0116
  - CVE-2012-0117
  - CVE-2012-0118
  - CVE-2012-0119
  - CVE-2012-0120
  - CVE-2012-0484
  - CVE-2012-0485
  - CVE-2012-0486
  - CVE-2012-0487
  - CVE-2012-0488
  - CVE-2012-0489
  - CVE-2012-0490
  - CVE-2012-0491
  - CVE-2012-0492
  - CVE-2012-0493
  - CVE-2012-0494
  - CVE-2012-0495
  - CVE-2012-0496

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include "btr0sea.h"
32
32
#include "row0upd.h"
33
33
#include "trx0rec.h"
 
34
#include "trx0roll.h" /* trx_roll_crash_recv_trx */
34
35
#include "que0que.h"
35
36
#include "row0row.h"
36
37
#include "srv0srv.h"
66
67
/*--------------------------------------*/
67
68
#define BTR_BLOB_HDR_SIZE               8
68
69
 
 
70
/* Estimated table level stats from sampled value. */
 
71
#define BTR_TABLE_STATS_FROM_SAMPLE(value, index, ext_size, not_empty)  \
 
72
        ((value * (ib_longlong) index->stat_n_leaf_pages                \
 
73
          + BTR_KEY_VAL_ESTIMATE_N_PAGES - 1 + ext_size                 \
 
74
          + not_empty)                                                  \
 
75
         / (BTR_KEY_VAL_ESTIMATE_N_PAGES + ext_size))
 
76
 
 
77
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
 
78
/* A BLOB field reference full of zero, for use in assertions and tests.
 
79
Initially, BLOB field references are set to zero, in
 
80
dtuple_convert_big_rec(). */
 
81
const byte field_ref_zero[BTR_EXTERN_FIELD_REF_SIZE];
 
82
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
 
83
 
69
84
/***********************************************************************
70
85
Marks all extern fields in a record as owned by the record. This function
71
86
should be called if the delete mark of a record is removed: a not delete
1565
1580
        ulint           old_rec_size;
1566
1581
        dtuple_t*       new_entry;
1567
1582
        dulint          roll_ptr;
1568
 
        trx_t*          trx;
1569
1583
        mem_heap_t*     heap;
1570
1584
        ibool           reorganized     = FALSE;
1571
1585
        ulint           i;
1578
1592
 
1579
1593
        heap = mem_heap_create(1024);
1580
1594
        offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
 
1595
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
 
1596
        ut_a(!rec_offs_any_null_extern(rec, offsets)
 
1597
             || thr_get_trx(thr) == trx_roll_crash_recv_trx);
 
1598
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
1581
1599
 
1582
1600
#ifdef UNIV_DEBUG
1583
1601
        if (btr_cur_print_record_ops && thr) {
1684
1702
 
1685
1703
        page_cur_move_to_prev(page_cursor);
1686
1704
 
1687
 
        trx = thr_get_trx(thr);
1688
 
 
1689
1705
        if (!(flags & BTR_KEEP_SYS_FLAG)) {
1690
1706
                row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR,
1691
1707
                                              roll_ptr);
1692
1708
                row_upd_index_entry_sys_field(new_entry, index, DATA_TRX_ID,
1693
 
                                              trx->id);
 
1709
                                              thr_get_trx(thr)->id);
1694
1710
        }
1695
1711
 
1696
1712
        rec = btr_cur_insert_if_possible(cursor, new_entry, &reorganized, mtr);
2835
2851
}
2836
2852
 
2837
2853
/***********************************************************************
 
2854
Record the number of non_null key values in a given index for
 
2855
each n-column prefix of the index where n < dict_index_get_n_unique(index).
 
2856
The estimates are eventually stored in the array:
 
2857
index->stat_n_non_null_key_vals. */
 
2858
static
 
2859
void
 
2860
btr_record_not_null_field_in_rec(
 
2861
/*=============================*/
 
2862
        ulint           n_unique,       /* in: dict_index_get_n_unique(index),
 
2863
                                        number of columns uniquely determine
 
2864
                                        an index entry */
 
2865
        const ulint*    offsets,        /* in: rec_get_offsets(rec, index),
 
2866
                                        its size could be for all fields or
 
2867
                                        that of "n_unique" */
 
2868
        ib_longlong*    n_not_null)     /* in/out: array to record number of
 
2869
                                        not null rows for n-column prefix */
 
2870
{
 
2871
        ulint   i;
 
2872
 
 
2873
        ut_ad(rec_offs_n_fields(offsets) >= n_unique);
 
2874
 
 
2875
        if (n_not_null == NULL) {
 
2876
                return;
 
2877
        }
 
2878
 
 
2879
        for (i = 0; i < n_unique; i++) {
 
2880
                if (rec_offs_nth_sql_null(offsets, i)) {
 
2881
                        break;
 
2882
                }
 
2883
 
 
2884
                n_not_null[i]++;
 
2885
        }
 
2886
}
 
2887
 
 
2888
/***********************************************************************
2838
2889
Estimates the number of different key values in a given index, for
2839
2890
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
2840
 
The estimates are stored in the array index->stat_n_diff_key_vals. */
 
2891
The estimates are stored in the array index->stat_n_diff_key_vals.
 
2892
If innodb_stats_method is "nulls_ignored", we also record the number of
 
2893
non-null values for each prefix and store the estimates in
 
2894
array index->stat_n_non_null_key_vals. */
2841
2895
 
2842
2896
void
2843
2897
btr_estimate_number_of_different_key_vals(
2851
2905
        ulint           matched_fields;
2852
2906
        ulint           matched_bytes;
2853
2907
        ib_longlong*    n_diff;
 
2908
        ib_longlong*    n_not_null;
 
2909
        ibool           stats_null_not_equal;
2854
2910
        ulint           not_empty_flag  = 0;
2855
2911
        ulint           total_external_size = 0;
2856
2912
        ulint           i;
2858
2914
        ulint           add_on;
2859
2915
        mtr_t           mtr;
2860
2916
        mem_heap_t*     heap            = NULL;
2861
 
        ulint           offsets_rec_[REC_OFFS_NORMAL_SIZE];
2862
 
        ulint           offsets_next_rec_[REC_OFFS_NORMAL_SIZE];
2863
 
        ulint*          offsets_rec     = offsets_rec_;
2864
 
        ulint*          offsets_next_rec= offsets_next_rec_;
2865
 
        *offsets_rec_ = (sizeof offsets_rec_) / sizeof *offsets_rec_;
2866
 
        *offsets_next_rec_
2867
 
                = (sizeof offsets_next_rec_) / sizeof *offsets_next_rec_;
 
2917
        ulint*          offsets_rec     = NULL;
 
2918
        ulint*          offsets_next_rec = NULL;
2868
2919
 
2869
2920
        n_cols = dict_index_get_n_unique(index);
2870
2921
 
2871
 
        n_diff = mem_alloc((n_cols + 1) * sizeof(ib_longlong));
2872
 
 
2873
 
        memset(n_diff, 0, (n_cols + 1) * sizeof(ib_longlong));
 
2922
        heap = mem_heap_create((sizeof *n_diff + sizeof *n_not_null)
 
2923
                               * (n_cols + 1)
 
2924
                               + dict_index_get_n_fields(index)
 
2925
                               * (sizeof *offsets_rec
 
2926
                                  + sizeof *offsets_next_rec));
 
2927
 
 
2928
        n_diff = mem_heap_zalloc(heap, (n_cols + 1) * sizeof(ib_longlong));
 
2929
 
 
2930
        n_not_null = NULL;
 
2931
 
 
2932
        /* Check srv_innodb_stats_method setting, and decide whether we
 
2933
        need to record non-null value and also decide if NULL is
 
2934
        considered equal (by setting stats_null_not_equal value) */
 
2935
        switch (srv_innodb_stats_method) {
 
2936
        case SRV_STATS_NULLS_IGNORED:
 
2937
                n_not_null = mem_heap_zalloc(heap, (n_cols + 1)
 
2938
                                             * sizeof *n_not_null);
 
2939
                /* fall through */
 
2940
 
 
2941
        case SRV_STATS_NULLS_UNEQUAL:
 
2942
                /* for both SRV_STATS_NULLS_IGNORED and SRV_STATS_NULLS_UNEQUAL
 
2943
                case, we will treat NULLs as unequal value */
 
2944
                stats_null_not_equal = TRUE;
 
2945
                break;
 
2946
 
 
2947
        case SRV_STATS_NULLS_EQUAL:
 
2948
                stats_null_not_equal = FALSE;
 
2949
                break;
 
2950
 
 
2951
        default:
 
2952
                ut_error;
 
2953
        }
2874
2954
 
2875
2955
        /* We sample some pages in the index to get an estimate */
2876
2956
 
2877
2957
        for (i = 0; i < BTR_KEY_VAL_ESTIMATE_N_PAGES; i++) {
2878
 
                rec_t*  supremum;
2879
2958
                mtr_start(&mtr);
2880
2959
 
2881
2960
                btr_cur_open_at_rnd_pos(index, BTR_SEARCH_LEAF, &cursor, &mtr);
2888
2967
 
2889
2968
                page = btr_cur_get_page(&cursor);
2890
2969
 
2891
 
                supremum = page_get_supremum_rec(page);
2892
2970
                rec = page_rec_get_next(page_get_infimum_rec(page));
2893
2971
 
2894
 
                if (rec != supremum) {
 
2972
                if (!page_rec_is_supremum(rec)) {
2895
2973
                        not_empty_flag = 1;
2896
2974
                        offsets_rec = rec_get_offsets(rec, index, offsets_rec,
2897
2975
                                                      ULINT_UNDEFINED, &heap);
 
2976
 
 
2977
                        if (n_not_null) {
 
2978
                                btr_record_not_null_field_in_rec(
 
2979
                                        n_cols, offsets_rec, n_not_null);
 
2980
                        }
2898
2981
                }
2899
2982
 
2900
 
                while (rec != supremum) {
 
2983
                while (!page_rec_is_supremum(rec)) {
2901
2984
                        rec_t*  next_rec = page_rec_get_next(rec);
2902
 
                        if (next_rec == supremum) {
 
2985
                        if (page_rec_is_supremum(next_rec)) {
 
2986
                                total_external_size +=
 
2987
                                        btr_rec_get_externally_stored_len(
 
2988
                                                rec, offsets_rec);
2903
2989
                                break;
2904
2990
                        }
2905
2991
 
2907
2993
                        matched_bytes = 0;
2908
2994
                        offsets_next_rec = rec_get_offsets(next_rec, index,
2909
2995
                                                           offsets_next_rec,
2910
 
                                                           n_cols, &heap);
 
2996
                                                           ULINT_UNDEFINED,
 
2997
                                                           &heap);
2911
2998
 
2912
2999
                        cmp_rec_rec_with_match(rec, next_rec,
2913
3000
                                               offsets_rec, offsets_next_rec,
2914
 
                                               index, &matched_fields,
 
3001
                                               index, stats_null_not_equal,
 
3002
                                               &matched_fields,
2915
3003
                                               &matched_bytes);
2916
3004
 
2917
3005
                        for (j = matched_fields + 1; j <= n_cols; j++) {
2921
3009
                                n_diff[j]++;
2922
3010
                        }
2923
3011
 
 
3012
                        if (n_not_null) {
 
3013
                                btr_record_not_null_field_in_rec(
 
3014
                                        n_cols, offsets_next_rec, n_not_null);
 
3015
                        }
 
3016
 
2924
3017
                        total_external_size
2925
3018
                                += btr_rec_get_externally_stored_len(
2926
3019
                                        rec, offsets_rec);
2955
3048
                        }
2956
3049
                }
2957
3050
 
2958
 
                offsets_rec = rec_get_offsets(rec, index, offsets_rec,
2959
 
                                              ULINT_UNDEFINED, &heap);
2960
 
                total_external_size += btr_rec_get_externally_stored_len(
2961
 
                        rec, offsets_rec);
2962
3051
                mtr_commit(&mtr);
2963
3052
        }
2964
3053
 
2971
3060
        included in index->stat_n_leaf_pages) */
2972
3061
 
2973
3062
        for (j = 0; j <= n_cols; j++) {
2974
 
                index->stat_n_diff_key_vals[j]
2975
 
                        = ((n_diff[j]
2976
 
                            * (ib_longlong)index->stat_n_leaf_pages
2977
 
                            + BTR_KEY_VAL_ESTIMATE_N_PAGES - 1
2978
 
                            + total_external_size
2979
 
                            + not_empty_flag)
2980
 
                           / (BTR_KEY_VAL_ESTIMATE_N_PAGES
2981
 
                              + total_external_size));
 
3063
                index->stat_n_diff_key_vals[j] = BTR_TABLE_STATS_FROM_SAMPLE(
 
3064
                        n_diff[j], index, total_external_size, not_empty_flag);
2982
3065
 
2983
3066
                /* If the tree is small, smaller than
2984
3067
                10 * BTR_KEY_VAL_ESTIMATE_N_PAGES + total_external_size, then
2997
3080
                }
2998
3081
 
2999
3082
                index->stat_n_diff_key_vals[j] += add_on;
3000
 
        }
3001
 
 
3002
 
        mem_free(n_diff);
3003
 
        if (UNIV_LIKELY_NULL(heap)) {
3004
 
                mem_heap_free(heap);
3005
 
        }
 
3083
 
 
3084
                /* Update the stat_n_non_null_key_vals[] with our
 
3085
                sampled result. stat_n_non_null_key_vals[] is created
 
3086
                and initialized to zero in dict_index_add_to_cache(),
 
3087
                along with stat_n_diff_key_vals[] array */
 
3088
                if (n_not_null != NULL && (j < n_cols)) {
 
3089
                        index->stat_n_non_null_key_vals[j] =
 
3090
                                 BTR_TABLE_STATS_FROM_SAMPLE(
 
3091
                                        n_not_null[j], index,
 
3092
                                        total_external_size, not_empty_flag);
 
3093
                }
 
3094
        }
 
3095
 
 
3096
        mem_heap_free(heap);
3006
3097
}
3007
3098
 
3008
3099
/*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/