From 5ae5453291d0c0ca01a73c794b79e267dc1b44e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sat, 4 Sep 2021 19:08:14 +0300 Subject: [PATCH] MDEV-25919 fixup: MSAN and Valgrind errors related to statistics dict_table_close(): Fix a race condition around dict_stats_deinit(). This was not observed; it should have been caught by an assertion. dict_stats_deinit(): Slightly simplify the code. ha_innobase::info_low(): If the table is unreadable, initialize some dummy statistics. --- storage/innobase/dict/dict0dict.cc | 6 ++++-- storage/innobase/handler/ha_innodb.cc | 5 +++++ storage/innobase/include/dict0stats.ic | 8 +++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 447ff7929f0..98c619cb7d3 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -225,7 +225,8 @@ void dict_table_close(dict_table_t *table) if (table->release()) { table->stats_mutex_lock(); - dict_stats_deinit(table); + if (table->get_ref_count() == 0) + dict_stats_deinit(table); table->stats_mutex_unlock(); } dict_sys.unlock(); @@ -258,7 +259,8 @@ dict_table_close( that FLUSH TABLE can be used to forcibly fetch stats from disk if they have been manually modified. */ table->stats_mutex_lock(); - dict_stats_deinit(table); + if (table->get_ref_count() == 0) + dict_stats_deinit(table); table->stats_mutex_unlock(); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 0ce32554232..56d9444016a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -14532,7 +14532,12 @@ ha_innobase::info_low( DBUG_ASSERT(ib_table->get_ref_count() > 0); if (!ib_table->is_readable()) { + ib_table->stats_mutex_lock(); ib_table->stat_initialized = true; + ib_table->stat_n_rows = 0; + ib_table->stat_clustered_index_size = 0; + ib_table->stat_sum_of_other_index_sizes = 0; + ib_table->stats_mutex_unlock(); } if (flag & HA_STATUS_TIME) { diff --git a/storage/innobase/include/dict0stats.ic b/storage/innobase/include/dict0stats.ic index e49153eb099..dd516275156 100644 --- a/storage/innobase/include/dict0stats.ic +++ b/storage/innobase/include/dict0stats.ic @@ -175,16 +175,13 @@ dict_stats_deinit( dict_table_t* table) /*!< in/out: table */ { ut_ad(table->stats_mutex_is_owner()); + ut_ad(table->get_ref_count() == 0); - ut_a(table->get_ref_count() == 0); - +#ifdef HAVE_valgrind if (!table->stat_initialized) { return; } - table->stat_initialized = FALSE; - -#ifdef HAVE_valgrind MEM_UNDEFINED(&table->stat_n_rows, sizeof table->stat_n_rows); MEM_UNDEFINED(&table->stat_clustered_index_size, sizeof table->stat_clustered_index_size); @@ -218,4 +215,5 @@ dict_stats_deinit( sizeof(index->stat_n_leaf_pages)); } #endif /* HAVE_valgrind */ + table->stat_initialized = FALSE; }