Commit 956f21c3 authored by Julius Goryavsky's avatar Julius Goryavsky

Merge remote-tracking branch 'origin/bb-10.4-MDEV-21910' into 10.4

parents 3280edda 6a1713ac
...@@ -84,6 +84,7 @@ extern struct wsrep_service_st { ...@@ -84,6 +84,7 @@ extern struct wsrep_service_st {
my_bool (*wsrep_get_debug_func)(); my_bool (*wsrep_get_debug_func)();
void (*wsrep_commit_ordered_func)(MYSQL_THD thd); void (*wsrep_commit_ordered_func)(MYSQL_THD thd);
my_bool (*wsrep_thd_is_applying_func)(const MYSQL_THD thd); my_bool (*wsrep_thd_is_applying_func)(const MYSQL_THD thd);
bool (*wsrep_thd_set_wsrep_aborter_func)(MYSQL_THD bf_thd, MYSQL_THD thd);
} *wsrep_service; } *wsrep_service;
#define MYSQL_SERVICE_WSREP_INCLUDED #define MYSQL_SERVICE_WSREP_INCLUDED
...@@ -124,6 +125,7 @@ extern struct wsrep_service_st { ...@@ -124,6 +125,7 @@ extern struct wsrep_service_st {
#define wsrep_get_debug() wsrep_service->wsrep_get_debug_func() #define wsrep_get_debug() wsrep_service->wsrep_get_debug_func()
#define wsrep_commit_ordered(T) wsrep_service->wsrep_commit_ordered_func(T) #define wsrep_commit_ordered(T) wsrep_service->wsrep_commit_ordered_func(T)
#define wsrep_thd_is_applying(T) wsrep_service->wsrep_thd_is_applying_func(T) #define wsrep_thd_is_applying(T) wsrep_service->wsrep_thd_is_applying_func(T)
#define wsrep_thd_set_wsrep_aborter(T) wsrep_service->wsrep_thd_set_wsrep_aborter_func(T1, T2)
#else #else
...@@ -176,6 +178,8 @@ extern "C" my_bool wsrep_thd_is_local(const MYSQL_THD thd); ...@@ -176,6 +178,8 @@ extern "C" my_bool wsrep_thd_is_local(const MYSQL_THD thd);
/* Return true if thd is in high priority mode */ /* Return true if thd is in high priority mode */
/* todo: rename to is_high_priority() */ /* todo: rename to is_high_priority() */
extern "C" my_bool wsrep_thd_is_applying(const MYSQL_THD thd); extern "C" my_bool wsrep_thd_is_applying(const MYSQL_THD thd);
/* set wsrep_aborter for the target THD */
extern "C" bool wsrep_thd_set_wsrep_aborter(MYSQL_THD bf_thd, MYSQL_THD victim_thd);
/* Return true if thd is in TOI mode */ /* Return true if thd is in TOI mode */
extern "C" my_bool wsrep_thd_is_toi(const MYSQL_THD thd); extern "C" my_bool wsrep_thd_is_toi(const MYSQL_THD thd);
/* Return true if thd is in replicating TOI mode */ /* Return true if thd is in replicating TOI mode */
...@@ -216,6 +220,7 @@ extern "C" my_bool wsrep_get_debug(); ...@@ -216,6 +220,7 @@ extern "C" my_bool wsrep_get_debug();
extern "C" void wsrep_commit_ordered(MYSQL_THD thd); extern "C" void wsrep_commit_ordered(MYSQL_THD thd);
extern "C" my_bool wsrep_thd_is_applying(const MYSQL_THD thd); extern "C" my_bool wsrep_thd_is_applying(const MYSQL_THD thd);
extern "C" bool wsrep_thd_set_wsrep_aborter(MYSQL_THD bf_thd, MYSQL_THD victim_thd);
#endif #endif
#endif /* MYSQL_SERVICE_WSREP_INCLUDED */ #endif /* MYSQL_SERVICE_WSREP_INCLUDED */
...@@ -69,21 +69,5 @@ select * from t1; ...@@ -69,21 +69,5 @@ select * from t1;
a b a b
2 1 2 1
disconnect node_2a; disconnect node_2a;
drop table t1; connection node_1;
connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
connection node_2a;
CREATE TABLE t1 (i int primary key);
SET DEBUG_SYNC = "before_wsrep_ordered_commit SIGNAL bwoc_reached WAIT_FOR bwoc_continue";
INSERT INTO t1 VALUES (1);
connection node_2;
SET DEBUG_SYNC = "now WAIT_FOR bwoc_reached";
SET DEBUG_SYNC = "now SIGNAL bwoc_continue";
SET DEBUG_SYNC='RESET';
connection node_2a;
connection node_2;
select * from t1;
i
1
disconnect node_2a;
connection node_2;
drop table t1; drop table t1;
connection node_2;
connection node_1;
connection node_2;
CREATE TABLE t1(a int not null primary key auto_increment,b int) engine=InnoDB;
insert into t1 values (NULL,1);
connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
connection node_2a;
truncate t1;
insert into t1 values (1,0);
begin;
update t1 set b=2 where a=1;
connection node_2;
set session wsrep_sync_wait=0;
connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2;
connection node_2b;
SET GLOBAL debug_dbug = "d,sync.before_wsrep_thd_abort";
connection node_1;
select * from t1;
a b
1 0
update t1 set b= 1 where a=1;
connection node_2b;
SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.before_wsrep_thd_abort_reached";
connection node_2;
SET DEBUG_SYNC= 'before_awake_no_mutex SIGNAL awake_reached WAIT_FOR continue_kill';
connection node_2b;
SET DEBUG_SYNC='now WAIT_FOR awake_reached';
SET GLOBAL debug_dbug = "";
SET DEBUG_SYNC = "now SIGNAL signal.before_wsrep_thd_abort";
SET DEBUG_SYNC = "now SIGNAL continue_kill";
connection node_2;
connection node_2a;
select * from t1;
connection node_2;
SET DEBUG_SYNC = "RESET";
drop table t1;
disconnect node_2a;
connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
connection node_2a;
CREATE TABLE t1 (i int primary key);
SET DEBUG_SYNC = "before_wsrep_ordered_commit SIGNAL bwoc_reached WAIT_FOR bwoc_continue";
INSERT INTO t1 VALUES (1);
connection node_2;
SET DEBUG_SYNC = "now WAIT_FOR bwoc_reached";
SET DEBUG_SYNC = "now SIGNAL bwoc_continue";
SET DEBUG_SYNC='RESET';
connection node_2a;
connection node_2;
select * from t1;
i
1
disconnect node_2a;
connection node_1;
drop table t1;
connection node_2; connection node_2;
connection node_1; connection node_1;
connection node_2;
call mtr.add_suppression("WSREP: Trying to continue unpaused monitor");
connection node_1; connection node_1;
call mtr.add_suppression("WSREP: Trying to continue unpaused monitor"); call mtr.add_suppression("WSREP: Trying to continue unpaused monitor");
CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2; CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2;
......
--source include/galera_cluster.inc --source include/galera_cluster.inc
--source include/have_innodb.inc --source include/have_innodb.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
# #
# Test case 1: Start a transaction on node_2a and kill it # Test case 1: Start a transaction on node_2a and kill it
...@@ -135,56 +133,9 @@ update t1 set a =5, b=2; ...@@ -135,56 +133,9 @@ update t1 set a =5, b=2;
--eval KILL $k_thread --eval KILL $k_thread
--enable_query_log --enable_query_log
select * from t1; select * from t1;
--disconnect node_2a --disconnect node_2a
--connection node_1
drop table t1; drop table t1;
#
# Test case 7:
# run a transaction in node 2, and set a sync point to pause the transaction
# in commit phase.
# Through another connection to node 2, kill the committing transaction by
# KILL QUERY command
#
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
--connection node_2a
--let $connection_id = `SELECT CONNECTION_ID()`
CREATE TABLE t1 (i int primary key);
# Set up sync point
SET DEBUG_SYNC = "before_wsrep_ordered_commit SIGNAL bwoc_reached WAIT_FOR bwoc_continue";
# Send insert which will block in the sync point above
--send INSERT INTO t1 VALUES (1)
--connection node_2
SET DEBUG_SYNC = "now WAIT_FOR bwoc_reached";
--disable_query_log
--disable_result_log
# victim has passed the point of no return, kill is not possible anymore
--eval KILL QUERY $connection_id
--enable_result_log
--enable_query_log
SET DEBUG_SYNC = "now SIGNAL bwoc_continue";
SET DEBUG_SYNC='RESET';
--connection node_2a
--error 0,1213
--reap
--connection node_2
# victim was able to complete the INSERT
select * from t1;
--disconnect node_2a
--connection node_2
drop table t1;
!include ../galera_2nodes.cnf
[mysqld.1]
wsrep-debug=SERVER
[mysqld.2]
wsrep-debug=SERVER
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
#
# Test case 7:
# 1. Start a transaction on node_2,
# and leave it pending while holding a row locked
# 2. set sync point pause applier
# 3. send a conflicting write on node_1, it will pause
# at the sync point
# 4. though another connection to node_2, kill the local
# transaction
#
--connection node_2
CREATE TABLE t1(a int not null primary key auto_increment,b int) engine=InnoDB;
insert into t1 values (NULL,1);
#
# connection node_2a runs a local transaction, that is victim of BF abort
# and victim of KILL command by connection node_2
#
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
--connection node_2a
truncate t1;
insert into t1 values (1,0);
# start a transaction that will conflict with later applier
begin;
update t1 set b=2 where a=1;
--connection node_2
set session wsrep_sync_wait=0;
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'root' AND COMMAND = 'Sleep' LIMIT 1
--source include/wait_condition.inc
--let $k_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'root' AND COMMAND = 'Sleep' LIMIT 1`
# connection node_2b is for controlling debug syn points
# first set a sync point for applier, to pause during BF aborting
# and before THD::awake would be called
#
--connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2
--connection node_2b
SET GLOBAL debug_dbug = "d,sync.before_wsrep_thd_abort";
#
# replicate an update, which will BF abort the victim node_2a
# however, while applier in node 2 is handling the abort,
# it will pause in sync point set by node_2b
#
--connection node_1
select * from t1;
update t1 set b= 1 where a=1;
#
# wait until the applying of above update has reached the sync point
# in node 2
#
--connection node_2b
SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.before_wsrep_thd_abort_reached";
--connection node_2
#
# pause KILL execution before awake
#
SET DEBUG_SYNC= 'before_awake_no_mutex SIGNAL awake_reached WAIT_FOR continue_kill';
--disable_query_log
--send_eval KILL $k_thread
--enable_query_log
--connection node_2b
SET DEBUG_SYNC='now WAIT_FOR awake_reached';
# release applier and KILL operator
SET GLOBAL debug_dbug = "";
SET DEBUG_SYNC = "now SIGNAL signal.before_wsrep_thd_abort";
SET DEBUG_SYNC = "now SIGNAL continue_kill";
--connection node_2
--reap
--connection node_2a
--error 0,1213
select * from t1;
--connection node_2
SET DEBUG_SYNC = "RESET";
drop table t1;
--disconnect node_2a
#
# Test case 7:
# run a transaction in node 2, and set a sync point to pause the transaction
# in commit phase.
# Through another connection to node 2, kill the committing transaction by
# KILL QUERY command
#
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
--connection node_2a
--let $connection_id = `SELECT CONNECTION_ID()`
CREATE TABLE t1 (i int primary key);
# Set up sync point
SET DEBUG_SYNC = "before_wsrep_ordered_commit SIGNAL bwoc_reached WAIT_FOR bwoc_continue";
# Send insert which will block in the sync point above
--send INSERT INTO t1 VALUES (1)
--connection node_2
SET DEBUG_SYNC = "now WAIT_FOR bwoc_reached";
--disable_query_log
--disable_result_log
# victim has passed the point of no return, kill is not possible anymore
--eval KILL QUERY $connection_id
--enable_result_log
--enable_query_log
SET DEBUG_SYNC = "now SIGNAL bwoc_continue";
SET DEBUG_SYNC='RESET';
--connection node_2a
--error 0,1213
--reap
--connection node_2
# victim was able to complete the INSERT
select * from t1;
--disconnect node_2a
--connection node_1
drop table t1;
...@@ -2,8 +2,10 @@ ...@@ -2,8 +2,10 @@
--source include/have_innodb.inc --source include/have_innodb.inc
--source include/big_test.inc --source include/big_test.inc
--connection node_1 --connection node_2
call mtr.add_suppression("WSREP: Trying to continue unpaused monitor");
--connection node_1
call mtr.add_suppression("WSREP: Trying to continue unpaused monitor"); call mtr.add_suppression("WSREP: Trying to continue unpaused monitor");
CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2; CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2;
......
...@@ -107,152 +107,161 @@ and (end_event_id <= @marker_end) ...@@ -107,152 +107,161 @@ and (end_event_id <= @marker_end)
) all_events ) all_events
order by relative_event_id asc; order by relative_event_id asc;
relative_event_id relative_end_event_id event_name comment nesting_event_type relative_nesting_event_id relative_event_id relative_end_event_id event_name comment nesting_event_type relative_nesting_event_id
0 20 statement/sql/select select "MARKER_BEGIN" as marker NULL NULL 0 21 statement/sql/select select "MARKER_BEGIN" as marker NULL NULL
1 4 stage/sql/Init (stage) STATEMENT 0 1 5 stage/sql/Init (stage) STATEMENT 0
2 2 wait/io/socket/sql/client_connection recv STAGE 1 2 2 wait/io/socket/sql/client_connection recv STAGE 1
3 3 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 1 3 3 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 1
4 4 wait/io/file/sql/query_log write STAGE 1 4 4 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 1
5 5 stage/sql/Checking permissions (stage) STATEMENT 0 5 5 wait/io/file/sql/query_log write STAGE 1
6 6 stage/sql/Opening tables (stage) STATEMENT 0 6 6 stage/sql/Checking permissions (stage) STATEMENT 0
7 7 stage/sql/After opening tables (stage) STATEMENT 0 7 7 stage/sql/Opening tables (stage) STATEMENT 0
8 8 stage/sql/Init (stage) STATEMENT 0 8 8 stage/sql/After opening tables (stage) STATEMENT 0
9 9 stage/sql/Optimizing (stage) STATEMENT 0 9 9 stage/sql/Init (stage) STATEMENT 0
10 10 stage/sql/Executing (stage) STATEMENT 0 10 10 stage/sql/Optimizing (stage) STATEMENT 0
11 11 stage/sql/End of update loop (stage) STATEMENT 0 11 11 stage/sql/Executing (stage) STATEMENT 0
12 12 stage/sql/Query end (stage) STATEMENT 0 12 12 stage/sql/End of update loop (stage) STATEMENT 0
13 13 stage/sql/Commit (stage) STATEMENT 0 13 13 stage/sql/Query end (stage) STATEMENT 0
14 14 stage/sql/Closing tables (stage) STATEMENT 0 14 14 stage/sql/Commit (stage) STATEMENT 0
15 15 stage/sql/Starting cleanup (stage) STATEMENT 0 15 15 stage/sql/Closing tables (stage) STATEMENT 0
16 16 stage/sql/Freeing items (stage) STATEMENT 0 16 16 stage/sql/Starting cleanup (stage) STATEMENT 0
17 17 wait/io/socket/sql/client_connection send STATEMENT 0 17 17 stage/sql/Freeing items (stage) STATEMENT 0
18 18 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 0 18 18 wait/io/socket/sql/client_connection send STATEMENT 0
19 20 stage/sql/Reset for next command (stage) STATEMENT 0 19 19 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 0
20 20 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 19 20 21 stage/sql/Reset for next command (stage) STATEMENT 0
21 21 idle idle NULL NULL 21 21 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 20
22 42 statement/sql/select select "This is simple statement one" as payload NULL NULL 22 22 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 0
23 26 stage/sql/Init (stage) STATEMENT 22 23 23 idle idle NULL NULL
24 24 wait/io/socket/sql/client_connection recv STAGE 23 24 45 statement/sql/select select "This is simple statement one" as payload NULL NULL
25 25 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 23 25 29 stage/sql/Init (stage) STATEMENT 24
26 26 wait/io/file/sql/query_log write STAGE 23 26 26 wait/io/socket/sql/client_connection recv STAGE 25
27 27 stage/sql/Checking permissions (stage) STATEMENT 22 27 27 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 25
28 28 stage/sql/Opening tables (stage) STATEMENT 22 28 28 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 25
29 29 stage/sql/After opening tables (stage) STATEMENT 22 29 29 wait/io/file/sql/query_log write STAGE 25
30 30 stage/sql/Init (stage) STATEMENT 22 30 30 stage/sql/Checking permissions (stage) STATEMENT 24
31 31 stage/sql/Optimizing (stage) STATEMENT 22 31 31 stage/sql/Opening tables (stage) STATEMENT 24
32 32 stage/sql/Executing (stage) STATEMENT 22 32 32 stage/sql/After opening tables (stage) STATEMENT 24
33 33 stage/sql/End of update loop (stage) STATEMENT 22 33 33 stage/sql/Init (stage) STATEMENT 24
34 34 stage/sql/Query end (stage) STATEMENT 22 34 34 stage/sql/Optimizing (stage) STATEMENT 24
35 35 stage/sql/Commit (stage) STATEMENT 22 35 35 stage/sql/Executing (stage) STATEMENT 24
36 36 stage/sql/Closing tables (stage) STATEMENT 22 36 36 stage/sql/End of update loop (stage) STATEMENT 24
37 37 stage/sql/Starting cleanup (stage) STATEMENT 22 37 37 stage/sql/Query end (stage) STATEMENT 24
38 38 stage/sql/Freeing items (stage) STATEMENT 22 38 38 stage/sql/Commit (stage) STATEMENT 24
39 39 wait/io/socket/sql/client_connection send STATEMENT 22 39 39 stage/sql/Closing tables (stage) STATEMENT 24
40 40 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 22 40 40 stage/sql/Starting cleanup (stage) STATEMENT 24
41 42 stage/sql/Reset for next command (stage) STATEMENT 22 41 41 stage/sql/Freeing items (stage) STATEMENT 24
42 42 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 41 42 42 wait/io/socket/sql/client_connection send STATEMENT 24
43 43 idle idle NULL NULL 43 43 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 24
44 64 statement/sql/select select "This is simple statement two" as payload NULL NULL 44 45 stage/sql/Reset for next command (stage) STATEMENT 24
45 48 stage/sql/Init (stage) STATEMENT 44 45 45 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 44
46 46 wait/io/socket/sql/client_connection recv STAGE 45 46 46 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 24
47 47 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 45 47 47 idle idle NULL NULL
48 48 wait/io/file/sql/query_log write STAGE 45 48 69 statement/sql/select select "This is simple statement two" as payload NULL NULL
49 49 stage/sql/Checking permissions (stage) STATEMENT 44 49 53 stage/sql/Init (stage) STATEMENT 48
50 50 stage/sql/Opening tables (stage) STATEMENT 44 50 50 wait/io/socket/sql/client_connection recv STAGE 49
51 51 stage/sql/After opening tables (stage) STATEMENT 44 51 51 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 49
52 52 stage/sql/Init (stage) STATEMENT 44 52 52 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 49
53 53 stage/sql/Optimizing (stage) STATEMENT 44 53 53 wait/io/file/sql/query_log write STAGE 49
54 54 stage/sql/Executing (stage) STATEMENT 44 54 54 stage/sql/Checking permissions (stage) STATEMENT 48
55 55 stage/sql/End of update loop (stage) STATEMENT 44 55 55 stage/sql/Opening tables (stage) STATEMENT 48
56 56 stage/sql/Query end (stage) STATEMENT 44 56 56 stage/sql/After opening tables (stage) STATEMENT 48
57 57 stage/sql/Commit (stage) STATEMENT 44 57 57 stage/sql/Init (stage) STATEMENT 48
58 58 stage/sql/Closing tables (stage) STATEMENT 44 58 58 stage/sql/Optimizing (stage) STATEMENT 48
59 59 stage/sql/Starting cleanup (stage) STATEMENT 44 59 59 stage/sql/Executing (stage) STATEMENT 48
60 60 stage/sql/Freeing items (stage) STATEMENT 44 60 60 stage/sql/End of update loop (stage) STATEMENT 48
61 61 wait/io/socket/sql/client_connection send STATEMENT 44 61 61 stage/sql/Query end (stage) STATEMENT 48
62 62 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 44 62 62 stage/sql/Commit (stage) STATEMENT 48
63 64 stage/sql/Reset for next command (stage) STATEMENT 44 63 63 stage/sql/Closing tables (stage) STATEMENT 48
64 64 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 63 64 64 stage/sql/Starting cleanup (stage) STATEMENT 48
65 65 idle idle NULL NULL 65 65 stage/sql/Freeing items (stage) STATEMENT 48
66 85 statement/sql/select select "This is the first part of a multi query" as payload; 66 66 wait/io/socket/sql/client_connection send STATEMENT 48
67 67 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 48
68 69 stage/sql/Reset for next command (stage) STATEMENT 48
69 69 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 68
70 70 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 48
71 71 idle idle NULL NULL
72 92 statement/sql/select select "This is the first part of a multi query" as payload;
select "And this is the second part of a multi query" as payload; select "And this is the second part of a multi query" as payload;
select "With a third part to make things complete" as payload NULL NULL select "With a third part to make things complete" as payload NULL NULL
67 71 stage/sql/Init (stage) STATEMENT 66 73 78 stage/sql/Init (stage) STATEMENT 72
68 68 wait/io/socket/sql/client_connection recv STAGE 67 74 74 wait/io/socket/sql/client_connection recv STAGE 73
69 69 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 67 75 75 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 73
70 70 wait/io/file/sql/query_log write STAGE 67 76 76 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 73
71 71 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 67 77 77 wait/io/file/sql/query_log write STAGE 73
72 72 stage/sql/Checking permissions (stage) STATEMENT 66 78 78 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 73
73 73 stage/sql/Opening tables (stage) STATEMENT 66 79 79 stage/sql/Checking permissions (stage) STATEMENT 72
74 74 stage/sql/After opening tables (stage) STATEMENT 66 80 80 stage/sql/Opening tables (stage) STATEMENT 72
75 75 stage/sql/Init (stage) STATEMENT 66 81 81 stage/sql/After opening tables (stage) STATEMENT 72
76 76 stage/sql/Optimizing (stage) STATEMENT 66 82 82 stage/sql/Init (stage) STATEMENT 72
77 77 stage/sql/Executing (stage) STATEMENT 66 83 83 stage/sql/Optimizing (stage) STATEMENT 72
78 78 stage/sql/End of update loop (stage) STATEMENT 66 84 84 stage/sql/Executing (stage) STATEMENT 72
79 79 stage/sql/Query end (stage) STATEMENT 66 85 85 stage/sql/End of update loop (stage) STATEMENT 72
80 80 stage/sql/Commit (stage) STATEMENT 66 86 86 stage/sql/Query end (stage) STATEMENT 72
81 81 stage/sql/Closing tables (stage) STATEMENT 66 87 87 stage/sql/Commit (stage) STATEMENT 72
82 82 stage/sql/Starting cleanup (stage) STATEMENT 66 88 88 stage/sql/Closing tables (stage) STATEMENT 72
83 85 stage/sql/Freeing items (stage) STATEMENT 66 89 89 stage/sql/Starting cleanup (stage) STATEMENT 72
84 84 wait/io/socket/sql/client_connection send STAGE 83 90 92 stage/sql/Freeing items (stage) STATEMENT 72
85 85 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 83 91 91 wait/io/socket/sql/client_connection send STAGE 90
86 103 statement/sql/select select "And this is the second part of a multi query" as payload; 92 92 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 90
93 110 statement/sql/select select "And this is the second part of a multi query" as payload;
select "With a third part to make things complete" as payload NULL NULL select "With a third part to make things complete" as payload NULL NULL
87 89 stage/sql/Init (stage) STATEMENT 86 94 96 stage/sql/Init (stage) STATEMENT 93
88 88 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 87 95 95 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 94
89 89 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 87 96 96 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 94
90 90 stage/sql/Checking permissions (stage) STATEMENT 86 97 97 stage/sql/Checking permissions (stage) STATEMENT 93
91 91 stage/sql/Opening tables (stage) STATEMENT 86 98 98 stage/sql/Opening tables (stage) STATEMENT 93
92 92 stage/sql/After opening tables (stage) STATEMENT 86 99 99 stage/sql/After opening tables (stage) STATEMENT 93
93 93 stage/sql/Init (stage) STATEMENT 86 100 100 stage/sql/Init (stage) STATEMENT 93
94 94 stage/sql/Optimizing (stage) STATEMENT 86 101 101 stage/sql/Optimizing (stage) STATEMENT 93
95 95 stage/sql/Executing (stage) STATEMENT 86 102 102 stage/sql/Executing (stage) STATEMENT 93
96 96 stage/sql/End of update loop (stage) STATEMENT 86 103 103 stage/sql/End of update loop (stage) STATEMENT 93
97 97 stage/sql/Query end (stage) STATEMENT 86 104 104 stage/sql/Query end (stage) STATEMENT 93
98 98 stage/sql/Commit (stage) STATEMENT 86 105 105 stage/sql/Commit (stage) STATEMENT 93
99 99 stage/sql/Closing tables (stage) STATEMENT 86 106 106 stage/sql/Closing tables (stage) STATEMENT 93
100 100 stage/sql/Starting cleanup (stage) STATEMENT 86 107 107 stage/sql/Starting cleanup (stage) STATEMENT 93
101 103 stage/sql/Freeing items (stage) STATEMENT 86 108 110 stage/sql/Freeing items (stage) STATEMENT 93
102 102 wait/io/socket/sql/client_connection send STAGE 101 109 109 wait/io/socket/sql/client_connection send STAGE 108
103 103 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 101 110 110 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 108
104 122 statement/sql/select select "With a third part to make things complete" as payload NULL NULL 111 129 statement/sql/select select "With a third part to make things complete" as payload NULL NULL
105 106 stage/sql/Init (stage) STATEMENT 104 112 113 stage/sql/Init (stage) STATEMENT 111
106 106 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 105 113 113 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 112
107 107 stage/sql/Checking permissions (stage) STATEMENT 104 114 114 stage/sql/Checking permissions (stage) STATEMENT 111
108 108 stage/sql/Opening tables (stage) STATEMENT 104 115 115 stage/sql/Opening tables (stage) STATEMENT 111
109 109 stage/sql/After opening tables (stage) STATEMENT 104 116 116 stage/sql/After opening tables (stage) STATEMENT 111
110 110 stage/sql/Init (stage) STATEMENT 104 117 117 stage/sql/Init (stage) STATEMENT 111
111 111 stage/sql/Optimizing (stage) STATEMENT 104 118 118 stage/sql/Optimizing (stage) STATEMENT 111
112 112 stage/sql/Executing (stage) STATEMENT 104 119 119 stage/sql/Executing (stage) STATEMENT 111
113 113 stage/sql/End of update loop (stage) STATEMENT 104 120 120 stage/sql/End of update loop (stage) STATEMENT 111
114 114 stage/sql/Query end (stage) STATEMENT 104 121 121 stage/sql/Query end (stage) STATEMENT 111
115 115 stage/sql/Commit (stage) STATEMENT 104 122 122 stage/sql/Commit (stage) STATEMENT 111
116 116 stage/sql/Closing tables (stage) STATEMENT 104 123 123 stage/sql/Closing tables (stage) STATEMENT 111
117 117 stage/sql/Starting cleanup (stage) STATEMENT 104 124 124 stage/sql/Starting cleanup (stage) STATEMENT 111
118 118 stage/sql/Freeing items (stage) STATEMENT 104 125 125 stage/sql/Freeing items (stage) STATEMENT 111
119 119 wait/io/socket/sql/client_connection send STATEMENT 104 126 126 wait/io/socket/sql/client_connection send STATEMENT 111
120 120 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 104 127 127 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 111
121 122 stage/sql/Reset for next command (stage) STATEMENT 104 128 129 stage/sql/Reset for next command (stage) STATEMENT 111
122 122 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 121 129 129 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 128
123 123 idle idle NULL NULL 130 130 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 111
124 144 statement/sql/select select "MARKER_END" as marker NULL NULL 131 131 idle idle NULL NULL
125 128 stage/sql/Init (stage) STATEMENT 124 132 153 statement/sql/select select "MARKER_END" as marker NULL NULL
126 126 wait/io/socket/sql/client_connection recv STAGE 125 133 137 stage/sql/Init (stage) STATEMENT 132
127 127 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 125 134 134 wait/io/socket/sql/client_connection recv STAGE 133
128 128 wait/io/file/sql/query_log write STAGE 125 135 135 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 133
129 129 stage/sql/Checking permissions (stage) STATEMENT 124 136 136 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 133
130 130 stage/sql/Opening tables (stage) STATEMENT 124 137 137 wait/io/file/sql/query_log write STAGE 133
131 131 stage/sql/After opening tables (stage) STATEMENT 124 138 138 stage/sql/Checking permissions (stage) STATEMENT 132
132 132 stage/sql/Init (stage) STATEMENT 124 139 139 stage/sql/Opening tables (stage) STATEMENT 132
133 133 stage/sql/Optimizing (stage) STATEMENT 124 140 140 stage/sql/After opening tables (stage) STATEMENT 132
134 134 stage/sql/Executing (stage) STATEMENT 124 141 141 stage/sql/Init (stage) STATEMENT 132
135 135 stage/sql/End of update loop (stage) STATEMENT 124 142 142 stage/sql/Optimizing (stage) STATEMENT 132
136 136 stage/sql/Query end (stage) STATEMENT 124 143 143 stage/sql/Executing (stage) STATEMENT 132
137 137 stage/sql/Commit (stage) STATEMENT 124 144 144 stage/sql/End of update loop (stage) STATEMENT 132
138 138 stage/sql/Closing tables (stage) STATEMENT 124 145 145 stage/sql/Query end (stage) STATEMENT 132
139 139 stage/sql/Starting cleanup (stage) STATEMENT 124 146 146 stage/sql/Commit (stage) STATEMENT 132
140 140 stage/sql/Freeing items (stage) STATEMENT 124 147 147 stage/sql/Closing tables (stage) STATEMENT 132
141 141 wait/io/socket/sql/client_connection send STATEMENT 124 148 148 stage/sql/Starting cleanup (stage) STATEMENT 132
142 142 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 124 149 149 stage/sql/Freeing items (stage) STATEMENT 132
143 144 stage/sql/Reset for next command (stage) STATEMENT 124 150 150 wait/io/socket/sql/client_connection send STATEMENT 132
144 144 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 143 151 151 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 132
152 153 stage/sql/Reset for next command (stage) STATEMENT 132
153 153 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 152
disconnect con1; disconnect con1;
...@@ -200,6 +200,16 @@ extern "C" void wsrep_handle_SR_rollback(THD *bf_thd, ...@@ -200,6 +200,16 @@ extern "C" void wsrep_handle_SR_rollback(THD *bf_thd,
extern "C" my_bool wsrep_thd_bf_abort(THD *bf_thd, THD *victim_thd, extern "C" my_bool wsrep_thd_bf_abort(THD *bf_thd, THD *victim_thd,
my_bool signal) my_bool signal)
{ {
DBUG_EXECUTE_IF("sync.before_wsrep_thd_abort",
{
const char act[]=
"now "
"SIGNAL sync.before_wsrep_thd_abort_reached "
"WAIT_FOR signal.before_wsrep_thd_abort";
DBUG_ASSERT(!debug_sync_set_action(bf_thd,
STRING_WITH_LEN(act)));
};);
my_bool ret= wsrep_bf_abort(bf_thd, victim_thd); my_bool ret= wsrep_bf_abort(bf_thd, victim_thd);
/* /*
Send awake signal if victim was BF aborted or does not Send awake signal if victim was BF aborted or does not
...@@ -211,10 +221,22 @@ extern "C" my_bool wsrep_thd_bf_abort(THD *bf_thd, THD *victim_thd, ...@@ -211,10 +221,22 @@ extern "C" my_bool wsrep_thd_bf_abort(THD *bf_thd, THD *victim_thd,
mysql_mutex_assert_not_owner(&victim_thd->LOCK_thd_data); mysql_mutex_assert_not_owner(&victim_thd->LOCK_thd_data);
mysql_mutex_assert_not_owner(&victim_thd->LOCK_thd_kill); mysql_mutex_assert_not_owner(&victim_thd->LOCK_thd_kill);
mysql_mutex_lock(&victim_thd->LOCK_thd_data); mysql_mutex_lock(&victim_thd->LOCK_thd_data);
if (victim_thd->wsrep_aborter && victim_thd->wsrep_aborter != bf_thd->thread_id)
{
WSREP_DEBUG("victim is killed already by %llu, skipping awake",
victim_thd->wsrep_aborter);
mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
return false;
}
mysql_mutex_lock(&victim_thd->LOCK_thd_kill); mysql_mutex_lock(&victim_thd->LOCK_thd_kill);
victim_thd->wsrep_aborter= bf_thd->thread_id;
victim_thd->awake_no_mutex(KILL_QUERY); victim_thd->awake_no_mutex(KILL_QUERY);
mysql_mutex_unlock(&victim_thd->LOCK_thd_kill); mysql_mutex_unlock(&victim_thd->LOCK_thd_kill);
mysql_mutex_unlock(&victim_thd->LOCK_thd_data); mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
} else {
WSREP_DEBUG("wsrep_thd_bf_abort skipped awake");
} }
return ret; return ret;
} }
...@@ -303,3 +325,15 @@ extern "C" void wsrep_commit_ordered(THD *thd) ...@@ -303,3 +325,15 @@ extern "C" void wsrep_commit_ordered(THD *thd)
thd->wsrep_cs().ordered_commit(); thd->wsrep_cs().ordered_commit();
} }
} }
extern "C" bool wsrep_thd_set_wsrep_aborter(THD *bf_thd, THD *victim_thd)
{
WSREP_DEBUG("wsrep_thd_set_wsrep_aborter called");
mysql_mutex_assert_owner(&victim_thd->LOCK_thd_data);
if (victim_thd->wsrep_aborter && victim_thd->wsrep_aborter != bf_thd->thread_id)
{
return true;
}
victim_thd->wsrep_aborter = bf_thd->thread_id;
return false;
}
...@@ -674,6 +674,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) ...@@ -674,6 +674,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
wsrep_has_ignored_error(false), wsrep_has_ignored_error(false),
wsrep_replicate_GTID(false), wsrep_replicate_GTID(false),
wsrep_ignore_table(false), wsrep_ignore_table(false),
wsrep_aborter(0),
/* wsrep-lib */ /* wsrep-lib */
m_wsrep_next_trx_id(WSREP_UNDEFINED_TRX_ID), m_wsrep_next_trx_id(WSREP_UNDEFINED_TRX_ID),
...@@ -1288,6 +1289,7 @@ void THD::init() ...@@ -1288,6 +1289,7 @@ void THD::init()
wsrep_affected_rows = 0; wsrep_affected_rows = 0;
m_wsrep_next_trx_id = WSREP_UNDEFINED_TRX_ID; m_wsrep_next_trx_id = WSREP_UNDEFINED_TRX_ID;
wsrep_replicate_GTID = false; wsrep_replicate_GTID = false;
wsrep_aborter = 0;
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
if (variables.sql_log_bin) if (variables.sql_log_bin)
...@@ -2121,11 +2123,19 @@ void THD::reset_killed() ...@@ -2121,11 +2123,19 @@ void THD::reset_killed()
DBUG_ENTER("reset_killed"); DBUG_ENTER("reset_killed");
if (killed != NOT_KILLED) if (killed != NOT_KILLED)
{ {
mysql_mutex_assert_not_owner(&LOCK_thd_kill);
mysql_mutex_lock(&LOCK_thd_kill); mysql_mutex_lock(&LOCK_thd_kill);
killed= NOT_KILLED; killed= NOT_KILLED;
killed_err= 0; killed_err= 0;
mysql_mutex_unlock(&LOCK_thd_kill); mysql_mutex_unlock(&LOCK_thd_kill);
} }
#ifdef WITH_WSREP
mysql_mutex_assert_not_owner(&LOCK_thd_data);
mysql_mutex_lock(&LOCK_thd_data);
wsrep_aborter= 0;
mysql_mutex_unlock(&LOCK_thd_data);
#endif /* WITH_WSREP */
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -4859,7 +4859,8 @@ class THD: public THD_count, /* this must be first */ ...@@ -4859,7 +4859,8 @@ class THD: public THD_count, /* this must be first */
table updates from being replicated to other nodes via galera replication. table updates from being replicated to other nodes via galera replication.
*/ */
bool wsrep_ignore_table; bool wsrep_ignore_table;
/* thread who has started kill for this THD protected by LOCK_thd_data*/
my_thread_id wsrep_aborter;
/* /*
Transaction id: Transaction id:
......
...@@ -9056,7 +9056,6 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ ...@@ -9056,7 +9056,6 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
uint error= (type == KILL_TYPE_QUERY ? ER_NO_SUCH_QUERY : ER_NO_SUCH_THREAD); uint error= (type == KILL_TYPE_QUERY ? ER_NO_SUCH_QUERY : ER_NO_SUCH_THREAD);
DBUG_ENTER("kill_one_thread"); DBUG_ENTER("kill_one_thread");
DBUG_PRINT("enter", ("id: %lld signal: %u", id, (uint) kill_signal)); DBUG_PRINT("enter", ("id: %lld signal: %u", id, (uint) kill_signal));
WSREP_DEBUG("kill_one_thread %llu", thd->thread_id);
if (id && (tmp= find_thread_by_id(id, type == KILL_TYPE_QUERY))) if (id && (tmp= find_thread_by_id(id, type == KILL_TYPE_QUERY)))
{ {
/* /*
...@@ -9089,12 +9088,29 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ ...@@ -9089,12 +9088,29 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
thd->security_ctx->user_matches(tmp->security_ctx)) thd->security_ctx->user_matches(tmp->security_ctx))
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
{ {
tmp->awake_no_mutex(kill_signal); #ifdef WITH_WSREP
error=0; DEBUG_SYNC(thd, "before_awake_no_mutex");
if (tmp->wsrep_aborter && tmp->wsrep_aborter != thd->thread_id)
{
/* victim is in hit list already, bail out */
WSREP_DEBUG("victim has wsrep aborter: %lu, skipping awake()",
tmp->wsrep_aborter);
error= 0;
}
else
#endif /* WITH_WSREP */
{
WSREP_DEBUG("kill_one_thread %llu, victim: %llu wsrep_aborter %llu by signal %d",
thd->thread_id, id, tmp->wsrep_aborter, kill_signal);
tmp->awake_no_mutex(kill_signal);
WSREP_DEBUG("victim: %llu taken care of", id);
error= 0;
}
} }
else else
error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR : error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR :
ER_KILL_DENIED_ERROR); ER_KILL_DENIED_ERROR);
if (WSREP(tmp)) mysql_mutex_unlock(&tmp->LOCK_thd_data); if (WSREP(tmp)) mysql_mutex_unlock(&tmp->LOCK_thd_data);
mysql_mutex_unlock(&tmp->LOCK_thd_kill); mysql_mutex_unlock(&tmp->LOCK_thd_kill);
} }
......
...@@ -173,7 +173,8 @@ static struct wsrep_service_st wsrep_handler = { ...@@ -173,7 +173,8 @@ static struct wsrep_service_st wsrep_handler = {
wsrep_get_sr_table_name, wsrep_get_sr_table_name,
wsrep_get_debug, wsrep_get_debug,
wsrep_commit_ordered, wsrep_commit_ordered,
wsrep_thd_is_applying wsrep_thd_is_applying,
wsrep_thd_set_wsrep_aborter
}; };
static struct thd_specifics_service_st thd_specifics_handler= static struct thd_specifics_service_st thd_specifics_handler=
......
...@@ -142,3 +142,6 @@ void wsrep_log(void (*)(const char *, ...), const char *, ...) ...@@ -142,3 +142,6 @@ void wsrep_log(void (*)(const char *, ...), const char *, ...)
my_bool wsrep_thd_is_applying(const THD*) my_bool wsrep_thd_is_applying(const THD*)
{ return 0;} { return 0;}
bool wsrep_thd_set_wsrep_aborter(THD*, THD*)
{ return 0;}
...@@ -18705,10 +18705,17 @@ wsrep_innobase_kill_one_trx( ...@@ -18705,10 +18705,17 @@ wsrep_innobase_kill_one_trx(
/* Mark transaction as a victim for Galera abort */ /* Mark transaction as a victim for Galera abort */
victim_trx->lock.was_chosen_as_wsrep_victim= true; victim_trx->lock.was_chosen_as_wsrep_victim= true;
if (wsrep_thd_set_wsrep_aborter(bf_thd, thd))
{
WSREP_DEBUG("innodb kill transaction skipped due to wsrep_aborter set");
wsrep_thd_UNLOCK(thd);
DBUG_RETURN(0);
}
/* Note that we need to release this as it will be acquired /* Note that we need to release this as it will be acquired
below in wsrep-lib */ below in wsrep-lib */
wsrep_thd_UNLOCK(thd); wsrep_thd_UNLOCK(thd);
DEBUG_SYNC(bf_thd, "before_wsrep_thd_abort");
if (wsrep_thd_bf_abort(bf_thd, thd, signal)) if (wsrep_thd_bf_abort(bf_thd, thd, signal))
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment