mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Move all kill mutex protection to LOCK_thd_kill
LOCK_thd_data was used to protect both THD data and ensure that the THD is not deleted while it was in use This patch moves the THD delete protection to LOCK_thd_kill, which already protects the THD for kill. The benefits are: - More well defined what LOCK_thd_data protects - LOCK_thd_data usage is now much simpler and easier to verify - Less chance of deadlocks in SHOW PROCESS LIST as there is less chance of interactions between mutexes - Remove not needed LOCK_thread_count from thd_get_error_context_description() - Fewer mutex taken for thd->awake() Other things: - Don't take mysys->var mutex in show processlist to check if thread is kill marked - thd->awake() now automatically takes the LOCK_thd_kill mutex (Simplifies code) - Apc uses LOCK_thd_kill instead of LOCK_thd_data
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user