List:Commits« Previous MessageNext Message »
From:Tor Didriksen Date:April 20 2012 8:55am
Subject:bzr push into mysql-trunk branch (tor.didriksen:3702 to 3703) Bug#12790933
View as plain text  
 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#12790933Tor Didriksen20 Apr