diff options
author | Michael Widenius <monty@askmonty.org> | 2013-01-11 00:22:14 +0200 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2013-01-11 00:22:14 +0200 |
commit | 6e9a48b67fceab17089ca4cd1406e302386a601b (patch) | |
tree | 41cca1d2f6ee3439b6b70e60608430164a8a8843 /sql/sql_class.cc | |
parent | 396f4d62c69335b8f7aefd43bbe099e8bb9e6905 (diff) | |
download | mariadb-git-6e9a48b67fceab17089ca4cd1406e302386a601b.tar.gz |
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.
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 42952585e07..312de8c74e4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -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) */ - |