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:
@ -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)));
|
||||
|
||||
|
Reference in New Issue
Block a user