~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/dict/dict0dict.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:
90
90
/** Identifies generated InnoDB foreign key names */
91
91
static char     dict_ibfk[] = "_ibfk_";
92
92
 
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];
 
93
/** array of rw locks protecting
 
94
dict_table_t::stat_initialized
 
95
dict_table_t::stat_n_rows (*)
 
96
dict_table_t::stat_clustered_index_size
 
97
dict_table_t::stat_sum_of_other_index_sizes
 
98
dict_table_t::stat_modified_counter (*)
 
99
dict_table_t::indexes*::stat_n_diff_key_vals[]
 
100
dict_table_t::indexes*::stat_index_size
 
101
dict_table_t::indexes*::stat_n_leaf_pages
 
102
(*) those are not always protected for performance reasons */
 
103
#define DICT_TABLE_STATS_LATCHES_SIZE   64
 
104
static rw_lock_t        dict_table_stats_latches[DICT_TABLE_STATS_LATCHES_SIZE];
96
105
 
97
106
/*******************************************************************//**
98
107
Tries to find column names for the index and sets the col field of the
253
262
        mutex_exit(&(dict_sys->mutex));
254
263
}
255
264
 
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])
 
265
/** Get the latch that protects the stats of a given table */
 
266
#define GET_TABLE_STATS_LATCH(table) \
 
267
        (&dict_table_stats_latches[ut_fold_ull(table->id) \
 
268
                                   % DICT_TABLE_STATS_LATCHES_SIZE])
260
269
 
261
270
/**********************************************************************//**
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. */
 
271
Lock the appropriate latch to protect a given table's statistics.
 
272
table->id is used to pick the corresponding latch from a global array of
 
273
latches. */
265
274
UNIV_INTERN
266
275
void
267
 
dict_index_stat_mutex_enter(
268
 
/*========================*/
269
 
        const dict_index_t*     index)  /*!< in: index */
 
276
dict_table_stats_lock(
 
277
/*==================*/
 
278
        const dict_table_t*     table,          /*!< in: table */
 
279
        ulint                   latch_mode)     /*!< in: RW_S_LATCH or
 
280
                                                RW_X_LATCH */
270
281
{
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);
 
282
        ut_ad(table != NULL);
 
283
        ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
275
284
 
276
 
        mutex_enter(GET_INDEX_STAT_MUTEX(index));
 
285
        switch (latch_mode) {
 
286
        case RW_S_LATCH:
 
287
                rw_lock_s_lock(GET_TABLE_STATS_LATCH(table));
 
288
                break;
 
289
        case RW_X_LATCH:
 
290
                rw_lock_x_lock(GET_TABLE_STATS_LATCH(table));
 
291
                break;
 
292
        case RW_NO_LATCH:
 
293
                /* fall through */
 
294
        default:
 
295
                ut_error;
 
296
        }
277
297
}
278
298
 
279
299
/**********************************************************************//**
280
 
Unlock the appropriate mutex that protects index->stat_n_diff_key_vals[]. */
 
300
Unlock the latch that has been locked by dict_table_stats_lock() */
281
301
UNIV_INTERN
282
302
void
283
 
dict_index_stat_mutex_exit(
284
 
/*=======================*/
285
 
        const dict_index_t*     index)  /*!< in: index */
 
303
dict_table_stats_unlock(
 
304
/*====================*/
 
305
        const dict_table_t*     table,          /*!< in: table */
 
306
        ulint                   latch_mode)     /*!< in: RW_S_LATCH or
 
307
                                                RW_X_LATCH */
286
308
{
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);
 
309
        ut_ad(table != NULL);
 
310
        ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
291
311
 
292
 
        mutex_exit(GET_INDEX_STAT_MUTEX(index));
 
312
        switch (latch_mode) {
 
313
        case RW_S_LATCH:
 
314
                rw_lock_s_unlock(GET_TABLE_STATS_LATCH(table));
 
315
                break;
 
316
        case RW_X_LATCH:
 
317
                rw_lock_x_unlock(GET_TABLE_STATS_LATCH(table));
 
318
                break;
 
319
        case RW_NO_LATCH:
 
320
                /* fall through */
 
321
        default:
 
322
                ut_error;
 
323
        }
293
324
}
294
325
 
295
326
/********************************************************************//**
680
711
        mutex_create(dict_foreign_err_mutex_key,
681
712
                     &dict_foreign_err_mutex, SYNC_ANY_LATCH);
682
713
 
683
 
        for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) {
684
 
          mutex_create(PFS_NOT_INSTRUMENTED,
685
 
                       &dict_index_stat_mutex[i], SYNC_INDEX_TREE);
686
 
        }
 
714
        for (i = 0; i < DICT_TABLE_STATS_LATCHES_SIZE; i++) {
 
715
                rw_lock_create(PFS_NOT_INSTRUMENTED,
 
716
                               &dict_table_stats_latches[i], SYNC_INDEX_TREE);
 
717
        }
687
718
}
688
719
 
689
720
/**********************************************************************//**
713
744
        mutex_exit(&(dict_sys->mutex));
714
745
 
715
746
        if (table != NULL) {
716
 
                if (!table->stat_initialized) {
717
 
                        /* If table->ibd_file_missing == TRUE, this will
718
 
                        print an error message and return without doing
719
 
                        anything. */
720
 
                        dict_update_statistics(table);
721
 
                }
 
747
                /* If table->ibd_file_missing == TRUE, this will
 
748
                print an error message and return without doing
 
749
                anything. */
 
750
                dict_update_statistics(table, TRUE /* only update stats
 
751
                                       if they have not been initialized */);
722
752
        }
723
753
 
724
754
        return(table);
3451
3481
                        start_of_latest_foreign);
3452
3482
                mutex_exit(&dict_foreign_err_mutex);
3453
3483
 
3454
 
                return(DB_CANNOT_ADD_CONSTRAINT);
 
3484
                return(DB_CHILD_NO_INDEX);
3455
3485
        }
3456
3486
        ptr = dict_accept(cs, ptr, "REFERENCES", &success);
3457
3487
 
3732
3762
                                start_of_latest_foreign);
3733
3763
                        mutex_exit(&dict_foreign_err_mutex);
3734
3764
 
3735
 
                        return(DB_CANNOT_ADD_CONSTRAINT);
 
3765
                        return(DB_PARENT_NO_INDEX);
3736
3766
                }
3737
3767
        } else {
3738
3768
                ut_a(trx->check_foreigns == FALSE);
4196
4226
are used in query optimization. */
4197
4227
UNIV_INTERN
4198
4228
void
4199
 
dict_update_statistics_low(
4200
 
/*=======================*/
 
4229
dict_update_statistics(
 
4230
/*===================*/
4201
4231
        dict_table_t*   table,          /*!< in/out: table */
4202
 
        ibool           has_dict_mutex __attribute__((unused)))
4203
 
                                        /*!< in: TRUE if the caller has the
4204
 
                                        dictionary mutex */
 
4232
        ibool           only_calc_if_missing_stats)/*!< in: only
 
4233
                                        update/recalc the stats if they have
 
4234
                                        not been initialized yet, otherwise
 
4235
                                        do nothing */
4205
4236
{
4206
4237
        dict_index_t*   index;
4207
4238
        ulint           sum_of_index_sizes      = 0;
4229
4260
                return;
4230
4261
        }
4231
4262
 
 
4263
        dict_table_stats_lock(table, RW_X_LATCH);
 
4264
 
 
4265
        if (only_calc_if_missing_stats && table->stat_initialized) {
 
4266
                dict_table_stats_unlock(table, RW_X_LATCH);
 
4267
                return;
 
4268
        }
4232
4269
 
4233
4270
        do {
4234
4271
                if (UNIV_LIKELY
4274
4311
 
4275
4312
        index = dict_table_get_first_index(table);
4276
4313
 
4277
 
        dict_index_stat_mutex_enter(index);
4278
 
 
4279
4314
        table->stat_n_rows = index->stat_n_diff_key_vals[
4280
4315
                dict_index_get_n_unique(index)];
4281
4316
 
4282
 
        dict_index_stat_mutex_exit(index);
4283
 
 
4284
4317
        table->stat_clustered_index_size = index->stat_index_size;
4285
4318
 
4286
4319
        table->stat_sum_of_other_index_sizes = sum_of_index_sizes
4289
4322
        table->stat_initialized = TRUE;
4290
4323
 
4291
4324
        table->stat_modified_counter = 0;
4292
 
}
4293
4325
 
4294
 
/*********************************************************************//**
4295
 
Calculates new estimates for table and index statistics. The statistics
4296
 
are used in query optimization. */
4297
 
UNIV_INTERN
4298
 
void
4299
 
dict_update_statistics(
4300
 
/*===================*/
4301
 
        dict_table_t*   table)  /*!< in/out: table */
4302
 
{
4303
 
        dict_update_statistics_low(table, FALSE);
 
4326
        dict_table_stats_unlock(table, RW_X_LATCH);
4304
4327
}
4305
4328
 
4306
4329
/**********************************************************************//**
4380
4403
 
4381
4404
        ut_ad(mutex_own(&(dict_sys->mutex)));
4382
4405
 
4383
 
        dict_update_statistics_low(table, TRUE);
 
4406
        dict_update_statistics(table, FALSE /* update even if initialized */);
 
4407
 
 
4408
        dict_table_stats_lock(table, RW_S_LATCH);
4384
4409
 
4385
4410
        fprintf(stderr,
4386
4411
                "--------------------------------------\n"
4408
4433
                index = UT_LIST_GET_NEXT(indexes, index);
4409
4434
        }
4410
4435
 
 
4436
        dict_table_stats_unlock(table, RW_S_LATCH);
 
4437
 
4411
4438
        foreign = UT_LIST_GET_FIRST(table->foreign_list);
4412
4439
 
4413
4440
        while (foreign != NULL) {
4456
4483
 
4457
4484
        ut_ad(mutex_own(&(dict_sys->mutex)));
4458
4485
 
4459
 
        dict_index_stat_mutex_enter(index);
4460
 
 
4461
4486
        if (index->n_user_defined_cols > 0) {
4462
4487
                n_vals = index->stat_n_diff_key_vals[
4463
4488
                        index->n_user_defined_cols];
4465
4490
                n_vals = index->stat_n_diff_key_vals[1];
4466
4491
        }
4467
4492
 
4468
 
        dict_index_stat_mutex_exit(index);
4469
 
 
4470
4493
        fprintf(stderr,
4471
4494
                "  INDEX: name %s, id %llu, fields %lu/%lu,"
4472
4495
                " uniq %lu, type %lu\n"
4809
4832
dict_table_replace_index_in_foreign_list(
4810
4833
/*=====================================*/
4811
4834
        dict_table_t*   table,  /*!< in/out: table */
4812
 
        dict_index_t*   index)  /*!< in: index to be replaced */
 
4835
        dict_index_t*   index,  /*!< in: index to be replaced */
 
4836
        const trx_t*    trx)    /*!< in: transaction handle */
4813
4837
{
4814
4838
        dict_foreign_t* foreign;
4815
4839
 
4820
4844
                if (foreign->foreign_index == index) {
4821
4845
                        dict_index_t*   new_index
4822
4846
                                = dict_foreign_find_equiv_index(foreign);
4823
 
                        ut_a(new_index);
 
4847
 
 
4848
                        /* There must exist an alternative index if
 
4849
                        check_foreigns (FOREIGN_KEY_CHECKS) is on, 
 
4850
                        since ha_innobase::prepare_drop_index had done
 
4851
                        the check before we reach here. */
 
4852
 
 
4853
                        ut_a(new_index || !trx->check_foreigns);
4824
4854
 
4825
4855
                        foreign->foreign_index = new_index;
4826
4856
                }
4953
4983
        mem_free(dict_sys);
4954
4984
        dict_sys = NULL;
4955
4985
 
4956
 
        for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) {
4957
 
                mutex_free(&dict_index_stat_mutex[i]);
 
4986
        for (i = 0; i < DICT_TABLE_STATS_LATCHES_SIZE; i++) {
 
4987
                rw_lock_free(&dict_table_stats_latches[i]);
4958
4988
        }
4959
4989
}
4960
4990
#endif /* !UNIV_HOTBACKUP */