From: Tor Didriksen Date: April 20 2012 8:55am Subject: bzr push into mysql-trunk branch (tor.didriksen:3702 to 3703) Bug#12790933 List-Archive: http://lists.mysql.com/commits/143592 X-Bug: 12790933 Message-Id: <201204200855.q3K8thbg028202@acsmt356.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3703 Tor Didriksen 2012-04-20 Bug#12790933 MULTIPLE DEADLOCKS / BOTTLENECKS INVOLVING LOCK_THREAD_COUNT LOCK_thread_count should protect the list of THD only, not the internal state of a THD. @ include/mysql/thread_pool_priv.h Declare remove_global_thread here, since it is used by the thread_pool. @ sql/mysqld.cc Remove delete_thd(), add destroy_thd() instead. @ sql/mysqld.h Remove delete_thd(), add destroy_thd() instead. @ sql/scheduler.cc Remove delete_thd(), add destroy_thd() instead. @ sql/sql_class.cc We should not hold LOCK_thread_count when running the THD DTOR. Grab LOCK_status before updating global_status_var. @ sql/sql_parse.cc We should not hold LOCK_thread_count when running the THD DTOR. modified: include/mysql/thread_pool_priv.h sql/mysqld.cc sql/mysqld.h sql/scheduler.cc sql/sql_class.cc sql/sql_parse.cc sql/sql_show.cc 3702 Oystein Grovlen 2012-04-20 [merge] Final merge mysql-trunk => mysql-wl#6043. No issues. added: mysql-test/r/bug12427262.result mysql-test/r/myisam_row_rpl.result mysql-test/t/bug12427262.test mysql-test/t/myisam_row_rpl-master.opt mysql-test/t/myisam_row_rpl-slave.opt mysql-test/t/myisam_row_rpl.test modified: CMakeLists.txt README VERSION client/mysql.cc client/mysql_upgrade.c client/mysqladmin.cc client/mysqlbinlog.cc client/mysqlcheck.c client/mysqldump.c client/mysqlimport.c client/mysqlshow.c client/mysqlslap.c client/mysqltest.cc cmake/os/Windows.cmake config.h.cmake extra/innochecksum.cc extra/perror.c include/welcome_copyright_notice.h mysql-test/include/assert_command_output.inc mysql-test/lib/My/CoreDump.pm mysql-test/r/log_tables.result mysql-test/r/rewrite_general_log.result mysql-test/suite/binlog/r/binlog_grant.result mysql-test/suite/binlog/r/binlog_multi_engine.result mysql-test/suite/binlog/t/binlog_grant.test mysql-test/suite/innodb/r/innodb-index-online.result mysql-test/suite/innodb/t/innodb-alter-discard.test mysql-test/suite/innodb/t/innodb-index-online.test mysql-test/suite/innodb_fts/r/innodb_fts_misc.result mysql-test/suite/innodb_fts/t/innodb_fts_misc.test mysql-test/suite/rpl/r/rpl_corruption.result mysql-test/suite/rpl/r/rpl_gtid_mode.result mysql-test/suite/rpl/t/rpl_corruption.test mysql-test/suite/rpl/t/rpl_gtid_mode.test mysql-test/suite/rpl/t/rpl_parallel_change_master.test mysql-test/t/rewrite_general_log.test packaging/WiX/custom_ui.wxs sql/gen_lex_hash.cc sql/ha_ndbcluster_binlog.cc sql/item.cc sql/item.h sql/item_func.cc sql/item_func.h sql/log_event.cc sql/log_event.h sql/mysqld.cc sql/rpl_info_file.cc sql/rpl_mi.cc sql/set_var.cc sql/sql_executor.cc sql/sql_parse.cc sql/sql_select.cc sql/sql_show.cc sql/sql_show.h sql/sql_string.h storage/innobase/pars/lexyy.cc storage/innobase/pars/pars0lex.l storage/myisam/ha_myisam.cc storage/perfschema/gen_pfs_lex_token.cc === modified file 'include/mysql/thread_pool_priv.h' --- a/include/mysql/thread_pool_priv.h 2011-06-30 15:46:53 +0000 +++ b/include/mysql/thread_pool_priv.h 2012-04-20 08:55:22 +0000 @@ -1,5 +1,5 @@ /* - Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. 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 @@ -99,7 +99,9 @@ void thd_cleanup(THD *thd); /* Decrement connection counter */ void dec_connection_count(); /* Destroy THD object */ -void delete_thd(THD *thd); +void destroy_thd(THD *thd); +/* Remove the THD from the set of global threads. */ +void remove_global_thread(THD *thd); /* thread_created is maintained by thread pool when activated since === modified file 'sql/mysqld.cc' --- a/sql/mysqld.cc 2012-04-18 13:06:39 +0000 +++ b/sql/mysqld.cc 2012-04-20 08:55:22 +0000 @@ -2366,18 +2366,12 @@ void dec_connection_count() } -/* - Delete the THD object and decrease number of threads - - SYNOPSIS - delete_thd() - thd Thread handler -*/ - -void delete_thd(THD *thd) +/** + Delete the THD object. + */ +void destroy_thd(THD *thd) { - mysql_mutex_assert_owner(&LOCK_thread_count); - remove_global_thread(thd); + mysql_mutex_assert_not_owner(&LOCK_thread_count); delete thd; } === modified file 'sql/mysqld.h' --- a/sql/mysqld.h 2012-04-18 13:06:39 +0000 +++ b/sql/mysqld.h 2012-04-20 08:55:22 +0000 @@ -68,7 +68,7 @@ void kill_mysql(void); void close_connection(THD *thd, uint sql_errno= 0); void handle_connection_in_main_thread(THD *thd); void create_thread_to_handle_connection(THD *thd); -void delete_thd(THD *thd); +void destroy_thd(THD *thd); bool one_thread_per_connection_end(THD *thd, bool block_pthread); void kill_blocked_pthreads(); void refresh_status(THD *thd); === modified file 'sql/scheduler.cc' --- a/sql/scheduler.cc 2012-04-13 12:00:39 +0000 +++ b/sql/scheduler.cc 2012-04-20 08:55:22 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. 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 @@ -35,10 +35,11 @@ static bool no_threads_end(THD *thd, boo thd_cleanup(thd); dec_connection_count(); - // THD is an incomplete type here, so use delete_thd() to delete it. + // THD is an incomplete type here, so use destroy_thd() to delete it. mysql_mutex_lock(&LOCK_thread_count); - delete_thd(thd); + remove_global_thread(thd); mysql_mutex_unlock(&LOCK_thread_count); + destroy_thd(thd); return 1; // Abort handle_one_connection } === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2012-04-17 14:37:50 +0000 +++ b/sql/sql_class.cc 2012-04-20 08:55:22 +0000 @@ -1402,14 +1402,19 @@ void THD::cleanup(void) THD::~THD() { + mysql_mutex_assert_not_owner(&LOCK_thread_count); THD_CHECK_SENTRY(this); DBUG_ENTER("~THD()"); DBUG_PRINT("info", ("THD dtor, this %p", this)); + /* Ensure that no one is using THD */ mysql_mutex_lock(&LOCK_thd_data); mysys_var=0; // Safety (shouldn't be needed) mysql_mutex_unlock(&LOCK_thd_data); + + mysql_mutex_lock(&LOCK_status); add_to_status(&global_status_var, &status_var); + mysql_mutex_unlock(&LOCK_status); /* Close connection */ #ifndef EMBEDDED_LIBRARY === modified file 'sql/sql_parse.cc' --- a/sql/sql_parse.cc 2012-04-18 09:18:20 +0000 +++ b/sql/sql_parse.cc 2012-04-20 08:55:22 +0000 @@ -801,16 +801,22 @@ end: net_end(&thd->net); thd->cleanup(); + if (thd_added) + { + mysql_mutex_lock(&LOCK_thread_count); + remove_global_thread(thd); + mysql_mutex_unlock(&LOCK_thread_count); + } /* - Here we delete the thd while holding the LOCK_thread_count. + We need to delete the thd before signalling that bootstrap is done. The reason is that we have to call ha_close_connection(thd) before shutting down InnoDB (this is done by THD::~THD()) */ + delete thd; + mysql_mutex_lock(&LOCK_thread_count); - if (thd_added) - remove_global_thread(thd); in_bootstrap= FALSE; - delete thd; + mysql_cond_broadcast(&COND_thread_count); mysql_mutex_unlock(&LOCK_thread_count); #ifndef EMBEDDED_LIBRARY === modified file 'sql/sql_show.cc' --- a/sql/sql_show.cc 2012-04-19 10:49:27 +0000 +++ b/sql/sql_show.cc 2012-04-20 08:55:22 +0000 @@ -2647,7 +2647,6 @@ void calc_sum_of_all_status(STATUS_VAR * { DBUG_ENTER("calc_sum_of_all_status"); - /* Ensure that thread id not killed during loop */ mysql_mutex_lock(&LOCK_thread_count); Thread_iterator it= global_thread_list_begin(); No bundle (reason: useless for push emails).