summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@montyprogram.com>2012-12-21 00:12:37 +0100
committerVladislav Vaintroub <wlad@montyprogram.com>2012-12-21 00:12:37 +0100
commit21b4fda3a565ca3d43ae6ac77df06e69076b0f8d (patch)
tree6b6b77bae7a02a0e32817deb138da947b701f963
parent1b2692d0e9f99d7cb2dbcdb8d030345679affbfc (diff)
downloadmariadb-git-21b4fda3a565ca3d43ae6ac77df06e69076b0f8d.tar.gz
MDEV-3945 - do not hold LOCK_thread_count when freeing THD.
The patch decreases the duration of LOCK_thread_count, so it is not hold during THD destructor and freeing memory. This mutex now only protects the integrity of threads list, when removing THD from it, and thread_count variable. The add_to_status() function that updates global status during client disconnect, is now correctly protected by the LOCK_status mutex. Benchmark : in a "non-persistent" sysbench test (oltp_ro with reconnect after each query), ~ 25% more connects/disconnects were measured
-rw-r--r--sql/mysqld.cc35
-rw-r--r--sql/scheduler.cc1
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/threadpool_common.cc1
4 files changed, 16 insertions, 22 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 3e4212f1aa9..c4c65977e60 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2441,21 +2441,6 @@ void dec_connection_count(THD *thd)
/*
- Delete the THD object and decrease number of threads
-
- SYNOPSIS
- delete_thd()
- thd Thread handler
-*/
-
-void delete_thd(THD *thd)
-{
- thread_count--;
- delete thd;
-}
-
-
-/*
Unlink thd from global list of available connections and free thd
SYNOPSIS
@@ -2473,14 +2458,23 @@ void unlink_thd(THD *thd)
thd_cleanup(thd);
dec_connection_count(thd);
+
+ mysql_mutex_lock(&LOCK_status);
+ add_to_status(&global_status_var, &thd->status_var);
+ mysql_mutex_unlock(&LOCK_status);
+
mysql_mutex_lock(&LOCK_thread_count);
+ thread_count--;
+ thd->unlink();
/*
Used by binlog_reset_master. It would be cleaner to use
DEBUG_SYNC here, but that's not possible because the THD's debug
sync feature has been shut down at this point.
*/
DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5););
- delete_thd(thd);
+ mysql_mutex_unlock(&LOCK_thread_count);
+
+ delete thd;
DBUG_VOID_RETURN;
}
@@ -2589,10 +2583,13 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
/* Mark that current_thd is not valid anymore */
my_pthread_setspecific_ptr(THR_THD, 0);
if (put_in_cache)
+ {
+ mysql_mutex_lock(&LOCK_thread_count);
put_in_cache= cache_thread();
- mysql_mutex_unlock(&LOCK_thread_count);
- if (put_in_cache)
- DBUG_RETURN(0); // Thread is reused
+ mysql_mutex_unlock(&LOCK_thread_count);
+ if (put_in_cache)
+ DBUG_RETURN(0); // Thread is reused
+ }
/* It's safe to broadcast outside a lock (COND... is not deleted here) */
DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
diff --git a/sql/scheduler.cc b/sql/scheduler.cc
index 0ae4121ef4c..54653557b16 100644
--- a/sql/scheduler.cc
+++ b/sql/scheduler.cc
@@ -35,7 +35,6 @@
static bool no_threads_end(THD *thd, bool put_in_cache)
{
unlink_thd(thd);
- mysql_mutex_unlock(&LOCK_thread_count);
return 1; // Abort handle_one_connection
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 81f021d9306..42952585e07 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1444,7 +1444,6 @@ THD::~THD()
mysql_mutex_lock(&LOCK_thd_data);
mysys_var=0; // Safety (shouldn't be needed)
mysql_mutex_unlock(&LOCK_thd_data);
- add_to_status(&global_status_var, &status_var);
/* Close connection */
#ifndef EMBEDDED_LIBRARY
diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc
index 6b956768287..147a59df9b7 100644
--- a/sql/threadpool_common.cc
+++ b/sql/threadpool_common.cc
@@ -173,7 +173,6 @@ void threadpool_remove_connection(THD *thd)
close_connection(thd, 0);
unlink_thd(thd);
- mysql_mutex_unlock(&LOCK_thread_count);
mysql_cond_broadcast(&COND_thread_count);
/*