summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/perfschema/r/nesting.result14
-rw-r--r--mysql-test/suite/perfschema/t/nesting.test1
-rw-r--r--sql/event_scheduler.cc3
-rw-r--r--sql/my_apc.cc24
-rw-r--r--sql/my_apc.h6
-rw-r--r--sql/mysqld.cc4
-rw-r--r--sql/slave.cc8
-rw-r--r--sql/sql_class.cc46
-rw-r--r--sql/sql_class.h16
-rw-r--r--sql/sql_insert.cc8
-rw-r--r--sql/sql_parse.cc20
-rw-r--r--sql/sql_repl.cc6
-rw-r--r--sql/sql_show.cc65
-rw-r--r--sql/threadpool_common.cc6
-rw-r--r--sql/wsrep_mysqld.cc2
15 files changed, 109 insertions, 120 deletions
diff --git a/mysql-test/suite/perfschema/r/nesting.result b/mysql-test/suite/perfschema/r/nesting.result
index 78126d93cc7..37681757973 100644
--- a/mysql-test/suite/perfschema/r/nesting.result
+++ b/mysql-test/suite/perfschema/r/nesting.result
@@ -125,7 +125,7 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re
15 15 stage/sql/Starting cleanup (stage) STATEMENT 0
16 16 stage/sql/Freeing items (stage) STATEMENT 0
17 17 wait/io/socket/sql/client_connection send STATEMENT 0
-18 18 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 0
+18 18 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 0
19 20 stage/sql/Reset for next command (stage) STATEMENT 0
20 20 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 19
21 21 idle idle NULL NULL
@@ -147,7 +147,7 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re
37 37 stage/sql/Starting cleanup (stage) STATEMENT 22
38 38 stage/sql/Freeing items (stage) STATEMENT 22
39 39 wait/io/socket/sql/client_connection send STATEMENT 22
-40 40 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 22
+40 40 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 22
41 42 stage/sql/Reset for next command (stage) STATEMENT 22
42 42 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 41
43 43 idle idle NULL NULL
@@ -169,7 +169,7 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re
59 59 stage/sql/Starting cleanup (stage) STATEMENT 44
60 60 stage/sql/Freeing items (stage) STATEMENT 44
61 61 wait/io/socket/sql/client_connection send STATEMENT 44
-62 62 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 44
+62 62 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 44
63 64 stage/sql/Reset for next command (stage) STATEMENT 44
64 64 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 63
65 65 idle idle NULL NULL
@@ -194,7 +194,7 @@ select "With a third part to make things complete" as payload NULL NULL
82 82 stage/sql/Starting cleanup (stage) STATEMENT 66
83 85 stage/sql/Freeing items (stage) STATEMENT 66
84 84 wait/io/socket/sql/client_connection send STAGE 83
-85 85 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 83
+85 85 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 83
86 103 statement/sql/select select "And this is the second part of a multi query" as payload;
select "With a third part to make things complete" as payload NULL NULL
87 89 stage/sql/Init (stage) STATEMENT 86
@@ -213,7 +213,7 @@ select "With a third part to make things complete" as payload NULL NULL
100 100 stage/sql/Starting cleanup (stage) STATEMENT 86
101 103 stage/sql/Freeing items (stage) STATEMENT 86
102 102 wait/io/socket/sql/client_connection send STAGE 101
-103 103 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 101
+103 103 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 101
104 122 statement/sql/select select "With a third part to make things complete" as payload NULL NULL
105 106 stage/sql/Init (stage) STATEMENT 104
106 106 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 105
@@ -230,7 +230,7 @@ select "With a third part to make things complete" as payload NULL NULL
117 117 stage/sql/Starting cleanup (stage) STATEMENT 104
118 118 stage/sql/Freeing items (stage) STATEMENT 104
119 119 wait/io/socket/sql/client_connection send STATEMENT 104
-120 120 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 104
+120 120 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 104
121 122 stage/sql/Reset for next command (stage) STATEMENT 104
122 122 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 121
123 123 idle idle NULL NULL
@@ -252,7 +252,7 @@ select "With a third part to make things complete" as payload NULL NULL
139 139 stage/sql/Starting cleanup (stage) STATEMENT 124
140 140 stage/sql/Freeing items (stage) STATEMENT 124
141 141 wait/io/socket/sql/client_connection send STATEMENT 124
-142 142 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 124
+142 142 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 124
143 144 stage/sql/Reset for next command (stage) STATEMENT 124
144 144 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 143
disconnect con1;
diff --git a/mysql-test/suite/perfschema/t/nesting.test b/mysql-test/suite/perfschema/t/nesting.test
index 9ab59157f50..d0547d8a932 100644
--- a/mysql-test/suite/perfschema/t/nesting.test
+++ b/mysql-test/suite/perfschema/t/nesting.test
@@ -39,6 +39,7 @@ update performance_schema.setup_instruments set enabled='YES', timed='YES'
'wait/io/socket/sql/client_connection',
'wait/synch/rwlock/sql/LOCK_grant',
'wait/synch/mutex/sql/THD::LOCK_thd_data',
+ 'wait/synch/mutex/sql/THD::LOCK_thd_kill',
'wait/io/file/sql/query_log');
update performance_schema.setup_instruments set enabled='YES', timed='YES'
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index 1e808a17604..225a3172dc1 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -648,14 +648,11 @@ Event_scheduler::stop()
state= STOPPING;
DBUG_PRINT("info", ("Scheduler thread has id %lu",
(ulong) scheduler_thd->thread_id));
- /* Lock from delete */
- mysql_mutex_lock(&scheduler_thd->LOCK_thd_data);
/* This will wake up the thread if it waits on Queue's conditional */
sql_print_information("Event Scheduler: Killing the scheduler thread, "
"thread id %lu",
(ulong) scheduler_thd->thread_id);
scheduler_thd->awake(KILL_CONNECTION);
- mysql_mutex_unlock(&scheduler_thd->LOCK_thd_data);
/* thd could be 0x0, when shutting down */
sql_print_information("Event Scheduler: "
diff --git a/sql/my_apc.cc b/sql/my_apc.cc
index b165a801ce5..2699ac9c60b 100644
--- a/sql/my_apc.cc
+++ b/sql/my_apc.cc
@@ -34,7 +34,7 @@
void Apc_target::init(mysql_mutex_t *target_mutex)
{
DBUG_ASSERT(!enabled);
- LOCK_thd_data_ptr= target_mutex;
+ LOCK_thd_kill_ptr= target_mutex;
#ifndef DBUG_OFF
n_calls_processed= 0;
#endif
@@ -45,7 +45,7 @@ void Apc_target::init(mysql_mutex_t *target_mutex)
void Apc_target::enqueue_request(Call_request *qe)
{
- mysql_mutex_assert_owner(LOCK_thd_data_ptr);
+ mysql_mutex_assert_owner(LOCK_thd_kill_ptr);
if (apc_calls)
{
Call_request *after= apc_calls->prev;
@@ -71,7 +71,7 @@ void Apc_target::enqueue_request(Call_request *qe)
void Apc_target::dequeue_request(Call_request *qe)
{
- mysql_mutex_assert_owner(LOCK_thd_data_ptr);
+ mysql_mutex_assert_owner(LOCK_thd_kill_ptr);
if (apc_calls == qe)
{
if ((apc_calls= apc_calls->next) == qe)
@@ -145,14 +145,14 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call,
int wait_res= 0;
PSI_stage_info old_stage;
- caller_thd->ENTER_COND(&apc_request.COND_request, LOCK_thd_data_ptr,
+ caller_thd->ENTER_COND(&apc_request.COND_request, LOCK_thd_kill_ptr,
&stage_show_explain, &old_stage);
/* todo: how about processing other errors here? */
while (!apc_request.processed && (wait_res != ETIMEDOUT))
{
- /* We own LOCK_thd_data_ptr */
+ /* We own LOCK_thd_kill_ptr */
wait_res= mysql_cond_timedwait(&apc_request.COND_request,
- LOCK_thd_data_ptr, &abstime);
+ LOCK_thd_kill_ptr, &abstime);
// &apc_request.LOCK_request, &abstime);
if (caller_thd->killed)
break;
@@ -163,7 +163,7 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call,
/*
The wait has timed out, or this thread was KILLed.
Remove the request from the queue (ok to do because we own
- LOCK_thd_data_ptr)
+ LOCK_thd_kill_ptr)
*/
apc_request.processed= TRUE;
dequeue_request(&apc_request);
@@ -176,7 +176,7 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call,
res= FALSE;
}
/*
- exit_cond() will call mysql_mutex_unlock(LOCK_thd_data_ptr) for us:
+ exit_cond() will call mysql_mutex_unlock(LOCK_thd_kill_ptr) for us:
*/
caller_thd->EXIT_COND(&old_stage);
@@ -185,7 +185,7 @@ bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call,
}
else
{
- mysql_mutex_unlock(LOCK_thd_data_ptr);
+ mysql_mutex_unlock(LOCK_thd_kill_ptr);
}
return res;
}
@@ -202,11 +202,11 @@ void Apc_target::process_apc_requests()
{
Call_request *request;
- mysql_mutex_lock(LOCK_thd_data_ptr);
+ mysql_mutex_lock(LOCK_thd_kill_ptr);
if (!(request= get_first_in_queue()))
{
/* No requests in the queue */
- mysql_mutex_unlock(LOCK_thd_data_ptr);
+ mysql_mutex_unlock(LOCK_thd_kill_ptr);
break;
}
@@ -225,7 +225,7 @@ void Apc_target::process_apc_requests()
n_calls_processed++;
#endif
mysql_cond_signal(&request->COND_request);
- mysql_mutex_unlock(LOCK_thd_data_ptr);
+ mysql_mutex_unlock(LOCK_thd_kill_ptr);
}
}
diff --git a/sql/my_apc.h b/sql/my_apc.h
index 46c6fbd549d..a04e09257b9 100644
--- a/sql/my_apc.h
+++ b/sql/my_apc.h
@@ -44,7 +44,7 @@ class THD;
*/
class Apc_target
{
- mysql_mutex_t *LOCK_thd_data_ptr;
+ mysql_mutex_t *LOCK_thd_kill_ptr;
public:
Apc_target() : enabled(0), apc_calls(NULL) {}
~Apc_target() { DBUG_ASSERT(!enabled && !apc_calls);}
@@ -66,9 +66,9 @@ public:
void disable()
{
DBUG_ASSERT(enabled);
- mysql_mutex_lock(LOCK_thd_data_ptr);
+ mysql_mutex_lock(LOCK_thd_kill_ptr);
bool process= !--enabled && have_apc_requests();
- mysql_mutex_unlock(LOCK_thd_data_ptr);
+ mysql_mutex_unlock(LOCK_thd_kill_ptr);
if (unlikely(process))
process_apc_requests();
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 374a988537f..c1e14974c35 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1704,7 +1704,7 @@ static void close_connections(void)
#endif
tmp->set_killed(KILL_SERVER_HARD);
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
- mysql_mutex_lock(&tmp->LOCK_thd_data);
+ mysql_mutex_lock(&tmp->LOCK_thd_kill);
if (tmp->mysys_var)
{
tmp->mysys_var->abort=1;
@@ -1727,7 +1727,7 @@ static void close_connections(void)
}
mysql_mutex_unlock(&tmp->mysys_var->mutex);
}
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ mysql_mutex_unlock(&tmp->LOCK_thd_kill);
}
mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list
diff --git a/sql/slave.cc b/sql/slave.cc
index c6ac31677cf..c7acaec9e21 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -343,9 +343,7 @@ handle_slave_background(void *arg __attribute__((unused)))
THD *to_kill= p->to_kill;
kill_list= p->next;
- mysql_mutex_lock(&to_kill->LOCK_thd_data);
to_kill->awake(KILL_CONNECTION);
- mysql_mutex_unlock(&to_kill->LOCK_thd_data);
mysql_mutex_lock(&to_kill->LOCK_wakeup_ready);
to_kill->rgi_slave->killed_for_retry=
rpl_group_info::RETRY_KILL_KILLED;
@@ -856,7 +854,7 @@ terminate_slave_thread(THD *thd,
int error __attribute__((unused));
DBUG_PRINT("loop", ("killing slave thread"));
- mysql_mutex_lock(&thd->LOCK_thd_data);
+ mysql_mutex_lock(&thd->LOCK_thd_kill);
#ifndef DONT_USE_THR_ALARM
/*
Error codes from pthread_kill are:
@@ -866,9 +864,9 @@ terminate_slave_thread(THD *thd,
int err __attribute__((unused))= pthread_kill(thd->real_id, thr_client_alarm);
DBUG_ASSERT(err != EINVAL);
#endif
- thd->awake(NOT_KILLED);
+ thd->awake_no_mutex(NOT_KILLED);
- mysql_mutex_unlock(&thd->LOCK_thd_data);
+ mysql_mutex_unlock(&thd->LOCK_thd_kill);
/*
There is a small chance that slave thread might miss the first
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 7af1170d107..c4ac5705c08 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -555,8 +555,6 @@ char *thd_get_error_context_description(THD *thd, char *buffer,
char header[256];
int len;
- mysql_mutex_lock(&LOCK_thread_count);
-
/*
The pointers thd->query and thd->proc_info might change since they are
being modified concurrently. This is acceptable for proc_info since its
@@ -612,7 +610,6 @@ char *thd_get_error_context_description(THD *thd, char *buffer,
}
mysql_mutex_unlock(&thd->LOCK_thd_data);
}
- mysql_mutex_unlock(&LOCK_thread_count);
if (str.c_ptr_safe() == buffer)
return buffer;
@@ -704,10 +701,8 @@ handle_condition(THD *thd,
extern "C" void thd_kill_timeout(THD* thd)
{
thd->status_var.max_statement_time_exceeded++;
- mysql_mutex_lock(&thd->LOCK_thd_data);
/* Kill queries that can't cause data corruptions */
thd->awake(KILL_TIMEOUT);
- mysql_mutex_unlock(&thd->LOCK_thd_data);
}
@@ -1363,7 +1358,7 @@ void THD::init(void)
session_tracker.enable(this);
#endif //EMBEDDED_LIBRARY
- apc_target.init(&LOCK_thd_data);
+ apc_target.init(&LOCK_thd_kill);
DBUG_VOID_RETURN;
}
@@ -1627,9 +1622,13 @@ THD::~THD()
if (!status_in_global)
add_status_to_global();
- /* Ensure that no one is using THD */
- mysql_mutex_lock(&LOCK_thd_data);
- mysql_mutex_unlock(&LOCK_thd_data);
+ /*
+ 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
+ */
+ mysql_mutex_lock(&LOCK_thd_kill);
+ mysql_mutex_unlock(&LOCK_thd_kill);
#ifdef WITH_WSREP
mysql_mutex_lock(&LOCK_wsrep_thd);
@@ -1802,17 +1801,17 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
This is normally called from another thread's THD object.
- @note Do always call this while holding LOCK_thd_data.
+ @note Do always call this while holding LOCK_thd_kill.
NOT_KILLED is used to awake a thread for a slave
*/
-void THD::awake(killed_state state_to_set)
+void THD::awake_no_mutex(killed_state state_to_set)
{
DBUG_ENTER("THD::awake");
DBUG_PRINT("enter", ("this: %p current_thd: %p state: %d",
this, current_thd, (int) state_to_set));
THD_CHECK_SENTRY(this);
- mysql_mutex_assert_owner(&LOCK_thd_data);
+ mysql_mutex_assert_owner(&LOCK_thd_kill);
print_aborted_warning(3, "KILLED");
@@ -1823,8 +1822,6 @@ void THD::awake(killed_state state_to_set)
if (killed >= KILL_CONNECTION)
state_to_set= killed;
- /* Set the 'killed' flag of 'this', which is the target THD object. */
- mysql_mutex_lock(&LOCK_thd_kill);
set_killed_no_mutex(state_to_set);
if (state_to_set >= KILL_CONNECTION || state_to_set == NOT_KILLED)
@@ -1911,7 +1908,6 @@ void THD::awake(killed_state state_to_set)
}
mysql_mutex_unlock(&mysys_var->mutex);
}
- mysql_mutex_unlock(&LOCK_thd_kill);
DBUG_VOID_RETURN;
}
@@ -1927,10 +1923,10 @@ void THD::disconnect()
{
Vio *vio= NULL;
- mysql_mutex_lock(&LOCK_thd_data);
-
set_killed(KILL_CONNECTION);
+ mysql_mutex_lock(&LOCK_thd_data);
+
#ifdef SIGNAL_WITH_VIO_CLOSE
/*
Since a active vio might might have not been set yet, in
@@ -1963,9 +1959,9 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
{
/* This code is similar to kill_delayed_threads() */
DBUG_PRINT("info", ("kill delayed thread"));
- mysql_mutex_lock(&in_use->LOCK_thd_data);
+ mysql_mutex_lock(&in_use->LOCK_thd_kill);
if (in_use->killed < KILL_CONNECTION)
- in_use->set_killed(KILL_CONNECTION);
+ in_use->set_killed_no_mutex(KILL_CONNECTION);
if (in_use->mysys_var)
{
mysql_mutex_lock(&in_use->mysys_var->mutex);
@@ -1976,7 +1972,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
in_use->mysys_var->abort= 1;
mysql_mutex_unlock(&in_use->mysys_var->mutex);
}
- mysql_mutex_unlock(&in_use->LOCK_thd_data);
+ mysql_mutex_unlock(&in_use->LOCK_thd_kill);
signalled= TRUE;
}
@@ -2084,7 +2080,7 @@ bool THD::store_globals()
return 1;
/*
mysys_var is concurrently readable by a killer thread.
- It is protected by LOCK_thd_data, it is not needed to lock while the
+ It is protected by LOCK_thd_kill, it is not needed to lock while the
pointer is changing from NULL not non-NULL. If the kill thread reads
NULL it doesn't refer to anything, but if it is non-NULL we need to
ensure that the thread doesn't proceed to assign another thread to
@@ -2135,9 +2131,9 @@ bool THD::store_globals()
void THD::reset_globals()
{
- mysql_mutex_lock(&LOCK_thd_data);
+ mysql_mutex_lock(&LOCK_thd_kill);
mysys_var= 0;
- mysql_mutex_unlock(&LOCK_thd_data);
+ mysql_mutex_unlock(&LOCK_thd_kill);
/* Undocking the thread specific data. */
set_current_thd(0);
@@ -5429,9 +5425,9 @@ void THD::set_query_and_id(char *query_arg, uint32 query_length_arg,
/** Assign a new value to thd->mysys_var. */
void THD::set_mysys_var(struct st_my_thread_var *new_mysys_var)
{
- mysql_mutex_lock(&LOCK_thd_data);
+ mysql_mutex_lock(&LOCK_thd_kill);
mysys_var= new_mysys_var;
- mysql_mutex_unlock(&LOCK_thd_data);
+ mysql_mutex_unlock(&LOCK_thd_kill);
}
/**
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 8e99d57d0b4..d733aea1756 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2127,11 +2127,15 @@ public:
- thd->query and thd->query_length (used by SHOW ENGINE
INNODB STATUS and SHOW PROCESSLIST
- thd->db and thd->db_length (used in SHOW PROCESSLIST)
- - thd->mysys_var (used by KILL statement and shutdown).
Is locked when THD is deleted.
*/
mysql_mutex_t LOCK_thd_data;
- /* Protect kill information */
+ /*
+ Protects:
+ - kill information
+ - mysys_var (used by KILL statement and shutdown).
+ - Also ensures that THD is not deleted while mutex is hold
+ */
mysql_mutex_t LOCK_thd_kill;
/* all prepared statements and cursors of this connection */
@@ -3131,7 +3135,13 @@ public:
}
void close_active_vio();
#endif
- void awake(killed_state state_to_set);
+ void awake_no_mutex(killed_state state_to_set);
+ void awake(killed_state state_to_set)
+ {
+ mysql_mutex_lock(&LOCK_thd_kill);
+ awake_no_mutex(state_to_set);
+ mysql_mutex_unlock(&LOCK_thd_kill);
+ }
/** Disconnect the associated communication endpoint. */
void disconnect();
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 698ff8246ed..07b03baaf27 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2702,9 +2702,9 @@ void kill_delayed_threads(void)
Delayed_insert *di;
while ((di= it++))
{
- mysql_mutex_lock(&di->thd.LOCK_thd_data);
+ mysql_mutex_lock(&di->thd.LOCK_thd_kill);
if (di->thd.killed < KILL_CONNECTION)
- di->thd.set_killed(KILL_CONNECTION);
+ di->thd.set_killed_no_mutex(KILL_CONNECTION);
if (di->thd.mysys_var)
{
mysql_mutex_lock(&di->thd.mysys_var->mutex);
@@ -2722,7 +2722,7 @@ void kill_delayed_threads(void)
}
mysql_mutex_unlock(&di->thd.mysys_var->mutex);
}
- mysql_mutex_unlock(&di->thd.LOCK_thd_data);
+ mysql_mutex_unlock(&di->thd.LOCK_thd_kill);
}
mysql_mutex_unlock(&LOCK_delayed_insert); // For unlink from list
DBUG_VOID_RETURN;
@@ -3076,9 +3076,9 @@ pthread_handler_t handle_delayed_insert(void *arg)
this.
*/
mysql_mutex_lock(&thd->LOCK_thd_data);
- thd->set_killed(KILL_CONNECTION_HARD); // If error
thd->mdl_context.set_needs_thr_lock_abort(0);
mysql_mutex_unlock(&thd->LOCK_thd_data);
+ thd->set_killed(KILL_CONNECTION_HARD); // If error
close_thread_tables(thd); // Free the table
thd->mdl_context.release_transactional_locks();
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 4246c9cdae9..2030c34d977 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -8758,13 +8758,13 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
/**
- Find a thread by id and return it, locking it LOCK_thd_data
+ Find a thread by id and return it, locking it LOCK_thd_kill
@param id Identifier of the thread we're looking for
@param query_id If true, search by query_id instead of thread_id
@return NULL - not found
- pointer - thread found, and its LOCK_thd_data is locked.
+ pointer - thread found, and its LOCK_thd_kill is locked.
*/
THD *find_thread_by_id(longlong id, bool query_id)
@@ -8778,7 +8778,7 @@ THD *find_thread_by_id(longlong id, bool query_id)
continue;
if (id == (query_id ? tmp->query_id : (longlong) tmp->thread_id))
{
- mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
+ mysql_mutex_lock(&tmp->LOCK_thd_kill); // Lock from delete
break;
}
}
@@ -8834,13 +8834,13 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
thd->security_ctx->user_matches(tmp->security_ctx)) &&
!wsrep_thd_is_BF(tmp, true))
{
- tmp->awake(kill_signal);
+ tmp->awake_no_mutex(kill_signal);
error=0;
}
else
error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR :
ER_KILL_DENIED_ERROR);
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ mysql_mutex_unlock(&tmp->LOCK_thd_kill);
}
DBUG_PRINT("exit", ("%d", error));
DBUG_RETURN(error);
@@ -8898,7 +8898,7 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user,
DBUG_RETURN(ER_KILL_DENIED_ERROR);
}
if (!threads_to_kill.push_back(tmp, thd->mem_root))
- mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
+ mysql_mutex_lock(&tmp->LOCK_thd_kill); // Lock from delete
}
}
mysql_mutex_unlock(&LOCK_thread_count);
@@ -8909,17 +8909,17 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user,
THD *ptr= it2++;
do
{
- ptr->awake(kill_signal);
+ ptr->awake_no_mutex(kill_signal);
/*
Careful here: The list nodes are allocated on the memroots of the
THDs to be awakened.
But those THDs may be terminated and deleted as soon as we release
- LOCK_thd_data, which will make the list nodes invalid.
+ LOCK_thd_kill, which will make the list nodes invalid.
Since the operation "it++" dereferences the "next" pointer of the
- previous list node, we need to do this while holding LOCK_thd_data.
+ previous list node, we need to do this while holding LOCK_thd_kill.
*/
next_ptr= it2++;
- mysql_mutex_unlock(&ptr->LOCK_thd_data);
+ mysql_mutex_unlock(&ptr->LOCK_thd_kill);
(*rows)++;
} while ((ptr= next_ptr));
}
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 7586e8837d0..36808e9e986 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -3344,7 +3344,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
if (tmp->get_command() == COM_BINLOG_DUMP &&
tmp->variables.server_id == slave_server_id)
{
- mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
+ mysql_mutex_lock(&tmp->LOCK_thd_kill); // Lock from delete
break;
}
}
@@ -3356,8 +3356,8 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
it will be slow because it will iterate through the list
again. We just to do kill the thread ourselves.
*/
- tmp->awake(KILL_SLAVE_SAME_ID);
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ tmp->awake_no_mutex(KILL_SLAVE_SAME_ID);
+ mysql_mutex_unlock(&tmp->LOCK_thd_kill);
}
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index bb6a03fff96..f5ce91c6612 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2578,23 +2578,28 @@ static const char *thread_state_info(THD *tmp)
{
if (tmp->net.reading_or_writing == 2)
return "Writing to net";
- else if (tmp->get_command() == COM_SLEEP)
+ if (tmp->get_command() == COM_SLEEP)
return "";
- else
- return "Reading from net";
+ return "Reading from net";
}
- else
#endif
+
+ if (tmp->proc_info)
+ return tmp->proc_info;
+
+ /* Check if we are waiting on a condition */
+ if (!trylock_short(&tmp->LOCK_thd_kill))
{
- if (tmp->proc_info)
- return tmp->proc_info;
- else if (tmp->mysys_var && tmp->mysys_var->current_cond)
+ /* mysys_var is protected by above mutex */
+ bool cond= tmp->mysys_var && tmp->mysys_var->current_cond;
+ mysql_mutex_unlock(&tmp->LOCK_thd_kill);
+ if (cond)
return "Waiting on cond";
- else
- return NULL;
}
+ return NULL;
}
+
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
{
Item *field;
@@ -2657,8 +2662,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
while ((tmp=it++))
{
Security_context *tmp_sctx= tmp->security_ctx;
- struct st_my_thread_var *mysys_var= 0;
- bool got_thd_data, got_mysys_lock= 0;
+ bool got_thd_data;
if ((tmp->vio_ok() || tmp->system_thread) &&
(!user || (!tmp->system_thread &&
tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
@@ -2684,17 +2688,10 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thd_info->command=(int) tmp->get_command();
if ((got_thd_data= !trylock_short(&tmp->LOCK_thd_data)))
- if ((mysys_var= tmp->mysys_var))
- got_mysys_lock= !trylock_short(&mysys_var->mutex);
-
- if (got_thd_data)
{
- /* This is correct under mysys_lock, otherwise an approximation */
+ /* This is an approximation */
thd_info->proc_info= (char*) (tmp->killed >= KILL_QUERY ?
"Killed" : 0);
- if (got_mysys_lock)
- mysql_mutex_unlock(&mysys_var->mutex);
-
/*
The following variables are only safe to access under a lock
*/
@@ -2952,13 +2949,13 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond)
tmp_sctx->user)))
{
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "PROCESS");
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ mysql_mutex_unlock(&tmp->LOCK_thd_kill);
DBUG_RETURN(1);
}
if (tmp == thd)
{
- mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ mysql_mutex_unlock(&tmp->LOCK_thd_kill);
my_error(ER_TARGET_NOT_EXPLAINABLE, MYF(0));
DBUG_RETURN(1);
}
@@ -2966,7 +2963,7 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond)
bool bres;
/*
Ok we've found the thread of interest and it won't go away because
- we're holding its LOCK_thd data. Post it a SHOW EXPLAIN request.
+ we're holding its LOCK_thd_kill. Post it a SHOW EXPLAIN request.
*/
bool timed_out;
int timeout_sec= 30;
@@ -3059,10 +3056,9 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
while ((tmp= it++))
{
Security_context *tmp_sctx= tmp->security_ctx;
- struct st_my_thread_var *mysys_var= 0;
const char *val, *db;
ulonglong max_counter;
- bool got_thd_data, got_mysys_lock= 0;
+ bool got_thd_data;
if ((!tmp->vio_ok() && !tmp->system_thread) ||
(user && (tmp->system_thread || !tmp_sctx->user ||
@@ -3090,10 +3086,6 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
strlen(tmp_sctx->host_or_ip), cs);
if ((got_thd_data= !trylock_short(&tmp->LOCK_thd_data)))
- if ((mysys_var= tmp->mysys_var))
- got_mysys_lock= !trylock_short(&mysys_var->mutex);
-
- if (got_thd_data)
{
/* DB */
if ((db= tmp->db))
@@ -3112,9 +3104,6 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
table->field[4]->store(command_name[tmp->get_command()].str,
command_name[tmp->get_command()].length, cs);
- if (got_mysys_lock)
- mysql_mutex_unlock(&mysys_var->mutex);
-
/* MYSQL_TIME */
ulonglong utime= tmp->start_utime;
ulonglong utime_after_query_snapshot= tmp->utime_after_query;
@@ -3124,13 +3113,6 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
table->field[5]->store(utime / HRTIME_RESOLUTION, TRUE);
- /* STATE */
- if ((val= thread_state_info(tmp)))
- {
- table->field[6]->store(val, strlen(val), cs);
- table->field[6]->set_notnull();
- }
-
if (got_thd_data)
{
if (tmp->query())
@@ -3162,6 +3144,13 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
mysql_mutex_unlock(&tmp->LOCK_thd_data);
}
+ /* STATE */
+ if ((val= thread_state_info(tmp)))
+ {
+ table->field[6]->store(val, strlen(val), cs);
+ table->field[6]->set_notnull();
+ }
+
/* TIME_MS */
table->field[8]->store((double)(utime / (HRTIME_RESOLUTION / 1000.0)));
diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc
index 598951da406..98b2dcd1fcd 100644
--- a/sql/threadpool_common.cc
+++ b/sql/threadpool_common.cc
@@ -250,7 +250,7 @@ static THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data)
}
delete connect;
add_to_active_threads(thd);
- thd->mysys_var= mysys_var;
+ thd->set_mysys_var(mysys_var);
thd->event_scheduler.data= scheduler_data;
/* Create new PSI thread for use with the THD. */
@@ -477,11 +477,11 @@ void tp_timeout_handler(TP_connection *c)
if (c->state != TP_STATE_IDLE)
return;
THD *thd=c->thd;
- mysql_mutex_lock(&thd->LOCK_thd_data);
+ mysql_mutex_lock(&thd->LOCK_thd_kill);
thd->set_killed(KILL_WAIT_TIMEOUT);
c->priority= TP_PRIORITY_HIGH;
post_kill_notification(thd);
- mysql_mutex_unlock(&thd->LOCK_thd_data);
+ mysql_mutex_unlock(&thd->LOCK_thd_kill);
}
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 7800ec5e627..00f1b777f17 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -2492,9 +2492,7 @@ extern "C" void wsrep_thd_awake(THD *thd, my_bool signal)
{
if (signal)
{
- mysql_mutex_lock(&thd->LOCK_thd_data);
thd->awake(KILL_QUERY);
- mysql_mutex_unlock(&thd->LOCK_thd_data);
}
else
{