diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2012-07-05 22:04:13 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2012-07-05 22:04:13 +0400 |
commit | 3e90dc1f77dc3fa51d542bf82a336753310f7776 (patch) | |
tree | d0c14418aa1ab3d3af27a98cd9a27d603d753fac /sql | |
parent | b97678f066dd9dfb32409c61028080ac14efb1eb (diff) | |
download | mariadb-git-3e90dc1f77dc3fa51d542bf82a336753310f7776.tar.gz |
MWL#182: Explain running statements
- Make SHOW EXPLAIN command be KILLable with KILL QUERY.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/my_apc.cc | 21 | ||||
-rw-r--r-- | sql/my_apc.h | 4 | ||||
-rw-r--r-- | sql/sql_show.cc | 8 |
3 files changed, 25 insertions, 8 deletions
diff --git a/sql/my_apc.cc b/sql/my_apc.cc index 1cc13f41566..dd15daf48a2 100644 --- a/sql/my_apc.cc +++ b/sql/my_apc.cc @@ -145,8 +145,8 @@ void Apc_target::dequeue_request(Call_request *qe) to use thd->enter_cond() calls to be killable) */ -bool Apc_target::make_apc_call(Apc_call *call, int timeout_sec, - bool *timed_out) +bool Apc_target::make_apc_call(THD *caller_thd, Apc_call *call, + int timeout_sec, bool *timed_out) { bool res= TRUE; *timed_out= FALSE; @@ -166,6 +166,9 @@ bool Apc_target::make_apc_call(Apc_call *call, int timeout_sec, set_timespec(abstime, timeout); int wait_res= 0; + const char *old_msg; + old_msg= caller_thd->enter_cond(&apc_request.COND_request, + LOCK_thd_data_ptr, "show_explain"); /* todo: how about processing other errors here? */ while (!apc_request.processed && (wait_res != ETIMEDOUT)) { @@ -173,13 +176,18 @@ bool Apc_target::make_apc_call(Apc_call *call, int timeout_sec, wait_res= mysql_cond_timedwait(&apc_request.COND_request, LOCK_thd_data_ptr, &abstime); // &apc_request.LOCK_request, &abstime); + if (caller_thd->killed) + { + break; + } } if (!apc_request.processed) { /* - The wait has timed out. Remove the request from the queue (ok to do - because we own LOCK_thd_data_ptr. + 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) */ apc_request.processed= TRUE; dequeue_request(&apc_request); @@ -191,7 +199,10 @@ bool Apc_target::make_apc_call(Apc_call *call, int timeout_sec, /* Request was successfully executed and dequeued by the target thread */ res= FALSE; } - mysql_mutex_unlock(LOCK_thd_data_ptr); + /* + exit_cond() will call mysql_mutex_unlock(LOCK_thd_data_ptr) for us: + */ + caller_thd->exit_cond(old_msg); /* Destroy all APC request data */ mysql_cond_destroy(&apc_request.COND_request); diff --git a/sql/my_apc.h b/sql/my_apc.h index 93b934c9df1..84819b9beea 100644 --- a/sql/my_apc.h +++ b/sql/my_apc.h @@ -33,6 +33,8 @@ requestor. */ +class THD; + /* Target for asynchronous procedure calls (APCs). - A target is running in some particular thread, @@ -62,7 +64,7 @@ public: }; /* Make a call in the target thread (see function definition for details) */ - bool make_apc_call(Apc_call *call, int timeout_sec, bool *timed_out); + bool make_apc_call(THD *caller_thd, Apc_call *call, int timeout_sec, bool *timed_out); #ifndef DBUG_OFF int n_calls_processed; /* Number of calls served by this target */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d26c8f18340..6c407f0cec3 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2084,11 +2084,15 @@ void mysqld_show_explain(THD *thd, const char *calling_user, ulong thread_id) explain_req.failed_to_produce= FALSE; /* Ok, we have a lock on target->LOCK_thd_data, can call: */ - bres= tmp->apc_target.make_apc_call(&explain_req, timeout_sec, &timed_out); + bres= tmp->apc_target.make_apc_call(thd, &explain_req, timeout_sec, &timed_out); if (bres || explain_req.failed_to_produce) { - /* TODO not enabled or time out */ + if (thd->killed) + { + thd->send_kill_message(); + } + else if (timed_out) { my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), |