diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2021-01-11 08:34:04 +0200 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2021-01-11 08:34:04 +0200 |
commit | d1aea01dd3438225a2adcca19d79f7a9ff22c8f8 (patch) | |
tree | a6fec29df398b8abf2e51dd18c117d84ca04d783 | |
parent | 3b548d3bbf888e7c9e9853cf826e528b5195d8bd (diff) | |
download | mariadb-git-bb-10.2-MDEV-23536.tar.gz |
MDEV-23536 : Race condition between KILL and transaction commitbb-10.2-MDEV-23536
Fix test regression. We need to pass information do we hold
THD::LOCK_thd_data mutex to close_thread_table,
close_thread_tables and Locked_tables_list::unlock_locked_tables
because unlock_locked_tables would otherwise take it.
-rw-r--r-- | sql/sql_base.cc | 16 | ||||
-rw-r--r-- | sql/sql_base.h | 4 | ||||
-rw-r--r-- | sql/sql_class.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 2 |
5 files changed, 14 insertions, 12 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index b8d18abb50c..d6cf79f35a6 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -717,7 +717,7 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, leave prelocked mode if needed. */ -void close_thread_tables(THD *thd) +void close_thread_tables(THD *thd, bool have_mutex) { TABLE *table; DBUG_ENTER("close_thread_tables"); @@ -856,7 +856,7 @@ void close_thread_tables(THD *thd) other thread tries to abort the MERGE lock in between. */ while (thd->open_tables) - (void) close_thread_table(thd, &thd->open_tables); + (void) close_thread_table(thd, &thd->open_tables, have_mutex); DBUG_VOID_RETURN; } @@ -864,7 +864,7 @@ void close_thread_tables(THD *thd) /* move one table to free list */ -void close_thread_table(THD *thd, TABLE **table_ptr) +void close_thread_table(THD *thd, TABLE **table_ptr, bool have_mutex) { TABLE *table= *table_ptr; DBUG_ENTER("close_thread_table"); @@ -889,9 +889,11 @@ void close_thread_table(THD *thd, TABLE **table_ptr) table->file->update_global_index_stats(); } - mysql_mutex_lock(&thd->LOCK_thd_data); + if (!have_mutex) + mysql_mutex_lock(&thd->LOCK_thd_data); *table_ptr=table->next; - mysql_mutex_unlock(&thd->LOCK_thd_data); + if (!have_mutex) + mysql_mutex_unlock(&thd->LOCK_thd_data); if (! table->needs_reopen()) { @@ -2193,7 +2195,7 @@ Locked_tables_list::init_locked_tables(THD *thd) */ void -Locked_tables_list::unlock_locked_tables(THD *thd) +Locked_tables_list::unlock_locked_tables(THD *thd, bool have_mutex) { DBUG_ASSERT(!thd->in_sub_stmt && !(thd->state_flags & Open_tables_state::BACKUPS_AVAIL)); @@ -2221,7 +2223,7 @@ Locked_tables_list::unlock_locked_tables(THD *thd) TRANSACT_TRACKER(clear_trx_state(thd, TX_LOCKED_TABLES)); DBUG_ASSERT(thd->transaction.stmt.is_empty()); - close_thread_tables(thd); + close_thread_tables(thd, have_mutex); /* We rely on the caller to implicitly commit the diff --git a/sql/sql_base.h b/sql/sql_base.h index b67341bcbda..55b0aa645cf 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -147,7 +147,7 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, TABLE_LIST *TABLE_LIST::*link, const char *db_name, const char *table_name); -void close_thread_tables(THD *thd); +void close_thread_tables(THD *thd, bool have_mutex=false); void switch_to_nullable_trigger_fields(List<Item> &items, TABLE *); void switch_defaults_to_nullable_trigger_fields(TABLE *table); bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, @@ -269,7 +269,7 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags, uint dt_phases); bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags); int decide_logging_format(THD *thd, TABLE_LIST *tables); -void close_thread_table(THD *thd, TABLE **table_ptr); +void close_thread_table(THD *thd, TABLE **table_ptr, bool have_mutex=false); TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, uint check_flag); bool is_equal(const LEX_STRING *a, const LEX_STRING *b); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2321991d99f..1d024860c5b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1374,7 +1374,7 @@ void THD::cleanup(bool have_mutex) #endif mysql_ha_cleanup(this); - locked_tables_list.unlock_locked_tables(this); + locked_tables_list.unlock_locked_tables(this, have_mutex); delete_dynamic(&user_var_events); close_temporary_tables(); diff --git a/sql/sql_class.h b/sql/sql_class.h index a97f64c13b3..714821f4c46 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1845,7 +1845,7 @@ public: init_sql_alloc(&m_locked_tables_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); } - void unlock_locked_tables(THD *thd); + void unlock_locked_tables(THD *thd, bool have_mutex=false); void unlock_locked_table(THD *thd, MDL_ticket *mdl_ticket); ~Locked_tables_list() { diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c79b3423b63..d3d8c8bb4e9 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -128,7 +128,7 @@ void destroy_thd(MYSQL_THD thd); void reset_thd(MYSQL_THD thd); TABLE *open_purge_table(THD *thd, const char *db, size_t dblen, const char *tb, size_t tblen); -void close_thread_tables(THD* thd); +void close_thread_tables(THD* thd, bool have_mutex=false); /** Check if user has used xtradb extended system variable that is not currently supported by innodb or marked as deprecated. */ |