diff options
author | Sergey Vojtovich <svoj@mariadb.org> | 2019-10-02 16:04:52 +0400 |
---|---|---|
committer | Sergey Vojtovich <svoj@mariadb.org> | 2019-10-07 13:30:22 +0400 |
commit | adefaeffcce7c4ae0844f72dd920603b35285d40 (patch) | |
tree | e5396eeec14a2283b36f5b0ff208562a21e7ef99 | |
parent | e43791d4dc8feb2c02a08ce73c0bb0e2c320018c (diff) | |
download | mariadb-git-adefaeffcce7c4ae0844f72dd920603b35285d40.tar.gz |
MDEV-19536 - Server crash or ASAN heap-use-after-free in is_temporary_table /
read_statistics_for_tables_if_needed
Regression after 279a907, read_statistics_for_tables_if_needed() was
called after open_normal_and_derived_tables() failure.
Fixed by moving read_statistics_for_tables() call to a branch of
get_schema_stat_record() where result of open_normal_and_derived_tables()
is checked.
Removed THD::force_read_stats, added read_statistics_for_tables() instead.
Simplified away statistics_for_command_is_needed().
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 3 | ||||
-rw-r--r-- | sql/sql_show.cc | 5 | ||||
-rw-r--r-- | sql/sql_statistics.cc | 83 | ||||
-rw-r--r-- | sql/sql_statistics.h | 1 |
5 files changed, 29 insertions, 64 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 1a3ca54abf8..ab105c67507 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -986,7 +986,6 @@ THD::THD(bool is_wsrep_applier) memset(&invoker_host, 0, sizeof(invoker_host)); prepare_derived_at_open= FALSE; create_tmp_table_for_derived= FALSE; - force_read_stats= FALSE; save_prep_leaf_list= FALSE; /* Restore THR_THD */ set_current_thd(old_THR_THD); diff --git a/sql/sql_class.h b/sql/sql_class.h index 8a4d8ff06a3..6c622648ac7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2200,9 +2200,6 @@ public: */ bool create_tmp_table_for_derived; - /* The flag to force reading statistics from EITS tables */ - bool force_read_stats; - bool save_prep_leaf_list; /* container for handler's private per-connection data */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 71bfc644441..c154f5da472 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4272,7 +4272,6 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'. */ - thd->force_read_stats= get_schema_table_idx(schema_table) == SCH_STATISTICS; lex->sql_command= SQLCOM_SHOW_FIELDS; result= (open_temporary_tables(thd, table_list) || open_normal_and_derived_tables(thd, table_list, @@ -4287,9 +4286,6 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, */ lex->sql_command= old_lex->sql_command; - (void) read_statistics_for_tables_if_needed(thd, table_list); - thd->force_read_stats= false; - DEBUG_SYNC(thd, "after_open_table_ignore_flush"); /* @@ -6165,6 +6161,7 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, KEY *key_info=show_table->s->key_info; if (show_table->file) { + (void) read_statistics_for_tables(thd, tables); show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index e18cec589be..4a1ed9cde4e 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -2161,54 +2161,6 @@ int alloc_statistics_for_table(THD* thd, TABLE *table) /** - @brief - Check whether any persistent statistics for the processed command is needed - - @param - thd The thread handle - - @details - The function checks whether any persitent statistics for the processed - command is needed to be read. - - @retval - TRUE statistics is needed to be read - @retval - FALSE Otherwise -*/ - -static -inline bool statistics_for_command_is_needed(THD *thd) -{ - if (thd->bootstrap || thd->variables.use_stat_tables == NEVER) - return FALSE; - - if (thd->force_read_stats) - return TRUE; - - switch(thd->lex->sql_command) { - case SQLCOM_SELECT: - case SQLCOM_INSERT: - case SQLCOM_INSERT_SELECT: - case SQLCOM_UPDATE: - case SQLCOM_UPDATE_MULTI: - case SQLCOM_DELETE: - case SQLCOM_DELETE_MULTI: - case SQLCOM_REPLACE: - case SQLCOM_REPLACE_SELECT: - case SQLCOM_CREATE_TABLE: - case SQLCOM_SET_OPTION: - case SQLCOM_DO: - break; - default: - return FALSE; - } - - return TRUE; -} - - -/** @brief Allocate memory for the statistical data used by a table share @@ -2255,9 +2207,6 @@ static int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share) DEBUG_SYNC(thd, "statistics_mem_alloc_start1"); DEBUG_SYNC(thd, "statistics_mem_alloc_start2"); - if (!statistics_for_command_is_needed(thd)) - DBUG_RETURN(1); - mysql_mutex_lock(&table_share->LOCK_share); if (stats_cb->stats_can_be_read) @@ -3110,9 +3059,6 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables) { if (!tables) return FALSE; - - if (!statistics_for_command_is_needed(thd)) - return FALSE; /* Do not read statistics for any query that explicity involves @@ -3245,14 +3191,39 @@ int read_histograms_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables) { + switch (thd->lex->sql_command) { + case SQLCOM_SELECT: + case SQLCOM_INSERT: + case SQLCOM_INSERT_SELECT: + case SQLCOM_UPDATE: + case SQLCOM_UPDATE_MULTI: + case SQLCOM_DELETE: + case SQLCOM_DELETE_MULTI: + case SQLCOM_REPLACE: + case SQLCOM_REPLACE_SELECT: + case SQLCOM_CREATE_TABLE: + case SQLCOM_SET_OPTION: + case SQLCOM_DO: + return read_statistics_for_tables(thd, tables); + default: + return 0; + } +} + + +int read_statistics_for_tables(THD *thd, TABLE_LIST *tables) +{ TABLE_LIST stat_tables[STATISTICS_TABLES]; Open_tables_backup open_tables_backup; - DBUG_ENTER("read_statistics_for_tables_if_needed"); + DBUG_ENTER("read_statistics_for_tables"); + + if (thd->bootstrap || thd->variables.use_stat_tables == NEVER) + DBUG_RETURN(0); for (TABLE_LIST *tl= tables; tl; tl= tl->next_global) { - if (get_use_stat_tables_mode(thd) > NEVER && tl->table) + if (tl->table) { TABLE_SHARE *table_share= tl->table->s; if (table_share && table_share->table_category == TABLE_CATEGORY_USER && diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h index 968f77cd2ca..71d727eab07 100644 --- a/sql/sql_statistics.h +++ b/sql/sql_statistics.h @@ -89,6 +89,7 @@ Use_stat_tables_mode get_use_stat_tables_mode(THD *thd) } int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables); +int read_statistics_for_tables(THD *thd, TABLE_LIST *tables); int collect_statistics_for_table(THD *thd, TABLE *table); void delete_stat_values_for_table_share(TABLE_SHARE *table_share); int alloc_statistics_for_table(THD *thd, TABLE *table); |