summaryrefslogtreecommitdiff
path: root/sql/protocol.cc
diff options
context:
space:
mode:
authorunknown <anozdrin/alik@ibm.>2007-11-30 16:12:20 +0300
committerunknown <anozdrin/alik@ibm.>2007-11-30 16:12:20 +0300
commit4b954cc094d2082982a1ac2cab99d1e905309048 (patch)
tree9d9e129506ee56e40def9af807200245632fb7a9 /sql/protocol.cc
parent90477e23e225170ee1c84067cdc1d612cc2978f6 (diff)
downloadmariadb-git-4b954cc094d2082982a1ac2cab99d1e905309048.tar.gz
A patch for BUG#32148: killing a query may be ineffective.
The problem was that THD::killed was reset after a command was read from the socket, but before it was actually handled. That lead to a race: if another KILL statement was issued for this connection in the middle of reading from the socket and processing a command, THD::killed state would be cleaned. The fix is to move this cleanup into net_send_error() function. A sample test case exists in binlog_killed.test: - connection 1: start a new transaction on table t1; - connection 2: send query to the server (w/o waiting for the result) to update data in table t1 -- this query will be blocked since there is unfinished transaction; - connection 1: kill query in connection 2 and finish the transaction; - connection 2: get result of the previous query -- it should be the "query-killed" error. This test however contains race condition, which can not be fixed with the current protocol: there is no way to guarantee, that the server will receive and start processing the query in connection 2 (which is intended to get blocked) before the KILL command (sent in the connection 1) will arrive. In other words, there is no way to ensure that the following sequence will not happen: - connection 1: start a new transaction on table t1; - connection 1: kill query in connection 2 and finish the transaction; - connection 2: send query to the server (w/o waiting for the result) to update data in table t1 -- this query will be blocked since there is unfinished transaction; - connection 2: get result of the previous query -- the query will succeed. So, there is no test case for this bug, since it's impossible to write a reliable test case under the current circumstances. sql/protocol.cc: Move thd->killed cleanup from dispatch_command() to net_send_error(). sql/sql_parse.cc: Move thd->killed cleanup from dispatch_command() to net_send_error().
Diffstat (limited to 'sql/protocol.cc')
-rw-r--r--sql/protocol.cc6
1 files changed, 6 insertions, 0 deletions
diff --git a/sql/protocol.cc b/sql/protocol.cc
index bf8faec006a..713f4ed3d25 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -76,6 +76,12 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
DBUG_ASSERT(!thd->spcont);
+ if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
+ {
+ thd->killed= THD::NOT_KILLED;
+ thd->mysys_var->abort= 0;
+ }
+
if (net && net->no_send_error)
{
thd->clear_error();