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).
| Thread |
|---|
| • bzr push into mysql-trunk branch (tor.didriksen:3702 to 3703) Bug#12790933 | Tor Didriksen | 20 Apr |