@@ -406,7 +406,9 @@ dict_stats_table_clone_create(
406406
407407dict_table_t * t;
408408
409- t = (dict_table_t *) mem_heap_alloc (heap, sizeof (*t));
409+ t = (dict_table_t *) mem_heap_zalloc (heap, sizeof (*t));
410+
411+ t->stats_mutex_init ();
410412
411413MEM_CHECK_DEFINED (&table->id , sizeof (table->id ));
412414t->id = table->id ;
@@ -434,7 +436,7 @@ dict_stats_table_clone_create(
434436
435437dict_index_t * idx;
436438
437- idx = (dict_index_t *) mem_heap_alloc (heap, sizeof (*idx));
439+ idx = (dict_index_t *) mem_heap_zalloc (heap, sizeof (*idx));
438440
439441MEM_CHECK_DEFINED (&index->id , sizeof (index->id ));
440442idx->id = index->id ;
@@ -452,7 +454,7 @@ dict_stats_table_clone_create(
452454
453455idx->n_uniq = index->n_uniq ;
454456
455- idx->fields = (dict_field_t *) mem_heap_alloc (
457+ idx->fields = (dict_field_t *) mem_heap_zalloc (
456458heap, idx->n_uniq * sizeof (idx->fields [0 ]));
457459
458460for (ulint i = 0 ; i < idx->n_uniq ; i++) {
@@ -463,15 +465,15 @@ dict_stats_table_clone_create(
463465/* hook idx into t->indexes */
464466UT_LIST_ADD_LAST (t->indexes , idx);
465467
466- idx->stat_n_diff_key_vals = (ib_uint64_t *) mem_heap_alloc (
468+ idx->stat_n_diff_key_vals = (ib_uint64_t *) mem_heap_zalloc (
467469heap,
468470idx->n_uniq * sizeof (idx->stat_n_diff_key_vals [0 ]));
469471
470- idx->stat_n_sample_sizes = (ib_uint64_t *) mem_heap_alloc (
472+ idx->stat_n_sample_sizes = (ib_uint64_t *) mem_heap_zalloc (
471473heap,
472474idx->n_uniq * sizeof (idx->stat_n_sample_sizes [0 ]));
473475
474- idx->stat_n_non_null_key_vals = (ib_uint64_t *) mem_heap_alloc (
476+ idx->stat_n_non_null_key_vals = (ib_uint64_t *) mem_heap_zalloc (
475477heap,
476478idx->n_uniq * sizeof (idx->stat_n_non_null_key_vals [0 ]));
477479ut_d (idx->magic_n = DICT_INDEX_MAGIC_N);
@@ -494,6 +496,7 @@ dict_stats_table_clone_free(
494496/* ========================*/
495497dict_table_t * t)/* !< in: dummy table object to free */
496498{
499+ t->stats_mutex_destroy ();
497500mem_heap_free (t->heap );
498501}
499502
@@ -510,7 +513,7 @@ dict_stats_empty_index(
510513{
511514ut_ad (!(index->type & DICT_FTS));
512515ut_ad (!dict_index_is_ibuf (index));
513- dict_sys. assert_locked ( );
516+ ut_ad (index-> table -> stats_mutex_is_owner () );
514517
515518ulint n_uniq = index->n_uniq ;
516519
@@ -540,7 +543,9 @@ dict_stats_empty_table(
540543bool empty_defrag_stats)
541544/* !< in: whether to empty defrag stats */
542545{
543- dict_sys.mutex_lock ();
546+ /* Initialize table/index level stats is now protected by
547+ table level lock_mutex.*/
548+ table->stats_mutex_lock ();
544549
545550/* Zero the stats members */
546551table->stat_n_rows = 0 ;
@@ -566,7 +571,7 @@ dict_stats_empty_table(
566571}
567572
568573table->stat_initialized = TRUE ;
569- dict_sys. mutex_unlock ();
574+ table-> stats_mutex_unlock ();
570575}
571576
572577/* ********************************************************************/ /* *
@@ -665,7 +670,8 @@ dict_stats_copy(
665670 to have the same statistics as if
666671 the table was empty */
667672{
668- dict_sys.assert_locked ();
673+ ut_ad (src->stats_mutex_is_owner ());
674+ ut_ad (dst->stats_mutex_is_owner ());
669675
670676dst->stats_last_recalc = src->stats_last_recalc ;
671677dst->stat_n_rows = src->stat_n_rows ;
@@ -790,8 +796,14 @@ dict_stats_snapshot_create(
790796
791797t = dict_stats_table_clone_create (table);
792798
799+ table->stats_mutex_lock ();
800+ ut_d (t->stats_mutex_lock ());
801+
793802dict_stats_copy (t, table, false );
794803
804+ ut_d (t->stats_mutex_unlock ());
805+ table->stats_mutex_unlock ();
806+
795807t->stat_persistent = table->stat_persistent ;
796808t->stats_auto_recalc = table->stats_auto_recalc ;
797809t->stats_sample_pages = table->stats_sample_pages ;
@@ -836,14 +848,14 @@ dict_stats_update_transient_for_index(
836848Initialize some bogus index cardinality
837849statistics, so that the data can be queried in
838850various means, also via secondary indexes. */
839- dict_sys. mutex_lock ();
851+ index-> table -> stats_mutex_lock ();
840852dict_stats_empty_index (index, false );
841- dict_sys. mutex_unlock ();
853+ index-> table -> stats_mutex_unlock ();
842854#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
843855} else if (ibuf_debug && !dict_index_is_clust (index)) {
844- dict_sys. mutex_lock ();
856+ index-> table -> stats_mutex_lock ();
845857dict_stats_empty_index (index, false );
846- dict_sys. mutex_unlock ();
858+ index-> table -> stats_mutex_unlock ();
847859#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
848860} else {
849861mtr_t mtr;
@@ -864,9 +876,9 @@ dict_stats_update_transient_for_index(
864876
865877switch (size) {
866878case ULINT_UNDEFINED:
867- dict_sys. mutex_lock ();
879+ index-> table -> stats_mutex_lock ();
868880dict_stats_empty_index (index, false );
869- dict_sys. mutex_unlock ();
881+ index-> table -> stats_mutex_unlock ();
870882return ;
871883case 0 :
872884/* The root node of the tree is a leaf */
@@ -883,7 +895,7 @@ dict_stats_update_transient_for_index(
883895index);
884896
885897if (!stats.empty ()) {
886- dict_sys. mutex_lock ();
898+ index-> table -> stats_mutex_lock ();
887899for (size_t i = 0 ; i < stats.size (); ++i) {
888900index->stat_n_diff_key_vals [i]
889901= stats[i].n_diff_key_vals ;
@@ -892,7 +904,7 @@ dict_stats_update_transient_for_index(
892904index->stat_n_non_null_key_vals [i]
893905= stats[i].n_non_null_key_vals ;
894906}
895- dict_sys. mutex_unlock ();
907+ index-> table -> stats_mutex_unlock ();
896908}
897909}
898910}
@@ -910,7 +922,7 @@ dict_stats_update_transient(
910922/* ========================*/
911923dict_table_t * table)/* !< in/out: table */
912924{
913- dict_sys. assert_not_locked ( );
925+ ut_ad (!table-> stats_mutex_is_owner () );
914926
915927dict_index_t * index;
916928ulint sum_of_index_sizes = 0 ;
@@ -943,9 +955,9 @@ dict_stats_update_transient(
943955
944956if (dict_stats_should_ignore_index (index)
945957 || !index->is_readable ()) {
946- dict_sys. mutex_lock ();
958+ index-> table -> stats_mutex_lock ();
947959dict_stats_empty_index (index, false );
948- dict_sys. mutex_unlock ();
960+ index-> table -> stats_mutex_unlock ();
949961continue ;
950962}
951963
@@ -954,7 +966,7 @@ dict_stats_update_transient(
954966sum_of_index_sizes += index->stat_index_size ;
955967}
956968
957- dict_sys. mutex_lock ();
969+ table-> stats_mutex_lock ();
958970
959971index = dict_table_get_first_index (table);
960972
@@ -972,7 +984,7 @@ dict_stats_update_transient(
972984
973985table->stat_initialized = TRUE ;
974986
975- dict_sys. mutex_unlock ();
987+ table-> stats_mutex_unlock ();
976988}
977989
978990/* @{ Pseudo code about the relation between the following functions
@@ -1930,7 +1942,7 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index)
19301942DBUG_PRINT (" info" , (" index: %s, online status: %d" , index->name (),
19311943 dict_index_get_online_status (index)));
19321944
1933- dict_sys. assert_not_locked (); // this function is slow
1945+ ut_ad (!index-> table -> stats_mutex_is_owner ());
19341946ut_ad (index->table ->get_ref_count ());
19351947
19361948/* Disable update statistic for Rtree */
@@ -2002,14 +2014,14 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index)
20022014
20032015mtr.commit ();
20042016
2005- dict_sys. mutex_lock ();
2017+ index-> table -> stats_mutex_lock ();
20062018for (ulint i = 0 ; i < n_uniq; i++) {
20072019result.stats [i].n_diff_key_vals = index->stat_n_diff_key_vals [i];
20082020result.stats [i].n_sample_sizes = total_pages;
20092021result.stats [i].n_non_null_key_vals = index->stat_n_non_null_key_vals [i];
20102022}
20112023result.n_leaf_pages = index->stat_n_leaf_pages ;
2012- dict_sys. mutex_unlock ();
2024+ index-> table -> stats_mutex_unlock ();
20132025
20142026DBUG_RETURN (result);
20152027}
@@ -2243,13 +2255,13 @@ dict_stats_update_persistent(
22432255}
22442256
22452257ut_ad (!dict_index_is_ibuf (index));
2246- dict_sys. mutex_lock ();
2258+ table-> stats_mutex_lock ();
22472259dict_stats_empty_index (index, false );
2248- dict_sys. mutex_unlock ();
2260+ table-> stats_mutex_unlock ();
22492261
22502262index_stats_t stats = dict_stats_analyze_index (index);
22512263
2252- dict_sys. mutex_lock ();
2264+ table-> stats_mutex_lock ();
22532265index->stat_index_size = stats.index_size ;
22542266index->stat_n_leaf_pages = stats.n_leaf_pages ;
22552267for (size_t i = 0 ; i < stats.stats .size (); ++i) {
@@ -2285,9 +2297,9 @@ dict_stats_update_persistent(
22852297}
22862298
22872299if (!(table->stats_bg_flag & BG_STAT_SHOULD_QUIT)) {
2288- dict_sys. mutex_unlock ();
2300+ table-> stats_mutex_unlock ();
22892301stats = dict_stats_analyze_index (index);
2290- dict_sys. mutex_lock ();
2302+ table-> stats_mutex_lock ();
22912303
22922304index->stat_index_size = stats.index_size ;
22932305index->stat_n_leaf_pages = stats.n_leaf_pages ;
@@ -2313,7 +2325,7 @@ dict_stats_update_persistent(
23132325
23142326dict_stats_assert_initialized (table);
23152327
2316- dict_sys. mutex_unlock ();
2328+ table-> stats_mutex_unlock ();
23172329
23182330return (DB_SUCCESS);
23192331}
@@ -3123,13 +3135,11 @@ dict_stats_update_for_index(
31233135{
31243136DBUG_ENTER (" dict_stats_update_for_index" );
31253137
3126- dict_sys.assert_not_locked ();
3127-
31283138if (dict_stats_is_persistent_enabled (index->table )) {
31293139
31303140if (dict_stats_persistent_storage_check (false )) {
31313141index_stats_t stats = dict_stats_analyze_index (index);
3132- dict_sys. mutex_lock ();
3142+ index-> table -> stats_mutex_lock ();
31333143index->stat_index_size = stats.index_size ;
31343144index->stat_n_leaf_pages = stats.n_leaf_pages ;
31353145for (size_t i = 0 ; i < stats.stats .size (); ++i) {
@@ -3142,7 +3152,7 @@ dict_stats_update_for_index(
31423152}
31433153index->table ->stat_sum_of_other_index_sizes
31443154+= index->stat_index_size ;
3145- dict_sys. mutex_unlock ();
3155+ index-> table -> stats_mutex_unlock ();
31463156
31473157dict_stats_save (index->table , &index->id );
31483158DBUG_VOID_RETURN;
@@ -3183,7 +3193,7 @@ dict_stats_update(
31833193the persistent statistics
31843194storage */
31853195{
3186- dict_sys. assert_not_locked ( );
3196+ ut_ad (!table-> stats_mutex_is_owner () );
31873197
31883198if (!table->is_readable ()) {
31893199return (dict_stats_report_error (table));
@@ -3318,7 +3328,10 @@ dict_stats_update(
33183328switch (err) {
33193329case DB_SUCCESS:
33203330
3321- dict_sys.mutex_lock ();
3331+ table->stats_mutex_lock ();
3332+ /* t is localized to this thread so no need to
3333+ take stats mutex lock (limiting it to debug only) */
3334+ ut_d (t->stats_mutex_lock ());
33223335
33233336/* Pass reset_ignored_indexes=true as parameter
33243337to dict_stats_copy. This will cause statictics
@@ -3327,7 +3340,8 @@ dict_stats_update(
33273340
33283341dict_stats_assert_initialized (table);
33293342
3330- dict_sys.mutex_unlock ();
3343+ ut_d (t->stats_mutex_unlock ());
3344+ table->stats_mutex_unlock ();
33313345
33323346dict_stats_table_clone_free (t);
33333347
0 commit comments