diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-04-24 09:37:46 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-04-24 09:37:46 +0300 |
commit | 14a18d7d7f6293ad0e106288eab4fdcb3a72ebd9 (patch) | |
tree | 4e8f676417f4bc6cadfbd41d6b606a1c0142c7ac /storage/innobase | |
parent | 25ed665a2047e4766bc380ab30977a337f42485e (diff) | |
download | mariadb-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.cc | 18 |
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; |