~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/dict/dict0dict.c

  • Committer: Patrick Crews
  • Date: 2010-12-07 20:02:50 UTC
  • Revision ID: gleebix@gmail.com-20101207200250-6a27jgqalgw5bsb5
Added disabled.def file to disable drizzleslap due to Bug#684269.  Need to skip for tarball release this round

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 1996, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
56
56
 
57
57
#include <ctype.h>
58
58
 
59
 
#include <drizzled/session.h>
60
 
 
61
59
/** the dictionary system */
62
60
UNIV_INTERN dict_sys_t* dict_sys        = NULL;
63
61
 
92
90
/** Identifies generated InnoDB foreign key names */
93
91
static char     dict_ibfk[] = "_ibfk_";
94
92
 
95
 
/** array of rw locks protecting
96
 
dict_table_t::stat_initialized
97
 
dict_table_t::stat_n_rows (*)
98
 
dict_table_t::stat_clustered_index_size
99
 
dict_table_t::stat_sum_of_other_index_sizes
100
 
dict_table_t::stat_modified_counter (*)
101
 
dict_table_t::indexes*::stat_n_diff_key_vals[]
102
 
dict_table_t::indexes*::stat_index_size
103
 
dict_table_t::indexes*::stat_n_leaf_pages
104
 
(*) those are not always protected for performance reasons */
105
 
#define DICT_TABLE_STATS_LATCHES_SIZE   64
106
 
static rw_lock_t        dict_table_stats_latches[DICT_TABLE_STATS_LATCHES_SIZE];
 
93
/** array of mutexes protecting dict_index_t::stat_n_diff_key_vals[] */
 
94
#define DICT_INDEX_STAT_MUTEX_SIZE      32
 
95
static mutex_t  dict_index_stat_mutex[DICT_INDEX_STAT_MUTEX_SIZE];
107
96
 
108
97
/*******************************************************************//**
109
98
Tries to find column names for the index and sets the col field of the
264
253
        mutex_exit(&(dict_sys->mutex));
265
254
}
266
255
 
267
 
/** Get the latch that protects the stats of a given table */
268
 
#define GET_TABLE_STATS_LATCH(table) \
269
 
        (&dict_table_stats_latches[ut_fold_ull(table->id) \
270
 
                                   % DICT_TABLE_STATS_LATCHES_SIZE])
 
256
/** Get the mutex that protects index->stat_n_diff_key_vals[] */
 
257
#define GET_INDEX_STAT_MUTEX(index) \
 
258
        (&dict_index_stat_mutex[ut_fold_ull(index->id) \
 
259
                                % DICT_INDEX_STAT_MUTEX_SIZE])
271
260
 
272
261
/**********************************************************************//**
273
 
Lock the appropriate latch to protect a given table's statistics.
274
 
table->id is used to pick the corresponding latch from a global array of
275
 
latches. */
 
262
Lock the appropriate mutex to protect index->stat_n_diff_key_vals[].
 
263
index->id is used to pick the right mutex and it should not change
 
264
before dict_index_stat_mutex_exit() is called on this index. */
276
265
UNIV_INTERN
277
266
void
278
 
dict_table_stats_lock(
279
 
/*==================*/
280
 
        const dict_table_t*     table,          /*!< in: table */
281
 
        ulint                   latch_mode)     /*!< in: RW_S_LATCH or
282
 
                                                RW_X_LATCH */
 
267
dict_index_stat_mutex_enter(
 
268
/*========================*/
 
269
        const dict_index_t*     index)  /*!< in: index */
283
270
{
284
 
        ut_ad(table != NULL);
285
 
        ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
 
271
        ut_ad(index != NULL);
 
272
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
273
        ut_ad(index->cached);
 
274
        ut_ad(!index->to_be_dropped);
286
275
 
287
 
        switch (latch_mode) {
288
 
        case RW_S_LATCH:
289
 
                rw_lock_s_lock(GET_TABLE_STATS_LATCH(table));
290
 
                break;
291
 
        case RW_X_LATCH:
292
 
                rw_lock_x_lock(GET_TABLE_STATS_LATCH(table));
293
 
                break;
294
 
        case RW_NO_LATCH:
295
 
                /* fall through */
296
 
        default:
297
 
                ut_error;
298
 
        }
 
276
        mutex_enter(GET_INDEX_STAT_MUTEX(index));
299
277
}
300
278
 
301
279
/**********************************************************************//**
302
 
Unlock the latch that has been locked by dict_table_stats_lock() */
 
280
Unlock the appropriate mutex that protects index->stat_n_diff_key_vals[]. */
303
281
UNIV_INTERN
304
282
void
305
 
dict_table_stats_unlock(
306
 
/*====================*/
307
 
        const dict_table_t*     table,          /*!< in: table */
308
 
        ulint                   latch_mode)     /*!< in: RW_S_LATCH or
309
 
                                                RW_X_LATCH */
 
283
dict_index_stat_mutex_exit(
 
284
/*=======================*/
 
285
        const dict_index_t*     index)  /*!< in: index */
310
286
{
311
 
        ut_ad(table != NULL);
312
 
        ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
 
287
        ut_ad(index != NULL);
 
288
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
289
        ut_ad(index->cached);
 
290
        ut_ad(!index->to_be_dropped);
313
291
 
314
 
        switch (latch_mode) {
315
 
        case RW_S_LATCH:
316
 
                rw_lock_s_unlock(GET_TABLE_STATS_LATCH(table));
317
 
                break;
318
 
        case RW_X_LATCH:
319
 
                rw_lock_x_unlock(GET_TABLE_STATS_LATCH(table));
320
 
                break;
321
 
        case RW_NO_LATCH:
322
 
                /* fall through */
323
 
        default:
324
 
                ut_error;
325
 
        }
 
292
        mutex_exit(GET_INDEX_STAT_MUTEX(index));
326
293
}
327
294
 
328
295
/********************************************************************//**
611
578
{
612
579
        dict_table_t*   table;
613
580
 
614
 
        if (trx->dict_operation_lock_mode == RW_X_LATCH) {
 
581
        if (table_id <= DICT_FIELDS_ID
 
582
            || trx->dict_operation_lock_mode == RW_X_LATCH) {
615
583
 
616
584
                /* Note: An X latch implies that the transaction
617
585
                already owns the dictionary mutex. */
690
658
{
691
659
        int     i;
692
660
 
693
 
        dict_sys = static_cast<dict_sys_t *>(mem_alloc(sizeof(dict_sys_t)));
 
661
        dict_sys = mem_alloc(sizeof(dict_sys_t));
694
662
 
695
663
        mutex_create(dict_sys_mutex_key, &dict_sys->mutex, SYNC_DICT);
696
664
 
713
681
        mutex_create(dict_foreign_err_mutex_key,
714
682
                     &dict_foreign_err_mutex, SYNC_ANY_LATCH);
715
683
 
716
 
        for (i = 0; i < DICT_TABLE_STATS_LATCHES_SIZE; i++) {
717
 
                rw_lock_create(PFS_NOT_INSTRUMENTED,
718
 
                               &dict_table_stats_latches[i], SYNC_INDEX_TREE);
719
 
        }
 
684
        for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) {
 
685
          mutex_create(PFS_NOT_INSTRUMENTED,
 
686
                       &dict_index_stat_mutex[i], SYNC_INDEX_TREE);
 
687
        }
720
688
}
721
689
 
722
690
/**********************************************************************//**
746
714
        mutex_exit(&(dict_sys->mutex));
747
715
 
748
716
        if (table != NULL) {
749
 
                /* If table->ibd_file_missing == TRUE, this will
750
 
                print an error message and return without doing
751
 
                anything. */
752
 
                dict_update_statistics(table, TRUE /* only update stats
753
 
                                       if they have not been initialized */);
 
717
                if (!table->stat_initialized) {
 
718
                        /* If table->ibd_file_missing == TRUE, this will
 
719
                        print an error message and return without doing
 
720
                        anything. */
 
721
                        dict_update_statistics(table);
 
722
                }
754
723
        }
755
724
 
756
725
        return(table);
1013
982
                memory fragmentation, we assume a repeated calls of
1014
983
                ut_realloc() with the same size do not cause fragmentation */
1015
984
                ut_a(strlen(new_name) <= MAX_TABLE_NAME_LEN);
1016
 
                table->name = static_cast<char *>(ut_realloc(table->name, MAX_TABLE_NAME_LEN + 1));
 
985
                table->name = ut_realloc(table->name, MAX_TABLE_NAME_LEN + 1);
1017
986
        }
1018
987
        memcpy(table->name, new_name, strlen(new_name) + 1);
1019
988
 
1081
1050
                        TODO: store buf len to save memory */
1082
1051
 
1083
1052
                        foreign->foreign_table_name
1084
 
                                = static_cast<char *>(mem_heap_alloc(foreign->heap,
1085
 
                                                 ut_strlen(table->name) + 1));
 
1053
                                = mem_heap_alloc(foreign->heap,
 
1054
                                                 ut_strlen(table->name) + 1);
1086
1055
                }
1087
1056
 
1088
1057
                strcpy(foreign->foreign_table_name, table->name);
1105
1074
                                /* This is a generated >= 4.0.18 format id */
1106
1075
 
1107
1076
                                if (strlen(table->name) > strlen(old_name)) {
1108
 
                                        foreign->id = static_cast<char *>(mem_heap_alloc(
 
1077
                                        foreign->id = mem_heap_alloc(
1109
1078
                                                foreign->heap,
1110
1079
                                                strlen(table->name)
1111
 
                                                + strlen(old_id) + 1));
 
1080
                                                + strlen(old_id) + 1);
1112
1081
                                }
1113
1082
 
1114
1083
                                /* Replace the prefix 'databasename/tablename'
1124
1093
                                if (dict_get_db_name_len(table->name)
1125
1094
                                    > dict_get_db_name_len(foreign->id)) {
1126
1095
 
1127
 
                                        foreign->id = static_cast<char *>(mem_heap_alloc(
 
1096
                                        foreign->id = mem_heap_alloc(
1128
1097
                                                foreign->heap,
1129
 
                                                db_len + strlen(old_id) + 1));
 
1098
                                                db_len + strlen(old_id) + 1);
1130
1099
                                }
1131
1100
 
1132
1101
                                /* Replace the database prefix in id with the
1152
1121
                        /* Allocate a longer name buffer;
1153
1122
                        TODO: store buf len to save memory */
1154
1123
 
1155
 
                        foreign->referenced_table_name = static_cast<char *>(mem_heap_alloc(
1156
 
                                foreign->heap, strlen(table->name) + 1));
 
1124
                        foreign->referenced_table_name = mem_heap_alloc(
 
1125
                                foreign->heap, strlen(table->name) + 1);
1157
1126
                }
1158
1127
 
1159
1128
                strcpy(foreign->referenced_table_name, table->name);
1681
1650
 
1682
1651
        if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) {
1683
1652
 
1684
 
                new_index->stat_n_diff_key_vals = static_cast<ib_int64_t *>(mem_heap_alloc(
 
1653
                new_index->stat_n_diff_key_vals = mem_heap_alloc(
1685
1654
                        new_index->heap,
1686
1655
                        (1 + dict_index_get_n_unique(new_index))
1687
 
                        * sizeof(ib_int64_t)));
 
1656
                        * sizeof(ib_int64_t));
1688
1657
                /* Give some sensible values to stat_n_... in case we do
1689
1658
                not calculate statistics quickly enough */
1690
1659
 
2065
2034
        }
2066
2035
 
2067
2036
        /* Remember the table columns already contained in new_index */
2068
 
        void *indexed_ptr= mem_zalloc(table->n_cols * sizeof *indexed);
2069
 
        indexed = static_cast<unsigned long *>(indexed_ptr);
 
2037
        indexed = mem_zalloc(table->n_cols * sizeof *indexed);
2070
2038
 
2071
2039
        /* Mark the table columns already contained in new_index */
2072
2040
        for (i = 0; i < new_index->n_def; i++) {
2150
2118
        dict_index_copy(new_index, index, table, 0, index->n_fields);
2151
2119
 
2152
2120
        /* Remember the table columns already contained in new_index */
2153
 
        void *indexed_ptr= mem_zalloc(table->n_cols * sizeof *indexed);
2154
 
        indexed = static_cast<unsigned long *>(indexed_ptr);
 
2121
        indexed = mem_zalloc(table->n_cols * sizeof *indexed);
2155
2122
 
2156
2123
        /* Mark the table columns already contained in new_index */
2157
2124
        for (i = 0; i < new_index->n_def; i++) {
2842
2809
 
2843
2810
        if (quote) {
2844
2811
                char*   d;
2845
 
                str = d = static_cast<char *>(mem_heap_alloc(heap, len + 1));
 
2812
                str = d = mem_heap_alloc(heap, len + 1);
2846
2813
                while (len--) {
2847
2814
                        if ((*d++ = *s++) == quote) {
2848
2815
                                s++;
2861
2828
                /* Convert the identifier from connection character set
2862
2829
                to UTF-8. */
2863
2830
                len = 3 * len + 1;
2864
 
                *id = dst = static_cast<char *>(mem_heap_alloc(heap, len));
 
2831
                *id = dst = mem_heap_alloc(heap, len);
2865
2832
 
2866
2833
                innobase_convert_from_id(cs, dst, str, len);
2867
 
        } else if (!strncmp(str, srv_mysql50_table_name_prefix.c_str(),
2868
 
                            srv_mysql50_table_name_prefix.size())) {
 
2834
        } else if (!strncmp(str, srv_mysql50_table_name_prefix,
 
2835
                            sizeof srv_mysql50_table_name_prefix)) {
2869
2836
                /* This is a pre-5.1 table name
2870
2837
                containing chars other than [A-Za-z0-9].
2871
2838
                Discard the prefix and use raw UTF-8 encoding. */
2872
 
                str += srv_mysql50_table_name_prefix.size();
2873
 
                len -= srv_mysql50_table_name_prefix.size();
 
2839
                str += sizeof srv_mysql50_table_name_prefix;
 
2840
                len -= sizeof srv_mysql50_table_name_prefix;
2874
2841
                goto convert_id;
2875
2842
        } else {
2876
2843
                /* Encode using filename-safe characters. */
2877
2844
                len = 5 * len + 1;
2878
 
                *id = dst = static_cast<char *>(mem_heap_alloc(heap, len));
 
2845
                *id = dst = mem_heap_alloc(heap, len);
2879
2846
 
2880
2847
                innobase_convert_from_table_id(cs, dst, str, len);
2881
2848
        }
3013
2980
        table_name_len = strlen(table_name);
3014
2981
 
3015
2982
        /* Copy database_name, '/', table_name, '\0' */
3016
 
        ref = static_cast<char *>(mem_heap_alloc(heap, database_name_len + table_name_len + 2));
 
2983
        ref = mem_heap_alloc(heap, database_name_len + table_name_len + 2);
3017
2984
        memcpy(ref, database_name, database_name_len);
3018
2985
        ref[database_name_len] = '/';
3019
2986
        memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
3080
3047
        /* unclosed quote character (0 if none) */
3081
3048
        char            quote   = 0;
3082
3049
 
3083
 
        str = static_cast<char *>(mem_alloc(sql_length + 1));
 
3050
        str = mem_alloc(sql_length + 1);
3084
3051
 
3085
3052
        sptr = sql_string;
3086
3053
        ptr = str;
3485
3452
                        start_of_latest_foreign);
3486
3453
                mutex_exit(&dict_foreign_err_mutex);
3487
3454
 
3488
 
                return(DB_CHILD_NO_INDEX);
 
3455
                return(DB_CANNOT_ADD_CONSTRAINT);
3489
3456
        }
3490
3457
        ptr = dict_accept(cs, ptr, "REFERENCES", &success);
3491
3458
 
3509
3476
 
3510
3477
                db_len = dict_get_db_name_len(table->name);
3511
3478
 
3512
 
                foreign->id = static_cast<char*>(mem_heap_alloc(
3513
 
                        foreign->heap, db_len + strlen(constraint_name) + 2));
 
3479
                foreign->id = mem_heap_alloc(
 
3480
                        foreign->heap, db_len + strlen(constraint_name) + 2);
3514
3481
 
3515
3482
                ut_memcpy(foreign->id, table->name, db_len);
3516
3483
                foreign->id[db_len] = '/';
3522
3489
                                                      table->name);
3523
3490
        foreign->foreign_index = index;
3524
3491
        foreign->n_fields = (unsigned int) i;
3525
 
        foreign->foreign_col_names = static_cast<const char **>(mem_heap_alloc(foreign->heap,
3526
 
                                                    i * sizeof(void*)));
 
3492
        foreign->foreign_col_names = mem_heap_alloc(foreign->heap,
 
3493
                                                    i * sizeof(void*));
3527
3494
        for (i = 0; i < foreign->n_fields; i++) {
3528
3495
                foreign->foreign_col_names[i] = mem_heap_strdup(
3529
3496
                        foreign->heap,
3766
3733
                                start_of_latest_foreign);
3767
3734
                        mutex_exit(&dict_foreign_err_mutex);
3768
3735
 
3769
 
                        return(DB_PARENT_NO_INDEX);
 
3736
                        return(DB_CANNOT_ADD_CONSTRAINT);
3770
3737
                }
3771
3738
        } else {
3772
3739
                ut_a(trx->check_foreigns == FALSE);
3779
3746
        foreign->referenced_table_name
3780
3747
                = mem_heap_strdup(foreign->heap, referenced_table_name);
3781
3748
 
3782
 
        foreign->referenced_col_names = static_cast<const char **>(mem_heap_alloc(foreign->heap,
3783
 
                                                       i * sizeof(void*)));
 
3749
        foreign->referenced_col_names = mem_heap_alloc(foreign->heap,
 
3750
                                                       i * sizeof(void*));
3784
3751
        for (i = 0; i < foreign->n_fields; i++) {
3785
3752
                foreign->referenced_col_names[i]
3786
3753
                        = mem_heap_strdup(foreign->heap, column_names[i]);
3838
3805
        heap = mem_heap_create(10000);
3839
3806
 
3840
3807
        err = dict_create_foreign_constraints_low(
3841
 
                trx, heap, trx->session()->charset(), str, name,
 
3808
                trx, heap, innobase_get_charset(trx->mysql_thd), str, name,
3842
3809
                reject_fks);
3843
3810
 
3844
3811
        mem_heap_free(heap);
3876
3843
        ut_a(trx);
3877
3844
        ut_a(trx->mysql_thd);
3878
3845
 
3879
 
        cs = trx->session()->charset();
 
3846
        cs = innobase_get_charset(trx->mysql_thd);
3880
3847
 
3881
3848
        *n = 0;
3882
3849
 
3883
 
        *constraints_to_drop = static_cast<const char **>(mem_heap_alloc(heap, 1000 * sizeof(char*)));
 
3850
        *constraints_to_drop = mem_heap_alloc(heap, 1000 * sizeof(char*));
3884
3851
 
3885
 
        ptr= trx->session()->getQueryStringCopy(len);
 
3852
        ptr = innobase_get_stmt(trx->mysql_thd, &len);
3886
3853
 
3887
3854
        str = dict_strip_comments(ptr, len);
3888
3855
 
4097
4064
 
4098
4065
        dict_index_copy_types(tuple, index, n_unique);
4099
4066
 
4100
 
        buf = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
 
4067
        buf = mem_heap_alloc(heap, 4);
4101
4068
 
4102
4069
        mach_write_to_4(buf, page_no);
4103
4070
 
4230
4197
are used in query optimization. */
4231
4198
UNIV_INTERN
4232
4199
void
4233
 
dict_update_statistics(
4234
 
/*===================*/
 
4200
dict_update_statistics_low(
 
4201
/*=======================*/
4235
4202
        dict_table_t*   table,          /*!< in/out: table */
4236
 
        ibool           only_calc_if_missing_stats)/*!< in: only
4237
 
                                        update/recalc the stats if they have
4238
 
                                        not been initialized yet, otherwise
4239
 
                                        do nothing */
 
4203
        ibool           has_dict_mutex __attribute__((unused)))
 
4204
                                        /*!< in: TRUE if the caller has the
 
4205
                                        dictionary mutex */
4240
4206
{
4241
4207
        dict_index_t*   index;
 
4208
        ulint           size;
4242
4209
        ulint           sum_of_index_sizes      = 0;
4243
4210
 
4244
4211
        if (table->ibd_file_missing) {
4253
4220
                return;
4254
4221
        }
4255
4222
 
 
4223
        /* If we have set a high innodb_force_recovery level, do not calculate
 
4224
        statistics, as a badly corrupted index can cause a crash in it. */
 
4225
 
 
4226
        if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
 
4227
 
 
4228
                return;
 
4229
        }
 
4230
 
4256
4231
        /* Find out the sizes of the indexes and how many different values
4257
4232
        for the key they approximately have */
4258
4233
 
4264
4239
                return;
4265
4240
        }
4266
4241
 
4267
 
        dict_table_stats_lock(table, RW_X_LATCH);
4268
 
 
4269
 
        if (only_calc_if_missing_stats && table->stat_initialized) {
4270
 
                dict_table_stats_unlock(table, RW_X_LATCH);
4271
 
                return;
4272
 
        }
4273
 
 
4274
 
        do {
4275
 
                if (UNIV_LIKELY
4276
 
                    (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE
4277
 
                     || (srv_force_recovery < SRV_FORCE_NO_LOG_REDO
4278
 
                         && dict_index_is_clust(index)))) {
4279
 
                        ulint   size;
4280
 
                        size = btr_get_size(index, BTR_TOTAL_SIZE);
4281
 
 
4282
 
                        index->stat_index_size = size;
4283
 
 
4284
 
                        sum_of_index_sizes += size;
4285
 
 
4286
 
                        size = btr_get_size(index, BTR_N_LEAF_PAGES);
4287
 
 
4288
 
                        if (size == 0) {
4289
 
                                /* The root node of the tree is a leaf */
4290
 
                                size = 1;
4291
 
                        }
4292
 
 
4293
 
                        index->stat_n_leaf_pages = size;
4294
 
 
4295
 
                        btr_estimate_number_of_different_key_vals(index);
4296
 
                } else {
4297
 
                        /* If we have set a high innodb_force_recovery
4298
 
                        level, do not calculate statistics, as a badly
4299
 
                        corrupted index can cause a crash in it.
4300
 
                        Initialize some bogus index cardinality
4301
 
                        statistics, so that the data can be queried in
4302
 
                        various means, also via secondary indexes. */
4303
 
                        ulint   i;
4304
 
 
4305
 
                        sum_of_index_sizes++;
4306
 
                        index->stat_index_size = index->stat_n_leaf_pages = 1;
4307
 
 
4308
 
                        for (i = dict_index_get_n_unique(index); i; ) {
4309
 
                                index->stat_n_diff_key_vals[i--] = 1;
4310
 
                        }
 
4242
        while (index) {
 
4243
                size = btr_get_size(index, BTR_TOTAL_SIZE);
 
4244
 
 
4245
                index->stat_index_size = size;
 
4246
 
 
4247
                sum_of_index_sizes += size;
 
4248
 
 
4249
                size = btr_get_size(index, BTR_N_LEAF_PAGES);
 
4250
 
 
4251
                if (size == 0) {
 
4252
                        /* The root node of the tree is a leaf */
 
4253
                        size = 1;
4311
4254
                }
4312
4255
 
 
4256
                index->stat_n_leaf_pages = size;
 
4257
 
 
4258
                btr_estimate_number_of_different_key_vals(index);
 
4259
 
4313
4260
                index = dict_table_get_next_index(index);
4314
 
        } while (index);
 
4261
        }
4315
4262
 
4316
4263
        index = dict_table_get_first_index(table);
4317
4264
 
 
4265
        dict_index_stat_mutex_enter(index);
 
4266
 
4318
4267
        table->stat_n_rows = index->stat_n_diff_key_vals[
4319
4268
                dict_index_get_n_unique(index)];
4320
4269
 
 
4270
        dict_index_stat_mutex_exit(index);
 
4271
 
4321
4272
        table->stat_clustered_index_size = index->stat_index_size;
4322
4273
 
4323
4274
        table->stat_sum_of_other_index_sizes = sum_of_index_sizes
4326
4277
        table->stat_initialized = TRUE;
4327
4278
 
4328
4279
        table->stat_modified_counter = 0;
 
4280
}
4329
4281
 
4330
 
        dict_table_stats_unlock(table, RW_X_LATCH);
 
4282
/*********************************************************************//**
 
4283
Calculates new estimates for table and index statistics. The statistics
 
4284
are used in query optimization. */
 
4285
UNIV_INTERN
 
4286
void
 
4287
dict_update_statistics(
 
4288
/*===================*/
 
4289
        dict_table_t*   table)  /*!< in/out: table */
 
4290
{
 
4291
        dict_update_statistics_low(table, FALSE);
4331
4292
}
4332
4293
 
4333
4294
/**********************************************************************//**
4407
4368
 
4408
4369
        ut_ad(mutex_own(&(dict_sys->mutex)));
4409
4370
 
4410
 
        dict_update_statistics(table, FALSE /* update even if initialized */);
4411
 
 
4412
 
        dict_table_stats_lock(table, RW_S_LATCH);
 
4371
        dict_update_statistics_low(table, TRUE);
4413
4372
 
4414
4373
        fprintf(stderr,
4415
4374
                "--------------------------------------\n"
4437
4396
                index = UT_LIST_GET_NEXT(indexes, index);
4438
4397
        }
4439
4398
 
4440
 
        dict_table_stats_unlock(table, RW_S_LATCH);
4441
 
 
4442
4399
        foreign = UT_LIST_GET_FIRST(table->foreign_list);
4443
4400
 
4444
4401
        while (foreign != NULL) {
4484
4441
{
4485
4442
        ib_int64_t      n_vals;
4486
4443
        ulint           i;
 
4444
        const char*     type_string;
4487
4445
 
4488
4446
        ut_ad(mutex_own(&(dict_sys->mutex)));
4489
4447
 
 
4448
        dict_index_stat_mutex_enter(index);
 
4449
 
4490
4450
        if (index->n_user_defined_cols > 0) {
4491
4451
                n_vals = index->stat_n_diff_key_vals[
4492
4452
                        index->n_user_defined_cols];
4494
4454
                n_vals = index->stat_n_diff_key_vals[1];
4495
4455
        }
4496
4456
 
 
4457
        dict_index_stat_mutex_exit(index);
 
4458
 
 
4459
        if (dict_index_is_clust(index)) {
 
4460
                type_string = "clustered index";
 
4461
        } else if (dict_index_is_unique(index)) {
 
4462
                type_string = "unique index";
 
4463
        } else {
 
4464
                type_string = "secondary index";
 
4465
        }
 
4466
 
4497
4467
        fprintf(stderr,
4498
4468
                "  INDEX: name %s, id %llu, fields %lu/%lu,"
4499
4469
                " uniq %lu, type %lu\n"
4836
4806
dict_table_replace_index_in_foreign_list(
4837
4807
/*=====================================*/
4838
4808
        dict_table_t*   table,  /*!< in/out: table */
4839
 
        dict_index_t*   index,  /*!< in: index to be replaced */
4840
 
        const trx_t*    trx)    /*!< in: transaction handle */
 
4809
        dict_index_t*   index)  /*!< in: index to be replaced */
4841
4810
{
4842
4811
        dict_foreign_t* foreign;
4843
4812
 
4848
4817
                if (foreign->foreign_index == index) {
4849
4818
                        dict_index_t*   new_index
4850
4819
                                = dict_foreign_find_equiv_index(foreign);
4851
 
 
4852
 
                        /* There must exist an alternative index if
4853
 
                        check_foreigns (FOREIGN_KEY_CHECKS) is on, 
4854
 
                        since ha_innobase::prepare_drop_index had done
4855
 
                        the check before we reach here. */
4856
 
 
4857
 
                        ut_a(new_index || !trx->check_foreigns);
 
4820
                        ut_a(new_index);
4858
4821
 
4859
4822
                        foreign->foreign_index = new_index;
4860
4823
                }
4951
4914
        for (i = 0; i < hash_get_n_cells(dict_sys->table_hash); i++) {
4952
4915
                dict_table_t*   table;
4953
4916
 
4954
 
                table = static_cast<dict_table_t *>(HASH_GET_FIRST(dict_sys->table_hash, i));
 
4917
                table = HASH_GET_FIRST(dict_sys->table_hash, i);
4955
4918
 
4956
4919
                while (table) {
4957
4920
                        dict_table_t*   prev_table = table;
4958
4921
 
4959
 
                        table = static_cast<dict_table_t *>(HASH_GET_NEXT(name_hash, prev_table));
 
4922
                        table = HASH_GET_NEXT(name_hash, prev_table);
4960
4923
#ifdef UNIV_DEBUG
4961
4924
                        ut_a(prev_table->magic_n == DICT_TABLE_MAGIC_N);
4962
4925
#endif
4987
4950
        mem_free(dict_sys);
4988
4951
        dict_sys = NULL;
4989
4952
 
4990
 
        for (i = 0; i < DICT_TABLE_STATS_LATCHES_SIZE; i++) {
4991
 
                rw_lock_free(&dict_table_stats_latches[i]);
 
4953
        for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) {
 
4954
                mutex_free(&dict_index_stat_mutex[i]);
4992
4955
        }
4993
4956
}
4994
4957
#endif /* !UNIV_HOTBACKUP */