diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-01-11 10:35:06 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-01-11 10:35:06 +0200 |
commit | fd5e103aa4b97e080dd497b93992e5f32ef83fdf (patch) | |
tree | 4688325520abb9c71d1b41c62aa2265d32821db7 /sql/sql_class.cc | |
parent | a131b976b205af4023a5d43569fadf44dceade70 (diff) | |
parent | 5a1a7141870459cf66d8e441b443187f87a10d5d (diff) | |
download | mariadb-git-fd5e103aa4b97e080dd497b93992e5f32ef83fdf.tar.gz |
Merge 10.3 into 10.4
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ceb8dc1ade8..9d1588a7ce1 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2008, 2020, MariaDB Corporation. + Copyright (c) 2008, 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 @@ -1512,16 +1512,29 @@ void THD::reset_db(const LEX_CSTRING *new_db) /* Do operations that may take a long time */ -void THD::cleanup(void) +void THD::cleanup(bool have_mutex) { DBUG_ENTER("THD::cleanup"); DBUG_ASSERT(cleanup_done == 0); - set_killed(KILL_CONNECTION); + if (have_mutex) + set_killed_no_mutex(KILL_CONNECTION,0,0); + else + set_killed(KILL_CONNECTION); #ifdef WITH_WSREP if (wsrep_cs().state() != wsrep::client_state::s_none) { - wsrep_cs().cleanup(); + if (have_mutex) + { + mysql_mutex_assert_owner(static_cast<mysql_mutex_t*> + (m_wsrep_mutex.native())); + // Below wsrep-lib function will not acquire any mutexes + wsrep::unique_lock<wsrep::mutex> lock(m_wsrep_mutex, std::adopt_lock); + wsrep_cs().cleanup(lock); + lock.release(); + } + else + wsrep_cs().cleanup(); } wsrep_client_thread= false; #endif /* WITH_WSREP */ @@ -1598,16 +1611,38 @@ void THD::cleanup(void) void THD::free_connection() { DBUG_ASSERT(free_connection_done == 0); - my_free((char*) db.str); + /* Make sure threads are not available via server_threads. */ + assert_not_linked(); + + /* + Other threads may have a lock on THD::LOCK_thd_data or + THD::LOCK_thd_kill to ensure that this THD is not deleted + while they access it. The following mutex_lock ensures + that no one else is using this THD and it's now safe to + continue. + + For example consider KILL-statement execution on + sql_parse.cc kill_one_thread() that will use + THD::LOCK_thd_data to protect victim thread during + THD::awake(). + */ + mysql_mutex_lock(&LOCK_thd_data); + mysql_mutex_lock(&LOCK_thd_kill); + +#ifdef WITH_WSREP + delete wsrep_rgi; + wsrep_rgi= nullptr; +#endif /* WITH_WSREP */ + my_free(const_cast<char*>(db.str)); db= null_clex_str; #ifndef EMBEDDED_LIBRARY if (net.vio) vio_delete(net.vio); - net.vio= 0; + net.vio= nullptr; net_end(&net); #endif - if (!cleanup_done) - cleanup(); + if (!cleanup_done) + cleanup(true); // We have locked THD::LOCK_thd_kill ha_close_connection(this); plugin_thdvar_cleanup(this); mysql_audit_free_thd(this); @@ -1618,6 +1653,8 @@ void THD::free_connection() #if defined(ENABLED_PROFILING) profiling.restart(); // Reset profiling #endif + mysql_mutex_unlock(&LOCK_thd_kill); + mysql_mutex_unlock(&LOCK_thd_data); } /* @@ -1671,24 +1708,10 @@ THD::~THD() if (!status_in_global) add_status_to_global(); - /* - Other threads may have a lock on LOCK_thd_kill to ensure that this - THD is not deleted while they access it. The following mutex_lock - ensures that no one else is using this THD and it's now safe to delete - */ - if (WSREP_NNULL(this)) mysql_mutex_lock(&LOCK_thd_data); - mysql_mutex_lock(&LOCK_thd_kill); - mysql_mutex_unlock(&LOCK_thd_kill); - if (WSREP_NNULL(this)) mysql_mutex_unlock(&LOCK_thd_data); - if (!free_connection_done) free_connection(); #ifdef WITH_WSREP - if (wsrep_rgi != NULL) { - delete wsrep_rgi; - wsrep_rgi = NULL; - } mysql_cond_destroy(&COND_wsrep_thd); #endif mdl_context.destroy(); @@ -3142,12 +3165,12 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange, } /* Create the file world readable */ if ((file= mysql_file_create(key_select_to_file, - path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0) + path, 0644, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0) return file; #ifdef HAVE_FCHMOD - (void) fchmod(file, 0666); // Because of umask() + (void) fchmod(file, 0644); // Because of umask() #else - (void) chmod(path, 0666); + (void) chmod(path, 0644); #endif if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME))) { |