mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fixed some race conditons and bugs related to killed queries
KILL now breaks locks inside InnoDB Fixed possible deadlock when running INNODB STATUS Added ha_kill_query() and kill_query() to send kill signal to all storage engines Added reset_killed() to ensure we don't reset killed state while awake() is getting called include/mysql/plugin.h: Added thd_mark_as_hard_kill() include/mysql/plugin_audit.h.pp: Added thd_mark_as_hard_kill() include/mysql/plugin_auth.h.pp: Added thd_mark_as_hard_kill() include/mysql/plugin_ftparser.h.pp: Added thd_mark_as_hard_kill() sql/handler.cc: Added ha_kill_query() to send kill signal to all storage engines sql/handler.h: Added ha_kill_query() and kill_query() to send kill signal to all storage engines sql/log_event.cc: Use reset_killed() sql/mdl.cc: use thd->killed instead of thd_killed() to abort on soft kill sql/sp_rcontext.cc: Use reset_killed() sql/sql_class.cc: Fixed possible deadlock in INNODB STATUS by not getting thd->LOCK_thd_data if it's locked. Use reset_killed() Tell storge engines that KILL has been sent sql/sql_class.h: Added reset_killed() to ensure we don't reset killed state while awake() is getting called. Added mark_as_hard_kill() sql/sql_insert.cc: Use reset_killed() sql/sql_parse.cc: Simplify detection of killed queries. Use reset_killed() sql/sql_select.cc: Use reset_killed() sql/sql_union.cc: Use reset_killed() storage/innobase/handler/ha_innodb.cc: Added innobase_kill_query() Fixed error reporting for interrupted queries. storage/xtradb/handler/ha_innodb.cc: Added innobase_kill_query() Fixed error reporting for interrupted queries.
This commit is contained in:
@ -701,7 +701,7 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
|
||||
values doesn't have to very accurate and the memory it points to is static,
|
||||
but we need to attempt a snapshot on the pointer values to avoid using NULL
|
||||
values. The pointer to thd->query however, doesn't point to static memory
|
||||
and has to be protected by LOCK_thread_count or risk pointing to
|
||||
and has to be protected by thd->LOCK_thd_data or risk pointing to
|
||||
uninitialized memory.
|
||||
*/
|
||||
const char *proc_info= thd->proc_info;
|
||||
@ -736,20 +736,21 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
|
||||
str.append(proc_info);
|
||||
}
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
|
||||
if (thd->query())
|
||||
/* Don't wait if LOCK_thd_data is used as this could cause a deadlock */
|
||||
if (!mysql_mutex_trylock(&thd->LOCK_thd_data))
|
||||
{
|
||||
if (max_query_len < 1)
|
||||
len= thd->query_length();
|
||||
else
|
||||
len= min(thd->query_length(), max_query_len);
|
||||
str.append('\n');
|
||||
str.append(thd->query(), len);
|
||||
if (thd->query())
|
||||
{
|
||||
if (max_query_len < 1)
|
||||
len= thd->query_length();
|
||||
else
|
||||
len= min(thd->query_length(), max_query_len);
|
||||
str.append('\n');
|
||||
str.append(thd->query(), len);
|
||||
}
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
if (str.c_ptr_safe() == buffer)
|
||||
return buffer;
|
||||
|
||||
@ -1355,7 +1356,7 @@ void THD::change_user(void)
|
||||
mysql_mutex_unlock(&LOCK_status);
|
||||
|
||||
cleanup();
|
||||
killed= NOT_KILLED;
|
||||
reset_killed();
|
||||
cleanup_done= 0;
|
||||
init();
|
||||
stmt_map.reset();
|
||||
@ -1610,6 +1611,10 @@ void THD::awake(killed_state state_to_set)
|
||||
MYSQL_CALLBACK(scheduler, post_kill_notification, (this));
|
||||
}
|
||||
|
||||
/* Interrupt target waiting inside a storage engine. */
|
||||
if (state_to_set != NOT_KILLED)
|
||||
ha_kill_query(this, test(state_to_set & KILL_HARD_BIT));
|
||||
|
||||
/* Broadcast a condition to kick the target if it is waiting on it. */
|
||||
if (mysys_var)
|
||||
{
|
||||
@ -3848,6 +3853,18 @@ extern "C" int thd_killed(const MYSQL_THD thd)
|
||||
return thd->killed;
|
||||
}
|
||||
|
||||
/**
|
||||
Change kill level to hard.
|
||||
This ensures that thd_killed() will return true.
|
||||
This is important for storage engines that uses thd_killed() to
|
||||
verify if thread is killed.
|
||||
*/
|
||||
|
||||
extern "C" void thd_mark_as_hard_kill(MYSQL_THD thd)
|
||||
{
|
||||
thd->mark_as_hard_kill();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Send an out-of-band progress report to the client
|
||||
@ -5603,4 +5620,3 @@ bool Discrete_intervals_list::append(Discrete_interval *new_interval)
|
||||
}
|
||||
|
||||
#endif /* !defined(MYSQL_CLIENT) */
|
||||
|
||||
|
Reference in New Issue
Block a user