summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-04-24 09:37:46 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-04-24 09:37:46 +0300
commit14a18d7d7f6293ad0e106288eab4fdcb3a72ebd9 (patch)
tree4e8f676417f4bc6cadfbd41d6b606a1c0142c7ac /storage/innobase
parent25ed665a2047e4766bc380ab30977a337f42485e (diff)
downloadmariadb-git-14a18d7d7f6293ad0e106288eab4fdcb3a72ebd9.tar.gz
MDEV-23026/MDEV-25474 fixup: Assertion ib_table->stat_initialized
It is possible that an object that was originally created by open_purge_table() will remain cached and reused for SQL execution. Our previous fix wrongly assumed that ha_innobase::open() would always be called before SQL execution starts. Therefore, we must invoke dict_stats_init() in ha_innobase::info_low() instead of only doing it in ha_innobase::open(). Note: Concurrent execution of dict_stats_init() on the same table is possible, but it also was possible between two calls to ha_innobase::open(), with no ill effects observed. This should fix the assertion failure on stat_initialized. A possibly easy way to reproduce it would have been to run the server with innodb_force_recovery=2 (disable the purge of history), update a table so that an indexed virtual column will be affected, and finally restart the server normally (purge enabled), to observe a crash when the table is accessed from SQL. The problem was first observed and this fix verified by Elena Stepanova. Also Thirunarayanan Balathandayuthapani repeated the problem.
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/handler/ha_innodb.cc18
1 files changed, 7 insertions, 11 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index a725569fa6e..91d12f64fa5 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -6261,16 +6261,6 @@ no_such_table:
innobase_copy_frm_flags_from_table_share(ib_table, table->s);
- const bool bk_thread = THDVAR(thd, background_thread);
- /* No point to init any statistics if tablespace is still encrypted
- or if table is being opened by background thread */
- if (bk_thread) {
- } else if (ib_table->is_readable()) {
- dict_stats_init(ib_table);
- } else {
- ib_table->stat_initialized = 1;
- }
-
MONITOR_INC(MONITOR_TABLE_OPEN);
bool no_tablespace = false;
@@ -6516,7 +6506,7 @@ no_such_table:
}
}
- if (!bk_thread) {
+ if (!THDVAR(thd, background_thread)) {
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
}
@@ -14399,6 +14389,10 @@ ha_innobase::info_low(
ib_table = m_prebuilt->table;
DBUG_ASSERT(ib_table->get_ref_count() > 0);
+ if (!ib_table->is_readable()) {
+ ib_table->stat_initialized = true;
+ }
+
if (flag & HA_STATUS_TIME) {
if (is_analyze || innobase_stats_on_metadata) {
@@ -14449,6 +14443,8 @@ ha_innobase::info_low(
stats.update_time = (ulong) ib_table->update_time;
}
+ dict_stats_init(ib_table);
+
if (flag & HA_STATUS_VARIABLE) {
ulint stat_clustered_index_size;