Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
3e90dc1f
Commit
3e90dc1f
authored
Jul 05, 2012
by
Sergey Petrunya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MWL#182: Explain running statements
- Make SHOW EXPLAIN command be KILLable with KILL QUERY.
parent
b97678f0
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
140 additions
and
11 deletions
+140
-11
mysql-test/r/show_explain.result
mysql-test/r/show_explain.result
+40
-0
mysql-test/t/show_explain.test
mysql-test/t/show_explain.test
+49
-2
sql/my_apc.cc
sql/my_apc.cc
+16
-5
sql/my_apc.h
sql/my_apc.h
+3
-1
sql/sql_show.cc
sql/sql_show.cc
+6
-2
unittest/sql/my_apc-t.cc
unittest/sql/my_apc-t.cc
+26
-1
No files found.
mysql-test/r/show_explain.result
View file @
3e90dc1f
...
...
@@ -775,4 +775,44 @@ a
set debug_dbug='';
revoke all privileges on test.* from test2@localhost;
drop user test2@localhost;
#
# Test that it is possible to KILL a SHOW EXPLAIN command that's waiting
# on its target thread
#
create table t1 (pk int primary key, data char(64)) engine=innodb;
insert into t1 select A.a + 10 * B.a + 100 * C.a, 'data1' from t0 A, t0 B, t0 C;
# Lock two threads
set autocommit=0;
select * from t1 where pk between 10 and 20 for update;
pk data
10 data1
11 data1
12 data1
13 data1
14 data1
15 data1
16 data1
17 data1
18 data1
19 data1
20 data1
set autocommit=0;
select * from t1 where pk between 10 and 20 for update;
show explain for 3;
kill query $thr_default;
ERROR 70100: Query execution was interrupted
rollback;
pk data
10 data1
11 data1
12 data1
13 data1
14 data1
15 data1
16 data1
17 data1
18 data1
19 data1
20 data1
drop table t1;
drop table t0;
mysql-test/t/show_explain.test
View file @
3e90dc1f
...
...
@@ -2,6 +2,7 @@
# Tests for SHOW EXPLAIN FOR functionality
#
--
source
include
/
have_debug
.
inc
--
source
include
/
have_innodb
.
inc
--
disable_warnings
drop
table
if
exists
t0
,
t1
,
t2
,
t3
,
t4
;
...
...
@@ -788,11 +789,57 @@ connection con1;
reap
;
set
debug_dbug
=
''
;
revoke
all
privileges
on
test
.*
from
test2
@
localhost
;
drop
user
test2
@
localhost
;
disconnect
con2
;
--
echo
#
--
echo
# Test that it is possible to KILL a SHOW EXPLAIN command that's waiting
--
echo
# on its target thread
--
echo
#
connect
(
con2
,
localhost
,
root
,,);
connect
(
con3
,
localhost
,
root
,,);
connection
con2
;
create
table
t1
(
pk
int
primary
key
,
data
char
(
64
))
engine
=
innodb
;
insert
into
t1
select
A
.
a
+
10
*
B
.
a
+
100
*
C
.
a
,
'data1'
from
t0
A
,
t0
B
,
t0
C
;
--
echo
# Lock two threads
set
autocommit
=
0
;
select
*
from
t1
where
pk
between
10
and
20
for
update
;
connection
con1
;
set
autocommit
=
0
;
# This will freeze
send
select
*
from
t1
where
pk
between
10
and
20
for
update
;
# run SHOW EXPLAIN on a frozen thread
connection
default
;
let
$wait_condition
=
select
State
=
'Sending data'
from
information_schema
.
processlist
where
id
=
$thr2
;
let
$thr_default
=
`select connection_id()`
;
--
source
include
/
wait_condition
.
inc
send_eval
show
explain
for
$thr2
;
# kill the SHOW EXPLAIN command
connection
con3
;
let
$wait_condition
=
select
State
=
'show_explain'
from
information_schema
.
processlist
where
id
=
$thr_default
;
--
source
include
/
wait_condition
.
inc
evalp
kill
query
$thr_default
;
connection
default
;
--
error
ER_QUERY_INTERRUPTED
reap
;
connection
con2
;
rollback
;
connection
con1
;
reap
;
drop
table
t1
;
disconnect
con3
;
disconnect
con2
;
## TODO: Test this: have several SHOW EXPLAIN requests be queued up for a
## thread and served together.
...
...
sql/my_apc.cc
View file @
3e90dc1f
...
...
@@ -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
);
...
...
sql/my_apc.h
View file @
3e90dc1f
...
...
@@ -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 */
...
...
sql/sql_show.cc
View file @
3e90dc1f
...
...
@@ -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
),
...
...
unittest/sql/my_apc-t.cc
View file @
3e90dc1f
...
...
@@ -24,6 +24,29 @@
#include <tap.h>
/*
A fake THD with enter_cond/exit_cond and some other members.
*/
class
THD
{
mysql_mutex_t
*
thd_mutex
;
public:
bool
killed
;
THD
()
:
killed
(
FALSE
)
{}
inline
const
char
*
enter_cond
(
mysql_cond_t
*
cond
,
mysql_mutex_t
*
mutex
,
const
char
*
msg
)
{
mysql_mutex_assert_owner
(
mutex
);
thd_mutex
=
mutex
;
return
NULL
;
}
inline
void
exit_cond
(
const
char
*
old_msg
)
{
mysql_mutex_unlock
(
thd_mutex
);
}
};
#include "../sql/my_apc.h"
#define MY_APC_STANDALONE 1
...
...
@@ -115,6 +138,8 @@ void *test_apc_requestor_thread(void *ptr)
{
my_thread_init
();
fprintf
(
stderr
,
"# test_apc_requestor_thread started
\n
"
);
THD
my_thd
;
while
(
!
requestors_should_exit
)
{
int
dst_value
=
0
;
...
...
@@ -124,7 +149,7 @@ void *test_apc_requestor_thread(void *ptr)
bool
timed_out
;
mysql_mutex_lock
(
&
target_mutex
);
bool
res
=
apc_target
.
make_apc_call
(
&
apc_order
,
60
,
&
timed_out
);
bool
res
=
apc_target
.
make_apc_call
(
&
my_thd
,
&
apc_order
,
60
,
&
timed_out
);
if
(
res
)
{
if
(
timed_out
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment