summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-04-12 11:29:32 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-04-12 11:29:32 +0300
commitea2d44d01b4aead2e1d6d88b9eede39fd99dff67 (patch)
tree575386be3dc57e3f6ff1695cb5b6756567e5cf63
parent75dd7a048315affc0c5986b6e955965d46621c6a (diff)
downloadmariadb-git-ea2d44d01b4aead2e1d6d88b9eede39fd99dff67.tar.gz
MDEV-18802 Assertion table->stat_initialized failed in dict_stats_update_if_needed()
When a table has been evicted from dict_sys and reloaded internally by InnoDB for FOREIGN KEY processing, statistics may not be initialized, but nevertheless row_update_cascade_for_mysql() could invoke dict_stats_update_if_needed(). In that case, we cannot really update the statistics. For tables that have STATS_PERSISTENT=1 and STATS_AUTO_RECALC=1, ANALYZE TABLE might have to be executed later. dict_stats_update_if_needed(): Replace the assertion with a conditional early return.
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc19
1 files changed, 17 insertions, 2 deletions
diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc
index 589f53dde38..a4619a6069b 100644
--- a/storage/innobase/dict/dict0stats_bg.cc
+++ b/storage/innobase/dict/dict0stats_bg.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -154,9 +154,24 @@ schedule new estimates for table and index statistics to be calculated.
void dict_stats_update_if_needed_func(dict_table_t *table)
#endif
{
- ut_ad(table->stat_initialized);
ut_ad(!mutex_own(&dict_sys->mutex));
+ if (UNIV_UNLIKELY(!table->stat_initialized)) {
+ /* The table may have been evicted from dict_sys
+ and reloaded internally by InnoDB for FOREIGN KEY
+ processing, but not reloaded by the SQL layer.
+
+ We can (re)compute the transient statistics when the
+ table is actually loaded by the SQL layer.
+
+ Note: If InnoDB persistent statistics are enabled,
+ we will skip the updates. We must do this, because
+ dict_table_get_n_rows() below assumes that the
+ statistics have been initialized. The DBA may have
+ to execute ANALYZE TABLE. */
+ return;
+ }
+
ulonglong counter = table->stat_modified_counter++;
ulonglong n_rows = dict_table_get_n_rows(table);