@@ -406,7 +406,9 @@ dict_stats_table_clone_create(
406
406
407
407
dict_table_t * t;
408
408
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 ();
410
412
411
413
MEM_CHECK_DEFINED (&table->id , sizeof (table->id ));
412
414
t->id = table->id ;
@@ -434,7 +436,7 @@ dict_stats_table_clone_create(
434
436
435
437
dict_index_t * idx;
436
438
437
- idx = (dict_index_t *) mem_heap_alloc (heap, sizeof (*idx));
439
+ idx = (dict_index_t *) mem_heap_zalloc (heap, sizeof (*idx));
438
440
439
441
MEM_CHECK_DEFINED (&index->id , sizeof (index->id ));
440
442
idx->id = index->id ;
@@ -452,7 +454,7 @@ dict_stats_table_clone_create(
452
454
453
455
idx->n_uniq = index->n_uniq ;
454
456
455
- idx->fields = (dict_field_t *) mem_heap_alloc (
457
+ idx->fields = (dict_field_t *) mem_heap_zalloc (
456
458
heap, idx->n_uniq * sizeof (idx->fields [0 ]));
457
459
458
460
for (ulint i = 0 ; i < idx->n_uniq ; i++) {
@@ -463,15 +465,15 @@ dict_stats_table_clone_create(
463
465
/* hook idx into t->indexes */
464
466
UT_LIST_ADD_LAST (t->indexes , idx);
465
467
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 (
467
469
heap,
468
470
idx->n_uniq * sizeof (idx->stat_n_diff_key_vals [0 ]));
469
471
470
- idx->stat_n_sample_sizes = (ib_uint64_t *) mem_heap_alloc (
472
+ idx->stat_n_sample_sizes = (ib_uint64_t *) mem_heap_zalloc (
471
473
heap,
472
474
idx->n_uniq * sizeof (idx->stat_n_sample_sizes [0 ]));
473
475
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 (
475
477
heap,
476
478
idx->n_uniq * sizeof (idx->stat_n_non_null_key_vals [0 ]));
477
479
ut_d (idx->magic_n = DICT_INDEX_MAGIC_N);
@@ -494,6 +496,7 @@ dict_stats_table_clone_free(
494
496
/* ========================*/
495
497
dict_table_t * t) /* !< in: dummy table object to free */
496
498
{
499
+ t->stats_mutex_destroy ();
497
500
mem_heap_free (t->heap );
498
501
}
499
502
@@ -510,7 +513,7 @@ dict_stats_empty_index(
510
513
{
511
514
ut_ad (!(index->type & DICT_FTS));
512
515
ut_ad (!dict_index_is_ibuf (index));
513
- dict_sys. assert_locked ( );
516
+ ut_ad (index-> table -> stats_mutex_is_owner () );
514
517
515
518
ulint n_uniq = index->n_uniq ;
516
519
@@ -540,7 +543,9 @@ dict_stats_empty_table(
540
543
bool empty_defrag_stats)
541
544
/* !< in: whether to empty defrag stats */
542
545
{
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 ();
544
549
545
550
/* Zero the stats members */
546
551
table->stat_n_rows = 0 ;
@@ -566,7 +571,7 @@ dict_stats_empty_table(
566
571
}
567
572
568
573
table->stat_initialized = TRUE ;
569
- dict_sys. mutex_unlock ();
574
+ table-> stats_mutex_unlock ();
570
575
}
571
576
572
577
/* ********************************************************************/ /* *
@@ -665,7 +670,8 @@ dict_stats_copy(
665
670
to have the same statistics as if
666
671
the table was empty */
667
672
{
668
- dict_sys.assert_locked ();
673
+ ut_ad (src->stats_mutex_is_owner ());
674
+ ut_ad (dst->stats_mutex_is_owner ());
669
675
670
676
dst->stats_last_recalc = src->stats_last_recalc ;
671
677
dst->stat_n_rows = src->stat_n_rows ;
@@ -790,8 +796,14 @@ dict_stats_snapshot_create(
790
796
791
797
t = dict_stats_table_clone_create (table);
792
798
799
+ table->stats_mutex_lock ();
800
+ ut_d (t->stats_mutex_lock ());
801
+
793
802
dict_stats_copy (t, table, false );
794
803
804
+ ut_d (t->stats_mutex_unlock ());
805
+ table->stats_mutex_unlock ();
806
+
795
807
t->stat_persistent = table->stat_persistent ;
796
808
t->stats_auto_recalc = table->stats_auto_recalc ;
797
809
t->stats_sample_pages = table->stats_sample_pages ;
@@ -836,14 +848,14 @@ dict_stats_update_transient_for_index(
836
848
Initialize some bogus index cardinality
837
849
statistics, so that the data can be queried in
838
850
various means, also via secondary indexes. */
839
- dict_sys. mutex_lock ();
851
+ index-> table -> stats_mutex_lock ();
840
852
dict_stats_empty_index (index, false );
841
- dict_sys. mutex_unlock ();
853
+ index-> table -> stats_mutex_unlock ();
842
854
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
843
855
} else if (ibuf_debug && !dict_index_is_clust (index)) {
844
- dict_sys. mutex_lock ();
856
+ index-> table -> stats_mutex_lock ();
845
857
dict_stats_empty_index (index, false );
846
- dict_sys. mutex_unlock ();
858
+ index-> table -> stats_mutex_unlock ();
847
859
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
848
860
} else {
849
861
mtr_t mtr;
@@ -864,9 +876,9 @@ dict_stats_update_transient_for_index(
864
876
865
877
switch (size) {
866
878
case ULINT_UNDEFINED:
867
- dict_sys. mutex_lock ();
879
+ index-> table -> stats_mutex_lock ();
868
880
dict_stats_empty_index (index, false );
869
- dict_sys. mutex_unlock ();
881
+ index-> table -> stats_mutex_unlock ();
870
882
return ;
871
883
case 0 :
872
884
/* The root node of the tree is a leaf */
@@ -883,7 +895,7 @@ dict_stats_update_transient_for_index(
883
895
index);
884
896
885
897
if (!stats.empty ()) {
886
- dict_sys. mutex_lock ();
898
+ index-> table -> stats_mutex_lock ();
887
899
for (size_t i = 0 ; i < stats.size (); ++i) {
888
900
index->stat_n_diff_key_vals [i]
889
901
= stats[i].n_diff_key_vals ;
@@ -892,7 +904,7 @@ dict_stats_update_transient_for_index(
892
904
index->stat_n_non_null_key_vals [i]
893
905
= stats[i].n_non_null_key_vals ;
894
906
}
895
- dict_sys. mutex_unlock ();
907
+ index-> table -> stats_mutex_unlock ();
896
908
}
897
909
}
898
910
}
@@ -910,7 +922,7 @@ dict_stats_update_transient(
910
922
/* ========================*/
911
923
dict_table_t * table) /* !< in/out: table */
912
924
{
913
- dict_sys. assert_not_locked ( );
925
+ ut_ad (!table-> stats_mutex_is_owner () );
914
926
915
927
dict_index_t * index;
916
928
ulint sum_of_index_sizes = 0 ;
@@ -943,9 +955,9 @@ dict_stats_update_transient(
943
955
944
956
if (dict_stats_should_ignore_index (index)
945
957
|| !index->is_readable ()) {
946
- dict_sys. mutex_lock ();
958
+ index-> table -> stats_mutex_lock ();
947
959
dict_stats_empty_index (index, false );
948
- dict_sys. mutex_unlock ();
960
+ index-> table -> stats_mutex_unlock ();
949
961
continue ;
950
962
}
951
963
@@ -954,7 +966,7 @@ dict_stats_update_transient(
954
966
sum_of_index_sizes += index->stat_index_size ;
955
967
}
956
968
957
- dict_sys. mutex_lock ();
969
+ table-> stats_mutex_lock ();
958
970
959
971
index = dict_table_get_first_index (table);
960
972
@@ -972,7 +984,7 @@ dict_stats_update_transient(
972
984
973
985
table->stat_initialized = TRUE ;
974
986
975
- dict_sys. mutex_unlock ();
987
+ table-> stats_mutex_unlock ();
976
988
}
977
989
978
990
/* @{ 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)
1930
1942
DBUG_PRINT (" info" , (" index: %s, online status: %d" , index->name (),
1931
1943
dict_index_get_online_status (index)));
1932
1944
1933
- dict_sys. assert_not_locked (); // this function is slow
1945
+ ut_ad (!index-> table -> stats_mutex_is_owner ());
1934
1946
ut_ad (index->table ->get_ref_count ());
1935
1947
1936
1948
/* Disable update statistic for Rtree */
@@ -2002,14 +2014,14 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index)
2002
2014
2003
2015
mtr.commit ();
2004
2016
2005
- dict_sys. mutex_lock ();
2017
+ index-> table -> stats_mutex_lock ();
2006
2018
for (ulint i = 0 ; i < n_uniq; i++) {
2007
2019
result.stats [i].n_diff_key_vals = index->stat_n_diff_key_vals [i];
2008
2020
result.stats [i].n_sample_sizes = total_pages;
2009
2021
result.stats [i].n_non_null_key_vals = index->stat_n_non_null_key_vals [i];
2010
2022
}
2011
2023
result.n_leaf_pages = index->stat_n_leaf_pages ;
2012
- dict_sys. mutex_unlock ();
2024
+ index-> table -> stats_mutex_unlock ();
2013
2025
2014
2026
DBUG_RETURN (result);
2015
2027
}
@@ -2243,13 +2255,13 @@ dict_stats_update_persistent(
2243
2255
}
2244
2256
2245
2257
ut_ad (!dict_index_is_ibuf (index));
2246
- dict_sys. mutex_lock ();
2258
+ table-> stats_mutex_lock ();
2247
2259
dict_stats_empty_index (index, false );
2248
- dict_sys. mutex_unlock ();
2260
+ table-> stats_mutex_unlock ();
2249
2261
2250
2262
index_stats_t stats = dict_stats_analyze_index (index);
2251
2263
2252
- dict_sys. mutex_lock ();
2264
+ table-> stats_mutex_lock ();
2253
2265
index->stat_index_size = stats.index_size ;
2254
2266
index->stat_n_leaf_pages = stats.n_leaf_pages ;
2255
2267
for (size_t i = 0 ; i < stats.stats .size (); ++i) {
@@ -2285,9 +2297,9 @@ dict_stats_update_persistent(
2285
2297
}
2286
2298
2287
2299
if (!(table->stats_bg_flag & BG_STAT_SHOULD_QUIT)) {
2288
- dict_sys. mutex_unlock ();
2300
+ table-> stats_mutex_unlock ();
2289
2301
stats = dict_stats_analyze_index (index);
2290
- dict_sys. mutex_lock ();
2302
+ table-> stats_mutex_lock ();
2291
2303
2292
2304
index->stat_index_size = stats.index_size ;
2293
2305
index->stat_n_leaf_pages = stats.n_leaf_pages ;
@@ -2313,7 +2325,7 @@ dict_stats_update_persistent(
2313
2325
2314
2326
dict_stats_assert_initialized (table);
2315
2327
2316
- dict_sys. mutex_unlock ();
2328
+ table-> stats_mutex_unlock ();
2317
2329
2318
2330
return (DB_SUCCESS);
2319
2331
}
@@ -3123,13 +3135,11 @@ dict_stats_update_for_index(
3123
3135
{
3124
3136
DBUG_ENTER (" dict_stats_update_for_index" );
3125
3137
3126
- dict_sys.assert_not_locked ();
3127
-
3128
3138
if (dict_stats_is_persistent_enabled (index->table )) {
3129
3139
3130
3140
if (dict_stats_persistent_storage_check (false )) {
3131
3141
index_stats_t stats = dict_stats_analyze_index (index);
3132
- dict_sys. mutex_lock ();
3142
+ index-> table -> stats_mutex_lock ();
3133
3143
index->stat_index_size = stats.index_size ;
3134
3144
index->stat_n_leaf_pages = stats.n_leaf_pages ;
3135
3145
for (size_t i = 0 ; i < stats.stats .size (); ++i) {
@@ -3142,7 +3152,7 @@ dict_stats_update_for_index(
3142
3152
}
3143
3153
index->table ->stat_sum_of_other_index_sizes
3144
3154
+= index->stat_index_size ;
3145
- dict_sys. mutex_unlock ();
3155
+ index-> table -> stats_mutex_unlock ();
3146
3156
3147
3157
dict_stats_save (index->table , &index->id );
3148
3158
DBUG_VOID_RETURN;
@@ -3183,7 +3193,7 @@ dict_stats_update(
3183
3193
the persistent statistics
3184
3194
storage */
3185
3195
{
3186
- dict_sys. assert_not_locked ( );
3196
+ ut_ad (!table-> stats_mutex_is_owner () );
3187
3197
3188
3198
if (!table->is_readable ()) {
3189
3199
return (dict_stats_report_error (table));
@@ -3318,7 +3328,10 @@ dict_stats_update(
3318
3328
switch (err) {
3319
3329
case DB_SUCCESS:
3320
3330
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 ());
3322
3335
3323
3336
/* Pass reset_ignored_indexes=true as parameter
3324
3337
to dict_stats_copy. This will cause statictics
@@ -3327,7 +3340,8 @@ dict_stats_update(
3327
3340
3328
3341
dict_stats_assert_initialized (table);
3329
3342
3330
- dict_sys.mutex_unlock ();
3343
+ ut_d (t->stats_mutex_unlock ());
3344
+ table->stats_mutex_unlock ();
3331
3345
3332
3346
dict_stats_table_clone_free (t);
3333
3347
0 commit comments