summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Goryavsky <julius.goryavsky@mariadb.com>2020-07-16 13:03:29 +0200
committerJulius Goryavsky <julius.goryavsky@mariadb.com>2020-07-16 13:03:29 +0200
commit956f21c3b0beba89835e8d24fde4b67b589ab142 (patch)
tree6dda80b8519606c47b75f37d2a2d9e496bd0b3a5
parent3280edda8968a899f8f2b891059c4cfaff391c9b (diff)
parent6a1713ac17a882e0d5a44fa68edd47c064220975 (diff)
downloadmariadb-git-956f21c3b0beba89835e8d24fde4b67b589ab142.tar.gz
Merge remote-tracking branch 'origin/bb-10.4-MDEV-21910' into 10.4
-rw-r--r--include/mysql/service_wsrep.h5
-rw-r--r--mysql-test/suite/galera/r/galera_bf_kill.result18
-rw-r--r--mysql-test/suite/galera/r/galera_bf_kill_debug.result54
-rw-r--r--mysql-test/suite/galera/r/galera_bf_lock_wait.result2
-rw-r--r--mysql-test/suite/galera/t/galera_bf_kill.test51
-rw-r--r--mysql-test/suite/galera/t/galera_bf_kill_debug.cnf7
-rw-r--r--mysql-test/suite/galera/t/galera_bf_kill_debug.test140
-rw-r--r--mysql-test/suite/galera/t/galera_bf_lock_wait.test4
-rw-r--r--mysql-test/suite/perfschema/r/nesting.result295
-rw-r--r--sql/service_wsrep.cc34
-rw-r--r--sql/sql_class.cc10
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_parse.cc22
-rw-r--r--sql/sql_plugin_services.ic3
-rw-r--r--sql/wsrep_dummy.cc3
-rw-r--r--storage/innobase/handler/ha_innodb.cc7
16 files changed, 442 insertions, 216 deletions
diff --git a/include/mysql/service_wsrep.h b/include/mysql/service_wsrep.h
index 522eb56fc4e..0a06445de00 100644
--- a/include/mysql/service_wsrep.h
+++ b/include/mysql/service_wsrep.h
@@ -84,6 +84,7 @@ extern struct wsrep_service_st {
my_bool (*wsrep_get_debug_func)();
void (*wsrep_commit_ordered_func)(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;
#define MYSQL_SERVICE_WSREP_INCLUDED
@@ -124,6 +125,7 @@ extern struct wsrep_service_st {
#define wsrep_get_debug() wsrep_service->wsrep_get_debug_func()
#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_set_wsrep_aborter(T) wsrep_service->wsrep_thd_set_wsrep_aborter_func(T1, T2)
#else
@@ -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 */
/* todo: rename to is_high_priority() */
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 */
extern "C" my_bool wsrep_thd_is_toi(const MYSQL_THD thd);
/* Return true if thd is in replicating TOI mode */
@@ -216,6 +220,7 @@ extern "C" my_bool wsrep_get_debug();
extern "C" void wsrep_commit_ordered(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 /* MYSQL_SERVICE_WSREP_INCLUDED */
diff --git a/mysql-test/suite/galera/r/galera_bf_kill.result b/mysql-test/suite/galera/r/galera_bf_kill.result
index 2a7bc9eac29..3738e8c9684 100644
--- a/mysql-test/suite/galera/r/galera_bf_kill.result
+++ b/mysql-test/suite/galera/r/galera_bf_kill.result
@@ -69,21 +69,5 @@ select * from t1;
a b
2 1
disconnect node_2a;
-drop table t1;
-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;
+connection node_1;
drop table t1;
diff --git a/mysql-test/suite/galera/r/galera_bf_kill_debug.result b/mysql-test/suite/galera/r/galera_bf_kill_debug.result
new file mode 100644
index 00000000000..c3eae243f47
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_bf_kill_debug.result
@@ -0,0 +1,54 @@
+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;
diff --git a/mysql-test/suite/galera/r/galera_bf_lock_wait.result b/mysql-test/suite/galera/r/galera_bf_lock_wait.result
index 71627d11a4e..723f3e37282 100644
--- a/mysql-test/suite/galera/r/galera_bf_lock_wait.result
+++ b/mysql-test/suite/galera/r/galera_bf_lock_wait.result
@@ -1,5 +1,7 @@
connection node_2;
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");
CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2;
diff --git a/mysql-test/suite/galera/t/galera_bf_kill.test b/mysql-test/suite/galera/t/galera_bf_kill.test
index 3eb3ddc32b5..c8564bc9219 100644
--- a/mysql-test/suite/galera/t/galera_bf_kill.test
+++ b/mysql-test/suite/galera/t/galera_bf_kill.test
@@ -1,7 +1,5 @@
--source include/galera_cluster.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
@@ -135,56 +133,9 @@ update t1 set a =5, b=2;
--eval KILL $k_thread
--enable_query_log
-
select * from t1;
--disconnect node_2a
+--connection node_1
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;
-
diff --git a/mysql-test/suite/galera/t/galera_bf_kill_debug.cnf b/mysql-test/suite/galera/t/galera_bf_kill_debug.cnf
new file mode 100644
index 00000000000..e68f891792c
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_bf_kill_debug.cnf
@@ -0,0 +1,7 @@
+!include ../galera_2nodes.cnf
+
+[mysqld.1]
+wsrep-debug=SERVER
+
+[mysqld.2]
+wsrep-debug=SERVER
diff --git a/mysql-test/suite/galera/t/galera_bf_kill_debug.test b/mysql-test/suite/galera/t/galera_bf_kill_debug.test
new file mode 100644
index 00000000000..b687a5a6a67
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_bf_kill_debug.test
@@ -0,0 +1,140 @@
+--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;
+
diff --git a/mysql-test/suite/galera/t/galera_bf_lock_wait.test b/mysql-test/suite/galera/t/galera_bf_lock_wait.test
index 97d3b8e0710..a78a94eb1db 100644
--- a/mysql-test/suite/galera/t/galera_bf_lock_wait.test
+++ b/mysql-test/suite/galera/t/galera_bf_lock_wait.test
@@ -2,8 +2,10 @@
--source include/have_innodb.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");
CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2;
diff --git a/mysql-test/suite/perfschema/r/nesting.result b/mysql-test/suite/perfschema/r/nesting.result
index 37681757973..6f0030489f6 100644
--- a/mysql-test/suite/perfschema/r/nesting.result
+++ b/mysql-test/suite/perfschema/r/nesting.result
@@ -107,152 +107,161 @@ and (end_event_id <= @marker_end)
) all_events
order by relative_event_id asc;
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
-1 4 stage/sql/Init (stage) STATEMENT 0
+0 21 statement/sql/select select "MARKER_BEGIN" as marker NULL NULL
+1 5 stage/sql/Init (stage) STATEMENT 0
2 2 wait/io/socket/sql/client_connection recv 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
-5 5 stage/sql/Checking permissions (stage) STATEMENT 0
-6 6 stage/sql/Opening tables (stage) STATEMENT 0
-7 7 stage/sql/After opening tables (stage) STATEMENT 0
-8 8 stage/sql/Init (stage) STATEMENT 0
-9 9 stage/sql/Optimizing (stage) STATEMENT 0
-10 10 stage/sql/Executing (stage) STATEMENT 0
-11 11 stage/sql/End of update loop (stage) STATEMENT 0
-12 12 stage/sql/Query end (stage) STATEMENT 0
-13 13 stage/sql/Commit (stage) STATEMENT 0
-14 14 stage/sql/Closing tables (stage) STATEMENT 0
-15 15 stage/sql/Starting cleanup (stage) STATEMENT 0
-16 16 stage/sql/Freeing items (stage) STATEMENT 0
-17 17 wait/io/socket/sql/client_connection send STATEMENT 0
-18 18 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 0
-19 20 stage/sql/Reset for next command (stage) STATEMENT 0
-20 20 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 19
-21 21 idle idle NULL NULL
-22 42 statement/sql/select select "This is simple statement one" as payload NULL NULL
-23 26 stage/sql/Init (stage) STATEMENT 22
-24 24 wait/io/socket/sql/client_connection recv STAGE 23
-25 25 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 23
-26 26 wait/io/file/sql/query_log write STAGE 23
-27 27 stage/sql/Checking permissions (stage) STATEMENT 22
-28 28 stage/sql/Opening tables (stage) STATEMENT 22
-29 29 stage/sql/After opening tables (stage) STATEMENT 22
-30 30 stage/sql/Init (stage) STATEMENT 22
-31 31 stage/sql/Optimizing (stage) STATEMENT 22
-32 32 stage/sql/Executing (stage) STATEMENT 22
-33 33 stage/sql/End of update loop (stage) STATEMENT 22
-34 34 stage/sql/Query end (stage) STATEMENT 22
-35 35 stage/sql/Commit (stage) STATEMENT 22
-36 36 stage/sql/Closing tables (stage) STATEMENT 22
-37 37 stage/sql/Starting cleanup (stage) STATEMENT 22
-38 38 stage/sql/Freeing items (stage) STATEMENT 22
-39 39 wait/io/socket/sql/client_connection send STATEMENT 22
-40 40 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 22
-41 42 stage/sql/Reset for next command (stage) STATEMENT 22
-42 42 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 41
-43 43 idle idle NULL NULL
-44 64 statement/sql/select select "This is simple statement two" as payload NULL NULL
-45 48 stage/sql/Init (stage) STATEMENT 44
-46 46 wait/io/socket/sql/client_connection recv STAGE 45
-47 47 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 45
-48 48 wait/io/file/sql/query_log write STAGE 45
-49 49 stage/sql/Checking permissions (stage) STATEMENT 44
-50 50 stage/sql/Opening tables (stage) STATEMENT 44
-51 51 stage/sql/After opening tables (stage) STATEMENT 44
-52 52 stage/sql/Init (stage) STATEMENT 44
-53 53 stage/sql/Optimizing (stage) STATEMENT 44
-54 54 stage/sql/Executing (stage) STATEMENT 44
-55 55 stage/sql/End of update loop (stage) STATEMENT 44
-56 56 stage/sql/Query end (stage) STATEMENT 44
-57 57 stage/sql/Commit (stage) STATEMENT 44
-58 58 stage/sql/Closing tables (stage) STATEMENT 44
-59 59 stage/sql/Starting cleanup (stage) STATEMENT 44
-60 60 stage/sql/Freeing items (stage) STATEMENT 44
-61 61 wait/io/socket/sql/client_connection send STATEMENT 44
-62 62 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 44
-63 64 stage/sql/Reset for next command (stage) STATEMENT 44
-64 64 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 63
-65 65 idle idle NULL NULL
-66 85 statement/sql/select select "This is the first part of a multi query" as payload;
+4 4 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 1
+5 5 wait/io/file/sql/query_log write STAGE 1
+6 6 stage/sql/Checking permissions (stage) STATEMENT 0
+7 7 stage/sql/Opening tables (stage) STATEMENT 0
+8 8 stage/sql/After opening tables (stage) STATEMENT 0
+9 9 stage/sql/Init (stage) STATEMENT 0
+10 10 stage/sql/Optimizing (stage) STATEMENT 0
+11 11 stage/sql/Executing (stage) STATEMENT 0
+12 12 stage/sql/End of update loop (stage) STATEMENT 0
+13 13 stage/sql/Query end (stage) STATEMENT 0
+14 14 stage/sql/Commit (stage) STATEMENT 0
+15 15 stage/sql/Closing tables (stage) STATEMENT 0
+16 16 stage/sql/Starting cleanup (stage) STATEMENT 0
+17 17 stage/sql/Freeing items (stage) STATEMENT 0
+18 18 wait/io/socket/sql/client_connection send STATEMENT 0
+19 19 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 0
+20 21 stage/sql/Reset for next command (stage) STATEMENT 0
+21 21 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 20
+22 22 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 0
+23 23 idle idle NULL NULL
+24 45 statement/sql/select select "This is simple statement one" as payload NULL NULL
+25 29 stage/sql/Init (stage) STATEMENT 24
+26 26 wait/io/socket/sql/client_connection recv STAGE 25
+27 27 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 25
+28 28 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 25
+29 29 wait/io/file/sql/query_log write STAGE 25
+30 30 stage/sql/Checking permissions (stage) STATEMENT 24
+31 31 stage/sql/Opening tables (stage) STATEMENT 24
+32 32 stage/sql/After opening tables (stage) STATEMENT 24
+33 33 stage/sql/Init (stage) STATEMENT 24
+34 34 stage/sql/Optimizing (stage) STATEMENT 24
+35 35 stage/sql/Executing (stage) STATEMENT 24
+36 36 stage/sql/End of update loop (stage) STATEMENT 24
+37 37 stage/sql/Query end (stage) STATEMENT 24
+38 38 stage/sql/Commit (stage) STATEMENT 24
+39 39 stage/sql/Closing tables (stage) STATEMENT 24
+40 40 stage/sql/Starting cleanup (stage) STATEMENT 24
+41 41 stage/sql/Freeing items (stage) STATEMENT 24
+42 42 wait/io/socket/sql/client_connection send STATEMENT 24
+43 43 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 24
+44 45 stage/sql/Reset for next command (stage) STATEMENT 24
+45 45 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 44
+46 46 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 24
+47 47 idle idle NULL NULL
+48 69 statement/sql/select select "This is simple statement two" as payload NULL NULL
+49 53 stage/sql/Init (stage) STATEMENT 48
+50 50 wait/io/socket/sql/client_connection recv STAGE 49
+51 51 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 49
+52 52 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 49
+53 53 wait/io/file/sql/query_log write STAGE 49
+54 54 stage/sql/Checking permissions (stage) STATEMENT 48
+55 55 stage/sql/Opening tables (stage) STATEMENT 48
+56 56 stage/sql/After opening tables (stage) STATEMENT 48
+57 57 stage/sql/Init (stage) STATEMENT 48
+58 58 stage/sql/Optimizing (stage) STATEMENT 48
+59 59 stage/sql/Executing (stage) STATEMENT 48
+60 60 stage/sql/End of update loop (stage) STATEMENT 48
+61 61 stage/sql/Query end (stage) STATEMENT 48
+62 62 stage/sql/Commit (stage) STATEMENT 48
+63 63 stage/sql/Closing tables (stage) STATEMENT 48
+64 64 stage/sql/Starting cleanup (stage) STATEMENT 48
+65 65 stage/sql/Freeing items (stage) STATEMENT 48
+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 "With a third part to make things complete" as payload NULL NULL
-67 71 stage/sql/Init (stage) STATEMENT 66
-68 68 wait/io/socket/sql/client_connection recv STAGE 67
-69 69 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 67
-70 70 wait/io/file/sql/query_log write STAGE 67
-71 71 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 67
-72 72 stage/sql/Checking permissions (stage) STATEMENT 66
-73 73 stage/sql/Opening tables (stage) STATEMENT 66
-74 74 stage/sql/After opening tables (stage) STATEMENT 66
-75 75 stage/sql/Init (stage) STATEMENT 66
-76 76 stage/sql/Optimizing (stage) STATEMENT 66
-77 77 stage/sql/Executing (stage) STATEMENT 66
-78 78 stage/sql/End of update loop (stage) STATEMENT 66
-79 79 stage/sql/Query end (stage) STATEMENT 66
-80 80 stage/sql/Commit (stage) STATEMENT 66
-81 81 stage/sql/Closing tables (stage) STATEMENT 66
-82 82 stage/sql/Starting cleanup (stage) STATEMENT 66
-83 85 stage/sql/Freeing items (stage) STATEMENT 66
-84 84 wait/io/socket/sql/client_connection send STAGE 83
-85 85 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 83
-86 103 statement/sql/select select "And this is the second part of a multi query" as payload;
+73 78 stage/sql/Init (stage) STATEMENT 72
+74 74 wait/io/socket/sql/client_connection recv STAGE 73
+75 75 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 73
+76 76 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 73
+77 77 wait/io/file/sql/query_log write STAGE 73
+78 78 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 73
+79 79 stage/sql/Checking permissions (stage) STATEMENT 72
+80 80 stage/sql/Opening tables (stage) STATEMENT 72
+81 81 stage/sql/After opening tables (stage) STATEMENT 72
+82 82 stage/sql/Init (stage) STATEMENT 72
+83 83 stage/sql/Optimizing (stage) STATEMENT 72
+84 84 stage/sql/Executing (stage) STATEMENT 72
+85 85 stage/sql/End of update loop (stage) STATEMENT 72
+86 86 stage/sql/Query end (stage) STATEMENT 72
+87 87 stage/sql/Commit (stage) STATEMENT 72
+88 88 stage/sql/Closing tables (stage) STATEMENT 72
+89 89 stage/sql/Starting cleanup (stage) STATEMENT 72
+90 92 stage/sql/Freeing items (stage) STATEMENT 72
+91 91 wait/io/socket/sql/client_connection send STAGE 90
+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
-87 89 stage/sql/Init (stage) STATEMENT 86
-88 88 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 87
-89 89 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 87
-90 90 stage/sql/Checking permissions (stage) STATEMENT 86
-91 91 stage/sql/Opening tables (stage) STATEMENT 86
-92 92 stage/sql/After opening tables (stage) STATEMENT 86
-93 93 stage/sql/Init (stage) STATEMENT 86
-94 94 stage/sql/Optimizing (stage) STATEMENT 86
-95 95 stage/sql/Executing (stage) STATEMENT 86
-96 96 stage/sql/End of update loop (stage) STATEMENT 86
-97 97 stage/sql/Query end (stage) STATEMENT 86
-98 98 stage/sql/Commit (stage) STATEMENT 86
-99 99 stage/sql/Closing tables (stage) STATEMENT 86
-100 100 stage/sql/Starting cleanup (stage) STATEMENT 86
-101 103 stage/sql/Freeing items (stage) STATEMENT 86
-102 102 wait/io/socket/sql/client_connection send STAGE 101
-103 103 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 101
-104 122 statement/sql/select select "With a third part to make things complete" as payload NULL NULL
-105 106 stage/sql/Init (stage) STATEMENT 104
-106 106 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 105
-107 107 stage/sql/Checking permissions (stage) STATEMENT 104
-108 108 stage/sql/Opening tables (stage) STATEMENT 104
-109 109 stage/sql/After opening tables (stage) STATEMENT 104
-110 110 stage/sql/Init (stage) STATEMENT 104
-111 111 stage/sql/Optimizing (stage) STATEMENT 104
-112 112 stage/sql/Executing (stage) STATEMENT 104
-113 113 stage/sql/End of update loop (stage) STATEMENT 104
-114 114 stage/sql/Query end (stage) STATEMENT 104
-115 115 stage/sql/Commit (stage) STATEMENT 104
-116 116 stage/sql/Closing tables (stage) STATEMENT 104
-117 117 stage/sql/Starting cleanup (stage) STATEMENT 104
-118 118 stage/sql/Freeing items (stage) STATEMENT 104
-119 119 wait/io/socket/sql/client_connection send STATEMENT 104
-120 120 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 104
-121 122 stage/sql/Reset for next command (stage) STATEMENT 104
-122 122 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 121
-123 123 idle idle NULL NULL
-124 144 statement/sql/select select "MARKER_END" as marker NULL NULL
-125 128 stage/sql/Init (stage) STATEMENT 124
-126 126 wait/io/socket/sql/client_connection recv STAGE 125
-127 127 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 125
-128 128 wait/io/file/sql/query_log write STAGE 125
-129 129 stage/sql/Checking permissions (stage) STATEMENT 124
-130 130 stage/sql/Opening tables (stage) STATEMENT 124
-131 131 stage/sql/After opening tables (stage) STATEMENT 124
-132 132 stage/sql/Init (stage) STATEMENT 124
-133 133 stage/sql/Optimizing (stage) STATEMENT 124
-134 134 stage/sql/Executing (stage) STATEMENT 124
-135 135 stage/sql/End of update loop (stage) STATEMENT 124
-136 136 stage/sql/Query end (stage) STATEMENT 124
-137 137 stage/sql/Commit (stage) STATEMENT 124
-138 138 stage/sql/Closing tables (stage) STATEMENT 124
-139 139 stage/sql/Starting cleanup (stage) STATEMENT 124
-140 140 stage/sql/Freeing items (stage) STATEMENT 124
-141 141 wait/io/socket/sql/client_connection send STATEMENT 124
-142 142 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 124
-143 144 stage/sql/Reset for next command (stage) STATEMENT 124
-144 144 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 143
+94 96 stage/sql/Init (stage) STATEMENT 93
+95 95 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 94
+96 96 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 94
+97 97 stage/sql/Checking permissions (stage) STATEMENT 93
+98 98 stage/sql/Opening tables (stage) STATEMENT 93
+99 99 stage/sql/After opening tables (stage) STATEMENT 93
+100 100 stage/sql/Init (stage) STATEMENT 93
+101 101 stage/sql/Optimizing (stage) STATEMENT 93
+102 102 stage/sql/Executing (stage) STATEMENT 93
+103 103 stage/sql/End of update loop (stage) STATEMENT 93
+104 104 stage/sql/Query end (stage) STATEMENT 93
+105 105 stage/sql/Commit (stage) STATEMENT 93
+106 106 stage/sql/Closing tables (stage) STATEMENT 93
+107 107 stage/sql/Starting cleanup (stage) STATEMENT 93
+108 110 stage/sql/Freeing items (stage) STATEMENT 93
+109 109 wait/io/socket/sql/client_connection send STAGE 108
+110 110 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 108
+111 129 statement/sql/select select "With a third part to make things complete" as payload NULL NULL
+112 113 stage/sql/Init (stage) STATEMENT 111
+113 113 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 112
+114 114 stage/sql/Checking permissions (stage) STATEMENT 111
+115 115 stage/sql/Opening tables (stage) STATEMENT 111
+116 116 stage/sql/After opening tables (stage) STATEMENT 111
+117 117 stage/sql/Init (stage) STATEMENT 111
+118 118 stage/sql/Optimizing (stage) STATEMENT 111
+119 119 stage/sql/Executing (stage) STATEMENT 111
+120 120 stage/sql/End of update loop (stage) STATEMENT 111
+121 121 stage/sql/Query end (stage) STATEMENT 111
+122 122 stage/sql/Commit (stage) STATEMENT 111
+123 123 stage/sql/Closing tables (stage) STATEMENT 111
+124 124 stage/sql/Starting cleanup (stage) STATEMENT 111
+125 125 stage/sql/Freeing items (stage) STATEMENT 111
+126 126 wait/io/socket/sql/client_connection send STATEMENT 111
+127 127 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STATEMENT 111
+128 129 stage/sql/Reset for next command (stage) STATEMENT 111
+129 129 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 128
+130 130 wait/synch/mutex/sql/THD::LOCK_thd_data lock STATEMENT 111
+131 131 idle idle NULL NULL
+132 153 statement/sql/select select "MARKER_END" as marker NULL NULL
+133 137 stage/sql/Init (stage) STATEMENT 132
+134 134 wait/io/socket/sql/client_connection recv STAGE 133
+135 135 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 133
+136 136 wait/synch/mutex/sql/THD::LOCK_thd_data lock STAGE 133
+137 137 wait/io/file/sql/query_log write STAGE 133
+138 138 stage/sql/Checking permissions (stage) STATEMENT 132
+139 139 stage/sql/Opening tables (stage) STATEMENT 132
+140 140 stage/sql/After opening tables (stage) STATEMENT 132
+141 141 stage/sql/Init (stage) STATEMENT 132
+142 142 stage/sql/Optimizing (stage) STATEMENT 132
+143 143 stage/sql/Executing (stage) STATEMENT 132
+144 144 stage/sql/End of update loop (stage) STATEMENT 132
+145 145 stage/sql/Query end (stage) STATEMENT 132
+146 146 stage/sql/Commit (stage) STATEMENT 132
+147 147 stage/sql/Closing tables (stage) STATEMENT 132
+148 148 stage/sql/Starting cleanup (stage) STATEMENT 132
+149 149 stage/sql/Freeing items (stage) STATEMENT 132
+150 150 wait/io/socket/sql/client_connection send STATEMENT 132
+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;
diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc
index ada0bde803f..889f3630cc3 100644
--- a/sql/service_wsrep.cc
+++ b/sql/service_wsrep.cc
@@ -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,
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);
/*
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,
mysql_mutex_assert_not_owner(&victim_thd->LOCK_thd_data);
mysql_mutex_assert_not_owner(&victim_thd->LOCK_thd_kill);
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);
+ victim_thd->wsrep_aborter= bf_thd->thread_id;
victim_thd->awake_no_mutex(KILL_QUERY);
mysql_mutex_unlock(&victim_thd->LOCK_thd_kill);
mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
+ } else {
+ WSREP_DEBUG("wsrep_thd_bf_abort skipped awake");
}
return ret;
}
@@ -303,3 +325,15 @@ extern "C" void wsrep_commit_ordered(THD *thd)
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;
+}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index fbe73072863..40e606425c5 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -674,6 +674,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
wsrep_has_ignored_error(false),
wsrep_replicate_GTID(false),
wsrep_ignore_table(false),
+ wsrep_aborter(0),
/* wsrep-lib */
m_wsrep_next_trx_id(WSREP_UNDEFINED_TRX_ID),
@@ -1288,6 +1289,7 @@ void THD::init()
wsrep_affected_rows = 0;
m_wsrep_next_trx_id = WSREP_UNDEFINED_TRX_ID;
wsrep_replicate_GTID = false;
+ wsrep_aborter = 0;
#endif /* WITH_WSREP */
if (variables.sql_log_bin)
@@ -2121,11 +2123,19 @@ void THD::reset_killed()
DBUG_ENTER("reset_killed");
if (killed != NOT_KILLED)
{
+ mysql_mutex_assert_not_owner(&LOCK_thd_kill);
mysql_mutex_lock(&LOCK_thd_kill);
killed= NOT_KILLED;
killed_err= 0;
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;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 02ecb87038c..ad7631a66bb 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4859,7 +4859,8 @@ public:
table updates from being replicated to other nodes via galera replication.
*/
bool wsrep_ignore_table;
-
+ /* thread who has started kill for this THD protected by LOCK_thd_data*/
+ my_thread_id wsrep_aborter;
/*
Transaction id:
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index e5f5b7ff812..935e054e163 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -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);
DBUG_ENTER("kill_one_thread");
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)))
{
/*
@@ -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))
#endif /* WITH_WSREP */
{
- tmp->awake_no_mutex(kill_signal);
- error=0;
+#ifdef WITH_WSREP
+ 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
error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR :
ER_KILL_DENIED_ERROR);
+
if (WSREP(tmp)) mysql_mutex_unlock(&tmp->LOCK_thd_data);
mysql_mutex_unlock(&tmp->LOCK_thd_kill);
}
diff --git a/sql/sql_plugin_services.ic b/sql/sql_plugin_services.ic
index c7ecfcd482e..42fc0600807 100644
--- a/sql/sql_plugin_services.ic
+++ b/sql/sql_plugin_services.ic
@@ -173,7 +173,8 @@ static struct wsrep_service_st wsrep_handler = {
wsrep_get_sr_table_name,
wsrep_get_debug,
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=
diff --git a/sql/wsrep_dummy.cc b/sql/wsrep_dummy.cc
index 8e2b09cfe55..11fd90091f6 100644
--- a/sql/wsrep_dummy.cc
+++ b/sql/wsrep_dummy.cc
@@ -142,3 +142,6 @@ void wsrep_log(void (*)(const char *, ...), const char *, ...)
my_bool wsrep_thd_is_applying(const THD*)
{ return 0;}
+
+bool wsrep_thd_set_wsrep_aborter(THD*, THD*)
+{ return 0;}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 6056a863f8b..f85ee3f26fb 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -18705,10 +18705,17 @@ wsrep_innobase_kill_one_trx(
/* Mark transaction as a victim for Galera abort */
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
below in wsrep-lib */
wsrep_thd_UNLOCK(thd);
+ DEBUG_SYNC(bf_thd, "before_wsrep_thd_abort");
if (wsrep_thd_bf_abort(bf_thd, thd, signal))
{