mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
Revert MDEV-25114
Revert88a4be75a5
and9d97f92feb
, which had been prematurely pushed by accident.
This commit is contained in:
parent
cfe1a258e8
commit
f59f5c4a10
18 changed files with 229 additions and 765 deletions
|
@ -68,9 +68,6 @@ f1 f2 f3
|
|||
10 10 0
|
||||
INSERT INTO t1 VALUES (7,7,7);
|
||||
INSERT INTO t1 VALUES (8,8,8);
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
7
|
||||
SELECT * FROM t1;
|
||||
f1 f2 f3
|
||||
1 1 0
|
||||
|
@ -81,9 +78,6 @@ f1 f2 f3
|
|||
8 8 8
|
||||
10 10 0
|
||||
connection node_1;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
7
|
||||
SELECT * FROM t1;
|
||||
f1 f2 f3
|
||||
1 1 0
|
||||
|
@ -91,6 +85,5 @@ f1 f2 f3
|
|||
4 4 2
|
||||
5 5 2
|
||||
7 7 7
|
||||
8 8 8
|
||||
10 10 0
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -1,163 +0,0 @@
|
|||
#
|
||||
# Case 1: We execute bf kill to wsrep_innobase_kill_one_trx
|
||||
# function just before wsrep_thd_LOCK(thd) call. Then we
|
||||
# try to kill victim transaction by KILL QUERY
|
||||
#
|
||||
CREATE TABLE t1(id int not null primary key, b int) engine=innodb;
|
||||
INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
|
||||
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
begin;
|
||||
update t1 set b = b * 10 where id between 2 and 4;
|
||||
connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
SET DEBUG_SYNC='wsrep_before_BF_victim_lock SIGNAL bf_kill WAIT_FOR bf_continue';
|
||||
ALTER TABLE t1 ADD UNIQUE KEY b1(b);;
|
||||
connection node_1;
|
||||
SET DEBUG_SYNC='now WAIT_FOR bf_kill';
|
||||
connection node_1b;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`id` int(11) NOT NULL,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `b1` (`b`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
id b
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
4 4
|
||||
5 5
|
||||
connection node_1;
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
DROP TABLE t1;
|
||||
disconnect node_1a;
|
||||
disconnect node_1b;
|
||||
disconnect node_1c;
|
||||
#
|
||||
# Case 2: We execute bf kill to wsrep_innobase_kill_one_trx
|
||||
# function just after wsrep_thd_LOCK(thd) call. Then we
|
||||
# try to kill victim transaction by KILL QUERY
|
||||
#
|
||||
CREATE TABLE t1(id int not null primary key, b int) engine=innodb;
|
||||
INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
|
||||
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
begin;
|
||||
update t1 set b = b * 10 where id between 2 and 4;
|
||||
connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
SET DEBUG_SYNC='wsrep_after_BF_victim_lock SIGNAL bf_kill WAIT_FOR bf_continue';
|
||||
ALTER TABLE t1 ADD UNIQUE KEY b1(b);;
|
||||
connection node_1;
|
||||
SET DEBUG_SYNC='now WAIT_FOR bf_kill';
|
||||
connection node_1b;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`id` int(11) NOT NULL,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `b1` (`b`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
id b
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
4 4
|
||||
5 5
|
||||
connection node_1;
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
DROP TABLE t1;
|
||||
disconnect node_1a;
|
||||
disconnect node_1b;
|
||||
disconnect node_1c;
|
||||
#
|
||||
# Case 3: Create victim transaction and try to send user KILL
|
||||
# from several threads
|
||||
#
|
||||
CREATE TABLE t1(id int not null primary key, b int) engine=innodb;
|
||||
INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
|
||||
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
begin;
|
||||
update t1 set b = b * 10 where id between 2 and 4;
|
||||
connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connect node_1d, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connection node_1b;
|
||||
connection node_1c;
|
||||
connection node_1d;
|
||||
connection node_1;
|
||||
disconnect node_1a;
|
||||
disconnect node_1b;
|
||||
disconnect node_1c;
|
||||
disconnect node_1d;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Case 4: MDL-conflict, we execute ALTER until we hit gap in
|
||||
# wsrep_abort_transaction, while we are there we try to
|
||||
# manually KILL conflicting transaction (UPDATE) and
|
||||
# send conflicting transaction from other node to be executed
|
||||
# in this node by applier. As ALTER and KILL are TOI they
|
||||
# are not executed concurrently. Similarly UPDATE from other
|
||||
# node will wait for certification.
|
||||
#
|
||||
CREATE TABLE t1(id int not null primary key, b int) engine=innodb;
|
||||
INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
|
||||
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
begin;
|
||||
update t1 set b = b * 10 where id between 2 and 4;
|
||||
connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
SET DEBUG_SYNC='wsrep_abort_victim_unlocked SIGNAL bf_kill_unlocked WAIT_FOR bf_continue';
|
||||
ALTER TABLE t1 ADD UNIQUE KEY b1(b);;
|
||||
connection node_1;
|
||||
SET DEBUG_SYNC='now WAIT_FOR bf_kill_unlocked';
|
||||
connection node_1b;
|
||||
connection node_2;
|
||||
update t1 set b = b + 1000 where id between 2 and 4;;
|
||||
connection node_1;
|
||||
SET DEBUG_SYNC='now SIGNAL bf_continue';
|
||||
connection node_1c;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`id` int(11) NOT NULL,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `b1` (`b`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
SELECT * FROM t1;
|
||||
id b
|
||||
1 1
|
||||
5 5
|
||||
2 1002
|
||||
3 1003
|
||||
4 1004
|
||||
connection node_1b;
|
||||
connection node_1;
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
SELECT * FROM t1;
|
||||
id b
|
||||
1 1
|
||||
5 5
|
||||
2 1002
|
||||
3 1003
|
||||
4 1004
|
||||
connection node_2;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`id` int(11) NOT NULL,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `b1` (`b`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
SELECT * FROM t1;
|
||||
id b
|
||||
1 1
|
||||
5 5
|
||||
2 1002
|
||||
3 1003
|
||||
4 1004
|
||||
DROP TABLE t1;
|
||||
disconnect node_1a;
|
||||
disconnect node_1c;
|
|
@ -21,6 +21,22 @@ connection node_1a;
|
|||
connection node_1b;
|
||||
connection node_2;
|
||||
connection node_2a;
|
||||
connection node_1;
|
||||
SET SESSION wsrep_sync_wait=15;
|
||||
SELECT COUNT(*) FROM parent;
|
||||
COUNT(*)
|
||||
20001
|
||||
SELECT COUNT(*) FROM child;
|
||||
COUNT(*)
|
||||
10000
|
||||
connection node_2;
|
||||
SET SESSION wsrep_sync_wait=15;
|
||||
SELECT COUNT(*) FROM parent;
|
||||
COUNT(*)
|
||||
20001
|
||||
SELECT COUNT(*) FROM child;
|
||||
COUNT(*)
|
||||
10000
|
||||
DROP TABLE child;
|
||||
DROP TABLE parent;
|
||||
DROP TABLE ten;
|
||||
|
|
|
@ -140,13 +140,9 @@ SELECT * FROM t1;
|
|||
# original state in node 1
|
||||
INSERT INTO t1 VALUES (7,7,7);
|
||||
INSERT INTO t1 VALUES (8,8,8);
|
||||
SELECT COUNT(*) FROM t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
--connection node_1
|
||||
--let $wait_condition = SELECT COUNT(*) = 7 FROM t1
|
||||
--source include/wait_condition.inc
|
||||
SELECT COUNT(*) FROM t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
!include ../galera_2nodes.cnf
|
||||
|
||||
[mysqld.1]
|
||||
wsrep_log_conflicts=ON
|
||||
wsrep_debug=1
|
||||
|
||||
[mysqld.2]
|
||||
wsrep_log_conflicts=ON
|
||||
wsrep_debug=1
|
|
@ -1,283 +0,0 @@
|
|||
--source include/galera_cluster.inc
|
||||
--source include/have_debug.inc
|
||||
--source include/have_debug_sync.inc
|
||||
|
||||
--echo #
|
||||
--echo # Case 1: We execute bf kill to wsrep_innobase_kill_one_trx
|
||||
--echo # function just before wsrep_thd_LOCK(thd) call. Then we
|
||||
--echo # try to kill victim transaction by KILL QUERY
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1(id int not null primary key, b int) engine=innodb;
|
||||
INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
|
||||
|
||||
#
|
||||
# This will be victim transaction for both bf kill and
|
||||
# user KILL
|
||||
#
|
||||
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
begin;
|
||||
update t1 set b = b * 10 where id between 2 and 4;
|
||||
|
||||
#
|
||||
# Take thread id for above query
|
||||
#
|
||||
--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
--let $k_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'root' AND COMMAND = 'Sleep' LIMIT 1`
|
||||
|
||||
#
|
||||
# Set DEBUG_SYNC and send conflicting DDL that will be TOI (bf) and
|
||||
# cause bf_kill
|
||||
#
|
||||
--connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
SET DEBUG_SYNC='wsrep_before_BF_victim_lock SIGNAL bf_kill WAIT_FOR bf_continue';
|
||||
--send ALTER TABLE t1 ADD UNIQUE KEY b1(b);
|
||||
|
||||
#
|
||||
# Wait until we have reached the sync point
|
||||
#
|
||||
--connection node_1
|
||||
SET DEBUG_SYNC='now WAIT_FOR bf_kill';
|
||||
|
||||
#
|
||||
# Try to kill update query
|
||||
#
|
||||
--connection node_1b
|
||||
--disable_query_log
|
||||
--send_eval KILL QUERY $k_thread;
|
||||
|
||||
|
||||
#
|
||||
# Let bf_kill continue
|
||||
#
|
||||
--connection node_1
|
||||
SET DEBUG_SYNC='now SIGNAL bf_continue';
|
||||
--connection node_1c
|
||||
--reap
|
||||
SHOW CREATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
--connection node_1b
|
||||
--reap
|
||||
--enable_query_log
|
||||
|
||||
--connection node_1
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
DROP TABLE t1;
|
||||
|
||||
--disconnect node_1a
|
||||
--disconnect node_1b
|
||||
--disconnect node_1c
|
||||
|
||||
--echo #
|
||||
--echo # Case 2: We execute bf kill to wsrep_innobase_kill_one_trx
|
||||
--echo # function just after wsrep_thd_LOCK(thd) call. Then we
|
||||
--echo # try to kill victim transaction by KILL QUERY
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1(id int not null primary key, b int) engine=innodb;
|
||||
INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
|
||||
|
||||
#
|
||||
# This will be victim transaction for both bf kill and
|
||||
# user KILL
|
||||
#
|
||||
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
begin;
|
||||
update t1 set b = b * 10 where id between 2 and 4;
|
||||
|
||||
#
|
||||
# Take thread id for above query
|
||||
#
|
||||
--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
--let $k_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'root' AND COMMAND = 'Sleep' LIMIT 1`
|
||||
|
||||
#
|
||||
# Set DEBUG_SYNC and send conflicting DDL that will be TOI (bf) and
|
||||
# cause bf_kill
|
||||
#
|
||||
--connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
SET DEBUG_SYNC='wsrep_after_BF_victim_lock SIGNAL bf_kill WAIT_FOR bf_continue';
|
||||
--send ALTER TABLE t1 ADD UNIQUE KEY b1(b);
|
||||
|
||||
#
|
||||
# Wait until we have reached the sync point
|
||||
#
|
||||
--connection node_1
|
||||
SET DEBUG_SYNC='now WAIT_FOR bf_kill';
|
||||
|
||||
#
|
||||
# Try to kill update query
|
||||
#
|
||||
--connection node_1b
|
||||
--disable_query_log
|
||||
--send_eval KILL QUERY $k_thread;
|
||||
|
||||
#
|
||||
# Let bf_kill continue
|
||||
#
|
||||
--connection node_1
|
||||
SET DEBUG_SYNC='now SIGNAL bf_continue';
|
||||
--connection node_1c
|
||||
--reap
|
||||
SHOW CREATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
--connection node_1b
|
||||
--reap
|
||||
--enable_query_log
|
||||
|
||||
--connection node_1
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
DROP TABLE t1;
|
||||
|
||||
--disconnect node_1a
|
||||
--disconnect node_1b
|
||||
--disconnect node_1c
|
||||
|
||||
--echo #
|
||||
--echo # Case 3: Create victim transaction and try to send user KILL
|
||||
--echo # from several threads
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1(id int not null primary key, b int) engine=innodb;
|
||||
INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
|
||||
|
||||
#
|
||||
# This will be victim transaction for user KILL
|
||||
#
|
||||
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
begin;
|
||||
update t1 set b = b * 10 where id between 2 and 4;
|
||||
|
||||
#
|
||||
# Take thread id for above query
|
||||
#
|
||||
--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
--connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
--connect node_1d, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
|
||||
--connection node_1b
|
||||
--let $k_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'root' AND COMMAND = 'Sleep' LIMIT 1`
|
||||
|
||||
#
|
||||
# Try to kill update query from several connections concurrently
|
||||
#
|
||||
--disable_query_log
|
||||
--send_eval KILL QUERY $k_thread;
|
||||
|
||||
--connection node_1c
|
||||
--disable_query_log
|
||||
--send_eval KILL QUERY $k_thread;
|
||||
|
||||
--connection node_1d
|
||||
--disable_query_log
|
||||
--send_eval KILL QUERY $k_thread;
|
||||
|
||||
#
|
||||
# We do not know execution order so any of these could fail as KILL
|
||||
# has been already done
|
||||
#
|
||||
--connection node_1b
|
||||
--enable_query_log
|
||||
--error 0,ER_KILL_DENIED_ERROR
|
||||
--reap
|
||||
--connection node_1c
|
||||
--enable_query_log
|
||||
--error 0,ER_KILL_DENIED_ERROR
|
||||
--reap
|
||||
--connection node_1d
|
||||
--enable_query_log
|
||||
--error 0,ER_KILL_DENIED_ERROR
|
||||
--reap
|
||||
|
||||
--connection node_1
|
||||
--disconnect node_1a
|
||||
--disconnect node_1b
|
||||
--disconnect node_1c
|
||||
--disconnect node_1d
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Case 4: MDL-conflict, we execute ALTER until we hit gap in
|
||||
--echo # wsrep_abort_transaction, while we are there we try to
|
||||
--echo # manually KILL conflicting transaction (UPDATE) and
|
||||
--echo # send conflicting transaction from other node to be executed
|
||||
--echo # in this node by applier. As ALTER and KILL are TOI they
|
||||
--echo # are not executed concurrently. Similarly UPDATE from other
|
||||
--echo # node will wait for certification.
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1(id int not null primary key, b int) engine=innodb;
|
||||
INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
|
||||
|
||||
#
|
||||
# This will be victim transaction for both bf kill and
|
||||
# user KILL, and should not have any effect on result
|
||||
#
|
||||
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
begin;
|
||||
update t1 set b = b * 10 where id between 2 and 4;
|
||||
|
||||
#
|
||||
# Take thread id for above query
|
||||
#
|
||||
--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
--let $k_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'root' AND COMMAND = 'Sleep' LIMIT 1`
|
||||
|
||||
#
|
||||
# Set DEBUG_SYNC and send conflicting DDL that will be TOI (bf) and
|
||||
# cause bf_kill but let's execute it only to gap in wsrep_abort_transaction
|
||||
#
|
||||
--connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
SET DEBUG_SYNC='wsrep_abort_victim_unlocked SIGNAL bf_kill_unlocked WAIT_FOR bf_continue';
|
||||
--send ALTER TABLE t1 ADD UNIQUE KEY b1(b);
|
||||
|
||||
#
|
||||
# Wait until we have reached the sync point
|
||||
#
|
||||
--connection node_1
|
||||
SET DEBUG_SYNC='now WAIT_FOR bf_kill_unlocked';
|
||||
|
||||
#
|
||||
# Try to kill update query
|
||||
#
|
||||
--connection node_1b
|
||||
--disable_query_log
|
||||
--send_eval KILL QUERY $k_thread;
|
||||
|
||||
#
|
||||
# Send conflicting update from other node, this should be applied on both nodes
|
||||
# but should not kill ALTER
|
||||
#
|
||||
--enable_query_log
|
||||
--connection node_2
|
||||
--send update t1 set b = b + 1000 where id between 2 and 4;
|
||||
|
||||
#
|
||||
# Let bf_kill continue
|
||||
#
|
||||
--connection node_1
|
||||
SET DEBUG_SYNC='now SIGNAL bf_continue';
|
||||
--connection node_1c
|
||||
--reap
|
||||
SHOW CREATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
|
||||
--connection node_1b
|
||||
--reap
|
||||
--enable_query_log
|
||||
|
||||
--connection node_1
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
SELECT * FROM t1;
|
||||
|
||||
--connection node_2
|
||||
--reap
|
||||
SHOW CREATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--disconnect node_1a
|
||||
--disconnect node_1c
|
||||
|
|
@ -54,11 +54,15 @@ INSERT INTO parent VALUES (1, 0);
|
|||
--connection node_2a
|
||||
--reap
|
||||
|
||||
#
|
||||
# ALTER TABLE could bf kill one or more of INSERTs to parent, so
|
||||
# the actual number of rows in PARENT depends on whether
|
||||
# the INSERT is committed before ALTER TABLE is executed
|
||||
#
|
||||
--connection node_1
|
||||
SET SESSION wsrep_sync_wait=15;
|
||||
SELECT COUNT(*) FROM parent;
|
||||
SELECT COUNT(*) FROM child;
|
||||
|
||||
--connection node_2
|
||||
SET SESSION wsrep_sync_wait=15;
|
||||
SELECT COUNT(*) FROM parent;
|
||||
SELECT COUNT(*) FROM child;
|
||||
|
||||
DROP TABLE child;
|
||||
DROP TABLE parent;
|
||||
|
|
|
@ -66,7 +66,7 @@ call mtr.add_suppression("WSREP: Failed to get provider options");
|
|||
|
||||
#evalp SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
|
||||
|
||||
--replace_regex /.*libgalera.*/libgalera_smm.so/
|
||||
--replace_regex /.*libgalera_smm.*/libgalera_smm.so/
|
||||
SELECT @@global.wsrep_provider;
|
||||
SELECT @@global.wsrep_slave_threads;
|
||||
SELECT @@global.wsrep_cluster_address;
|
||||
|
@ -77,7 +77,7 @@ SHOW STATUS LIKE 'wsrep_thread_count';
|
|||
|
||||
#evalp SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
|
||||
|
||||
--replace_regex /.*libgalera.*/libgalera_smm.so/
|
||||
--replace_regex /.*libgalera_smm.*/libgalera_smm.so/
|
||||
SELECT @@global.wsrep_provider;
|
||||
SELECT @@global.wsrep_cluster_address;
|
||||
SELECT @@global.wsrep_on;
|
||||
|
@ -101,7 +101,7 @@ SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VA
|
|||
SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_rollbacker_thread_count';
|
||||
SELECT VARIABLE_VALUE AS EXPECT_2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
|
||||
|
||||
--replace_regex /.*libgalera.*/libgalera_smm.so/
|
||||
--replace_regex /.*libgalera_smm.*/libgalera_smm.so/
|
||||
SELECT @@global.wsrep_provider;
|
||||
SELECT @@global.wsrep_cluster_address;
|
||||
SELECT @@global.wsrep_on;
|
||||
|
|
|
@ -2391,7 +2391,7 @@ static void clean_up_mutexes()
|
|||
static void set_ports()
|
||||
{
|
||||
}
|
||||
void close_connection(THD *thd, uint sql_errno, my_bool locked)
|
||||
void close_connection(THD *thd, uint sql_errno)
|
||||
{
|
||||
}
|
||||
#else
|
||||
|
@ -2867,7 +2867,7 @@ static void network_init(void)
|
|||
For the connection that is doing shutdown, this is called twice
|
||||
*/
|
||||
|
||||
void close_connection(THD *thd, uint sql_errno, my_bool locked)
|
||||
void close_connection(THD *thd, uint sql_errno)
|
||||
{
|
||||
DBUG_ENTER("close_connection");
|
||||
|
||||
|
@ -2877,10 +2877,7 @@ void close_connection(THD *thd, uint sql_errno, my_bool locked)
|
|||
thd->print_aborted_warning(3, sql_errno ? ER_DEFAULT(sql_errno)
|
||||
: "CLOSE_CONNECTION");
|
||||
|
||||
if (locked)
|
||||
thd->disconnect_mutexed();
|
||||
else
|
||||
thd->disconnect();
|
||||
thd->disconnect();
|
||||
|
||||
MYSQL_CONNECTION_DONE((int) sql_errno, thd->thread_id);
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ enum enum_slave_parallel_mode {
|
|||
|
||||
/* Function prototypes */
|
||||
void kill_mysql(THD *thd= 0);
|
||||
void close_connection(THD *thd, uint sql_errno= 0, my_bool locked=false);
|
||||
void close_connection(THD *thd, uint sql_errno= 0);
|
||||
void handle_connection_in_main_thread(CONNECT *thd);
|
||||
void create_thread_to_handle_connection(CONNECT *connect);
|
||||
void signal_thd_deleted();
|
||||
|
|
|
@ -1804,11 +1804,11 @@ void THD::awake(killed_state state_to_set)
|
|||
the Vio might be disassociated concurrently.
|
||||
*/
|
||||
|
||||
void THD::disconnect_mutexed()
|
||||
void THD::disconnect()
|
||||
{
|
||||
Vio *vio= NULL;
|
||||
|
||||
mysql_mutex_assert_owner(&LOCK_thd_data);
|
||||
mysql_mutex_lock(&LOCK_thd_data);
|
||||
|
||||
set_killed(KILL_CONNECTION);
|
||||
|
||||
|
@ -1826,6 +1826,8 @@ void THD::disconnect_mutexed()
|
|||
if (net.vio != vio)
|
||||
vio_close(net.vio);
|
||||
net.thd= 0; // Don't collect statistics
|
||||
|
||||
mysql_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1877,18 +1879,16 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
|
|||
thread can see those instances (e.g. see partitioning code).
|
||||
*/
|
||||
if (!thd_table->needs_reopen())
|
||||
{
|
||||
signalled|= mysql_lock_abort_for_thread(this, thd_table);
|
||||
if (WSREP(this) && wsrep_thd_is_BF(this, FALSE))
|
||||
{
|
||||
WSREP_DEBUG("remove_table_from_cache: %llu",
|
||||
(unsigned long long) this->real_id);
|
||||
wsrep_abort_thd((void *)this, (void *)in_use, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(this) && wsrep_thd_is_BF(this, false))
|
||||
{
|
||||
WSREP_DEBUG("notify_shared_lock: BF thread %llu query %s"
|
||||
" victim %llu query %s",
|
||||
this->real_id, wsrep_thd_query(this),
|
||||
in_use->real_id, wsrep_thd_query(in_use));
|
||||
wsrep_abort_thd((void *)this, (void *)in_use, false);
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
mysql_mutex_unlock(&in_use->LOCK_thd_data);
|
||||
}
|
||||
|
|
|
@ -3231,13 +3231,8 @@ public:
|
|||
void awake(killed_state state_to_set);
|
||||
|
||||
/** Disconnect the associated communication endpoint. */
|
||||
inline void disconnect()
|
||||
{
|
||||
mysql_mutex_lock(&LOCK_thd_data);
|
||||
disconnect_mutexed();
|
||||
mysql_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
void disconnect_mutexed();
|
||||
void disconnect();
|
||||
|
||||
|
||||
/*
|
||||
Allows this thread to serve as a target for others to schedule Async
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
|
||||
Copyright (c) 2008, 2021, MariaDB
|
||||
Copyright (c) 2008, 2020, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -9069,18 +9069,6 @@ static
|
|||
void sql_kill(THD *thd, longlong id, killed_state state, killed_type type)
|
||||
{
|
||||
uint error;
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
{
|
||||
WSREP_DEBUG("sql_kill called");
|
||||
if (thd->wsrep_applier)
|
||||
{
|
||||
WSREP_DEBUG("KILL in applying, bailing out here");
|
||||
return;
|
||||
}
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
if (!(error= kill_one_thread(thd, id, state, type)))
|
||||
{
|
||||
if (!thd->killed)
|
||||
|
@ -9090,11 +9078,6 @@ void sql_kill(THD *thd, longlong id, killed_state state, killed_type type)
|
|||
}
|
||||
else
|
||||
my_error(error, MYF(0), id);
|
||||
#ifdef WITH_WSREP
|
||||
return;
|
||||
wsrep_error_label:
|
||||
my_error(ER_CANNOT_USER, MYF(0), wsrep_thd_query(thd));
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
|
||||
|
||||
|
@ -9103,18 +9086,6 @@ void sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
|
|||
{
|
||||
uint error;
|
||||
ha_rows rows;
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
{
|
||||
WSREP_DEBUG("sql_kill_user called");
|
||||
if (thd->wsrep_applier)
|
||||
{
|
||||
WSREP_DEBUG("KILL in applying, bailing out here");
|
||||
return;
|
||||
}
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
if (!(error= kill_threads_for_user(thd, user, state, &rows)))
|
||||
my_ok(thd, rows);
|
||||
else
|
||||
|
@ -9125,11 +9096,6 @@ void sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
|
|||
*/
|
||||
my_error(error, MYF(0), user->host.str, user->user.str);
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
return;
|
||||
wsrep_error_label:
|
||||
my_error(ER_CANNOT_USER, MYF(0), user->user.str);
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright 2008-2021 Codership Oy <http://www.codership.com>
|
||||
/* Copyright 2008-2015 Codership Oy <http://www.codership.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -835,25 +835,13 @@ void wsrep_thr_init()
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* This is wrapper for wsrep_break_lock in thr_lock.c */
|
||||
static int wsrep_thr_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr, my_bool signal)
|
||||
{
|
||||
THD* victim_thd= (THD *) victim_thd_ptr;
|
||||
/* We need to lock THD::LOCK_thd_data to protect victim
|
||||
from concurrent usage or disconnect or delete. */
|
||||
mysql_mutex_lock(&victim_thd->LOCK_thd_data);
|
||||
int res= wsrep_abort_thd(bf_thd_ptr, victim_thd_ptr, signal);
|
||||
mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
|
||||
return res;
|
||||
}
|
||||
|
||||
void wsrep_init_startup (bool first)
|
||||
{
|
||||
if (wsrep_init()) unireg_abort(1);
|
||||
|
||||
wsrep_thr_lock_init(
|
||||
(wsrep_thd_is_brute_force_fun)wsrep_thd_is_BF,
|
||||
(wsrep_abort_thd_fun)wsrep_thr_abort_thd,
|
||||
(wsrep_abort_thd_fun)wsrep_abort_thd,
|
||||
wsrep_debug, wsrep_convert_LOCK_to_trx,
|
||||
(wsrep_on_fun)wsrep_on);
|
||||
|
||||
|
@ -1706,11 +1694,6 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_,
|
|||
case SQLCOM_DROP_TABLE:
|
||||
buf_err= wsrep_drop_table_query(thd, &buf, &buf_len);
|
||||
break;
|
||||
case SQLCOM_KILL:
|
||||
WSREP_DEBUG("KILL as TOI: %s", thd->query());
|
||||
buf_err= wsrep_to_buf_helper(thd, thd->query(), thd->query_length(),
|
||||
&buf, &buf_len);
|
||||
break;
|
||||
case SQLCOM_CREATE_ROLE:
|
||||
if (sp_process_definer(thd))
|
||||
{
|
||||
|
@ -2075,11 +2058,8 @@ bool wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
|
|||
ticket->wsrep_report(true);
|
||||
}
|
||||
|
||||
/* This will call wsrep_abort_transaction so we should hold
|
||||
THD::LOCK_thd_data to protect victim from concurrent usage
|
||||
or disconnect or delete. */
|
||||
wsrep_abort_thd((void *) request_thd, (void *) granted_thd, 1);
|
||||
mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
|
||||
wsrep_abort_thd((void *) request_thd, (void *) granted_thd, 1);
|
||||
ret= false;
|
||||
}
|
||||
}
|
||||
|
@ -2261,7 +2241,6 @@ error:
|
|||
static bool abort_replicated(THD *thd)
|
||||
{
|
||||
bool ret_code= false;
|
||||
mysql_mutex_assert_owner(&thd->LOCK_thd_data);
|
||||
if (thd->wsrep_query_state== QUERY_COMMITTING)
|
||||
{
|
||||
WSREP_DEBUG("aborting replicated trx: %llu", (ulonglong)(thd->real_id));
|
||||
|
@ -2276,7 +2255,6 @@ static bool abort_replicated(THD *thd)
|
|||
/**/
|
||||
static inline bool is_client_connection(THD *thd)
|
||||
{
|
||||
mysql_mutex_assert_owner(&thd->LOCK_thd_data);
|
||||
return (thd->wsrep_client_thread && thd->variables.wsrep_on);
|
||||
}
|
||||
|
||||
|
@ -2285,8 +2263,9 @@ static inline bool is_replaying_connection(THD *thd)
|
|||
{
|
||||
bool ret;
|
||||
|
||||
mysql_mutex_assert_owner(&thd->LOCK_thd_data);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
ret= (thd->wsrep_conflict_state == REPLAYING) ? true : false;
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2296,8 +2275,9 @@ static inline bool is_committing_connection(THD *thd)
|
|||
{
|
||||
bool ret;
|
||||
|
||||
mysql_mutex_assert_owner(&thd->LOCK_thd_data);
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
ret= (thd->wsrep_query_state == QUERY_COMMITTING) ? true : false;
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2310,17 +2290,13 @@ static bool have_client_connections()
|
|||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++))
|
||||
{
|
||||
/* Protect thread from concurrent usage or disconnect or delete. */
|
||||
mysql_mutex_lock(&tmp->LOCK_thd_data);
|
||||
DBUG_PRINT("quit",("Informing thread %lld that it's time to die",
|
||||
(longlong) tmp->thread_id));
|
||||
if (is_client_connection(tmp) && tmp->killed == KILL_CONNECTION)
|
||||
{
|
||||
(void)abort_replicated(tmp);
|
||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
return true;
|
||||
}
|
||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -2352,21 +2328,14 @@ static my_bool have_committing_connections()
|
|||
I_List_iterator<THD> it(threads);
|
||||
while ((tmp=it++))
|
||||
{
|
||||
/* Protect from concurrent usage or disconnect or delete */
|
||||
mysql_mutex_lock(&tmp->LOCK_thd_data);
|
||||
if (!is_client_connection(tmp))
|
||||
{
|
||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_committing_connection(tmp))
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
return TRUE;
|
||||
}
|
||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
return FALSE;
|
||||
|
@ -2409,44 +2378,33 @@ void wsrep_close_client_connections(my_bool wait_to_end, THD *except_caller_thd)
|
|||
{
|
||||
DBUG_PRINT("quit",("Informing thread %lld that it's time to die",
|
||||
(longlong) tmp->thread_id));
|
||||
/* Protect from concurrent usage or disconnect or delete */
|
||||
mysql_mutex_lock(&tmp->LOCK_thd_data);
|
||||
/* We skip slave threads & scheduler on this first loop through. */
|
||||
if (!is_client_connection(tmp))
|
||||
{
|
||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tmp == except_caller_thd)
|
||||
{
|
||||
DBUG_ASSERT(is_client_connection(tmp));
|
||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_replaying_connection(tmp))
|
||||
{
|
||||
tmp->set_killed(KILL_CONNECTION);
|
||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* replicated transactions must be skipped and aborted
|
||||
with wsrep_abort_thd. */
|
||||
/* replicated transactions must be skipped */
|
||||
if (abort_replicated(tmp))
|
||||
{
|
||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
continue;
|
||||
}
|
||||
|
||||
WSREP_DEBUG("closing connection %lld", (longlong) tmp->thread_id);
|
||||
|
||||
/*
|
||||
instead of wsrep_close_thread() we do now soft kill by
|
||||
THD::awake(). Here also victim needs to be protected from
|
||||
concurrent usage or disconnect or delete.
|
||||
*/
|
||||
instead of wsrep_close_thread() we do now soft kill by THD::awake
|
||||
*/
|
||||
mysql_mutex_lock(&tmp->LOCK_thd_data);
|
||||
|
||||
tmp->awake(KILL_CONNECTION);
|
||||
|
||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
|
@ -2465,19 +2423,16 @@ void wsrep_close_client_connections(my_bool wait_to_end, THD *except_caller_thd)
|
|||
I_List_iterator<THD> it2(threads);
|
||||
while ((tmp=it2++))
|
||||
{
|
||||
/* Protect from concurrent usage or disconnect or delete */
|
||||
mysql_mutex_lock(&tmp->LOCK_thd_data);
|
||||
if (is_client_connection(tmp))
|
||||
#ifndef __bsdi__ // Bug in BSDI kernel
|
||||
if (is_client_connection(tmp) &&
|
||||
!abort_replicated(tmp) &&
|
||||
!is_replaying_connection(tmp) &&
|
||||
tmp != except_caller_thd)
|
||||
{
|
||||
if (!abort_replicated(tmp) &&
|
||||
!is_replaying_connection(tmp) &&
|
||||
tmp != except_caller_thd)
|
||||
{
|
||||
WSREP_INFO("killing local connection: %lld", (longlong) tmp->thread_id);
|
||||
close_connection(tmp,0, true);
|
||||
}
|
||||
WSREP_INFO("killing local connection: %lld", (longlong) tmp->thread_id);
|
||||
close_connection(tmp,0);
|
||||
}
|
||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
|
||||
|
@ -2666,9 +2621,7 @@ extern "C" void wsrep_thd_set_query_state(
|
|||
|
||||
void wsrep_thd_set_conflict_state(THD *thd, enum wsrep_conflict_state state)
|
||||
{
|
||||
DBUG_ASSERT(thd);
|
||||
mysql_mutex_assert_owner(&thd->LOCK_thd_data);
|
||||
thd->wsrep_conflict_state= state;
|
||||
if (WSREP(thd)) thd->wsrep_conflict_state= state;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2809,9 +2762,6 @@ extern "C" void wsrep_thd_awake(THD *thd, my_bool signal)
|
|||
{
|
||||
if (signal)
|
||||
{
|
||||
/* Here we should hold THD::LOCK_thd_data to
|
||||
protect from concurrent usage. */
|
||||
mysql_mutex_assert_owner(&thd->LOCK_thd_data);
|
||||
thd->awake(KILL_QUERY);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2013-2021 Codership Oy <info@codership.com>
|
||||
/* Copyright (C) 2013 Codership Oy <info@codership.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -804,12 +804,10 @@ my_bool wsrep_thd_is_local(void *thd_ptr, my_bool sync)
|
|||
|
||||
int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr, my_bool signal)
|
||||
{
|
||||
THD *victim_thd= (THD *) victim_thd_ptr;
|
||||
THD *bf_thd= (THD *) bf_thd_ptr;
|
||||
THD *victim_thd = (THD *) victim_thd_ptr;
|
||||
THD *bf_thd = (THD *) bf_thd_ptr;
|
||||
DBUG_ENTER("wsrep_abort_thd");
|
||||
|
||||
mysql_mutex_assert_owner(&victim_thd->LOCK_thd_data);
|
||||
|
||||
if ( (WSREP(bf_thd) ||
|
||||
( (WSREP_ON || bf_thd->variables.wsrep_OSU_method == WSREP_OSU_RSU) &&
|
||||
bf_thd->wsrep_exec_mode == TOTAL_ORDER) ) &&
|
||||
|
|
|
@ -32,6 +32,7 @@ void wsrep_create_rollbacker();
|
|||
|
||||
int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr,
|
||||
my_bool signal);
|
||||
|
||||
/*
|
||||
PA = Parallel Applying (on the slave side)
|
||||
*/
|
||||
|
|
|
@ -60,6 +60,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#include <my_service_manager.h>
|
||||
#include <key.h>
|
||||
#include <sql_manager.h>
|
||||
|
||||
/* Include necessary InnoDB headers */
|
||||
#include "btr0btr.h"
|
||||
|
@ -5233,21 +5234,17 @@ UNIV_INTERN void lock_cancel_waiting_and_release(lock_t* lock);
|
|||
@sa THD::awake() @sa ha_kill_query() */
|
||||
static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels)
|
||||
{
|
||||
DBUG_ENTER("innobase_kill_query");
|
||||
DBUG_ENTER("innobase_kill_query");
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_thd_get_conflict_state(thd) != NO_CONFLICT)
|
||||
{
|
||||
/* if victim has been signaled by BF thread and/or aborting
|
||||
is already progressing, following query aborting is not necessary
|
||||
any more. E.g. wsrep_innobase_kill_one_trx().
|
||||
Also, BF thread should own trx mutex for the victim, which would
|
||||
conflict with trx_mutex_enter() below
|
||||
*/
|
||||
WSREP_DEBUG("Victim thread %ld bail out conflict_state %s query %s",
|
||||
thd_get_thread_id(thd),
|
||||
wsrep_thd_conflict_state_str(thd), wsrep_thd_query(thd));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
if (wsrep_thd_get_conflict_state(thd) != NO_CONFLICT) {
|
||||
/* if victim has been signaled by BF thread and/or aborting
|
||||
is already progressing, following query aborting is not necessary
|
||||
any more.
|
||||
Also, BF thread should own trx mutex for the victim, which would
|
||||
conflict with trx_mutex_enter() below
|
||||
*/
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (trx_t* trx= thd_to_trx(thd))
|
||||
|
@ -19502,9 +19499,9 @@ static struct st_mysql_storage_engine innobase_storage_engine=
|
|||
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
static
|
||||
void
|
||||
wsrep_abort_slave_trx(
|
||||
/*==================*/
|
||||
wsrep_seqno_t bf_seqno,
|
||||
wsrep_seqno_t victim_seqno)
|
||||
{
|
||||
|
@ -19514,97 +19511,93 @@ wsrep_abort_slave_trx(
|
|||
"2) a bug in the code.\n\t"
|
||||
"3) a database corruption.\n Node consistency compromized, "
|
||||
"need to abort. Restart the node to resync with cluster.",
|
||||
bf_seqno, victim_seqno);
|
||||
(long long)bf_seqno, (long long)victim_seqno);
|
||||
abort();
|
||||
}
|
||||
/*******************************************************************//**
|
||||
This function is used to kill one transaction in BF. */
|
||||
void
|
||||
wsrep_innobase_kill_one_trx(
|
||||
MYSQL_THD const bf_thd,
|
||||
const trx_t * const bf_trx,
|
||||
trx_t *victim_trx,
|
||||
my_bool signal)
|
||||
|
||||
struct bg_wsrep_kill_trx_arg {
|
||||
my_thread_id thd_id;
|
||||
trx_id_t trx_id;
|
||||
int64_t bf_seqno;
|
||||
ibool signal;
|
||||
};
|
||||
|
||||
static void bg_wsrep_kill_trx(
|
||||
void *void_arg)
|
||||
{
|
||||
ut_ad(bf_thd);
|
||||
ut_ad(victim_trx);
|
||||
ut_ad(lock_mutex_own());
|
||||
ut_ad(trx_mutex_own(victim_trx));
|
||||
bg_wsrep_kill_trx_arg *arg = (bg_wsrep_kill_trx_arg*)void_arg;
|
||||
THD *thd = find_thread_by_id(arg->thd_id, false);
|
||||
trx_t *victim_trx = NULL;
|
||||
bool awake = false;
|
||||
DBUG_ENTER("bg_wsrep_kill_trx");
|
||||
|
||||
DBUG_ENTER("wsrep_innobase_kill_one_trx");
|
||||
THD *thd= (THD *) victim_trx->mysql_thd;
|
||||
int64_t bf_seqno= wsrep_thd_trx_seqno(bf_thd);
|
||||
|
||||
if (!thd) {
|
||||
WSREP_WARN("no THD for trx: " TRX_ID_FMT, victim_trx->id);
|
||||
DBUG_VOID_RETURN;
|
||||
if (thd) {
|
||||
victim_trx= thd_to_trx(thd);
|
||||
/* Victim trx might not exist e.g. on MDL-conflict. */
|
||||
if (victim_trx) {
|
||||
lock_mutex_enter();
|
||||
trx_mutex_enter(victim_trx);
|
||||
if (victim_trx->id != arg->trx_id ||
|
||||
victim_trx->state == TRX_STATE_COMMITTED_IN_MEMORY)
|
||||
{
|
||||
/* Victim was meanwhile rolled back or
|
||||
committed */
|
||||
trx_mutex_exit(victim_trx);
|
||||
lock_mutex_exit();
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
victim_trx= NULL;
|
||||
}
|
||||
} else {
|
||||
/* find_thread_by_id locked
|
||||
THD::LOCK_thd_data */
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we need to lock THD::LOCK_thd_data to protect from
|
||||
concurrent usage or disconnect or delete. */
|
||||
DEBUG_SYNC(bf_thd, "wsrep_before_BF_victim_lock");
|
||||
wsrep_thd_LOCK(thd);
|
||||
DEBUG_SYNC(bf_thd, "wsrep_after_BF_victim_lock");
|
||||
if (!victim_trx) {
|
||||
/* Victim trx might not exist (MDL-conflict) or victim
|
||||
was meanwhile rolled back or committed because of
|
||||
a KILL statement or a disconnect. */
|
||||
goto ret;
|
||||
}
|
||||
|
||||
WSREP_DEBUG("Aborter %s trx_id: " TRX_ID_FMT " thread: %ld "
|
||||
"seqno: %lld query_state: %s conflict_state: %s query: %s",
|
||||
wsrep_thd_is_BF(bf_thd, false) ? "BF" : "normal",
|
||||
bf_trx ? bf_trx->id : TRX_ID_MAX,
|
||||
thd_get_thread_id(bf_thd),
|
||||
bf_seqno,
|
||||
wsrep_thd_query_state_str(bf_thd),
|
||||
wsrep_thd_conflict_state_str(bf_thd),
|
||||
wsrep_thd_query(bf_thd));
|
||||
|
||||
WSREP_DEBUG("Victim %s trx_id: " TRX_ID_FMT " thread: %ld "
|
||||
"seqno: %lld query_state: %s conflict_state: %s query: %s",
|
||||
wsrep_thd_is_BF(thd, false) ? "BF" : "normal",
|
||||
victim_trx->id,
|
||||
WSREP_DEBUG("BF kill (" ULINTPF ", seqno: " INT64PF
|
||||
"), victim: (%lu) trx: " TRX_ID_FMT,
|
||||
arg->signal, arg->bf_seqno,
|
||||
thd_get_thread_id(thd),
|
||||
wsrep_thd_trx_seqno(thd),
|
||||
wsrep_thd_query_state_str(thd),
|
||||
wsrep_thd_conflict_state_str(thd),
|
||||
wsrep_thd_query(thd));
|
||||
victim_trx->id);
|
||||
|
||||
WSREP_LOG_CONFLICT(bf_thd, thd, TRUE);
|
||||
WSREP_DEBUG("Aborting query: %s conf %d trx: %" PRId64,
|
||||
(wsrep_thd_query(thd)) ? wsrep_thd_query(thd) : "void",
|
||||
wsrep_thd_conflict_state(thd, FALSE),
|
||||
wsrep_thd_ws_handle(thd)->trx_id);
|
||||
|
||||
if (wsrep_thd_query_state(thd) == QUERY_EXITING) {
|
||||
WSREP_DEBUG("kill trx EXITING for " TRX_ID_FMT,
|
||||
victim_trx->id);
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
DBUG_VOID_RETURN;
|
||||
goto ret_unlock;
|
||||
}
|
||||
|
||||
if (wsrep_thd_exec_mode(thd) != LOCAL_STATE) {
|
||||
WSREP_DEBUG("withdraw for BF trx: " TRX_ID_FMT
|
||||
", state: %s exec %s",
|
||||
WSREP_DEBUG("withdraw for BF trx: " TRX_ID_FMT ", state: %d",
|
||||
victim_trx->id,
|
||||
wsrep_thd_conflict_state_str(thd),
|
||||
wsrep_thd_exec_mode_str(thd));
|
||||
wsrep_thd_get_conflict_state(thd));
|
||||
}
|
||||
|
||||
switch (wsrep_thd_get_conflict_state(thd)) {
|
||||
case NO_CONFLICT:
|
||||
/* This will cause any call to innobase_kill_query()
|
||||
for this thd to bail out. */
|
||||
wsrep_thd_set_conflict_state(thd, MUST_ABORT);
|
||||
break;
|
||||
case MUST_ABORT:
|
||||
WSREP_DEBUG("victim " TRX_ID_FMT " in MUST ABORT state",
|
||||
victim_trx->id);
|
||||
wsrep_thd_awake(thd, signal);
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
DBUG_VOID_RETURN;
|
||||
break;
|
||||
goto ret_awake;
|
||||
case ABORTED:
|
||||
case ABORTING: // fall through
|
||||
default:
|
||||
WSREP_DEBUG("victim " TRX_ID_FMT " in state %s",
|
||||
victim_trx->id,
|
||||
wsrep_thd_conflict_state_str(thd));
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
DBUG_VOID_RETURN;
|
||||
break;
|
||||
WSREP_DEBUG("victim " TRX_ID_FMT " in state %d",
|
||||
victim_trx->id, wsrep_thd_get_conflict_state(thd));
|
||||
goto ret_unlock;
|
||||
}
|
||||
|
||||
switch (wsrep_thd_query_state(thd)) {
|
||||
|
@ -19617,12 +19610,12 @@ wsrep_innobase_kill_one_trx(
|
|||
victim_trx->id);
|
||||
|
||||
if (wsrep_thd_exec_mode(thd) == REPL_RECV) {
|
||||
wsrep_abort_slave_trx(bf_seqno,
|
||||
wsrep_abort_slave_trx(arg->bf_seqno,
|
||||
wsrep_thd_trx_seqno(thd));
|
||||
} else {
|
||||
wsrep_t *wsrep= get_wsrep();
|
||||
rcode = wsrep->abort_pre_commit(
|
||||
wsrep, bf_seqno,
|
||||
wsrep, arg->bf_seqno,
|
||||
(wsrep_trx_id_t)wsrep_thd_ws_handle(thd)->trx_id
|
||||
);
|
||||
|
||||
|
@ -19631,10 +19624,7 @@ wsrep_innobase_kill_one_trx(
|
|||
WSREP_DEBUG("cancel commit warning: "
|
||||
TRX_ID_FMT,
|
||||
victim_trx->id);
|
||||
wsrep_thd_awake(thd, signal);
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
DBUG_VOID_RETURN;
|
||||
break;
|
||||
goto ret_awake;
|
||||
case WSREP_OK:
|
||||
break;
|
||||
default:
|
||||
|
@ -19647,12 +19637,9 @@ wsrep_innobase_kill_one_trx(
|
|||
* kill the lock holder first.
|
||||
*/
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
wsrep_thd_awake(thd, signal);
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
break;
|
||||
goto ret_awake;
|
||||
case QUERY_EXEC:
|
||||
/* it is possible that victim trx is itself waiting for some
|
||||
* other lock. We need to cancel this waiting
|
||||
|
@ -19673,65 +19660,118 @@ wsrep_innobase_kill_one_trx(
|
|||
lock_cancel_waiting_and_release(wait_lock);
|
||||
}
|
||||
|
||||
wsrep_thd_awake(thd, signal);
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
} else {
|
||||
/* abort currently executing query */
|
||||
DBUG_PRINT("wsrep",("sending KILL_QUERY to: %lu",
|
||||
thd_get_thread_id(thd)));
|
||||
WSREP_DEBUG("kill query for: %ld",
|
||||
thd_get_thread_id(thd));
|
||||
wsrep_thd_awake(thd, signal);
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
|
||||
/* for BF thd, we need to prevent him from committing */
|
||||
if (wsrep_thd_exec_mode(thd) == REPL_RECV) {
|
||||
wsrep_abort_slave_trx(bf_seqno,
|
||||
wsrep_thd_trx_seqno(thd));
|
||||
wsrep_abort_slave_trx(arg->bf_seqno,
|
||||
wsrep_thd_trx_seqno(thd));
|
||||
}
|
||||
}
|
||||
break;
|
||||
goto ret_awake;
|
||||
case QUERY_IDLE:
|
||||
{
|
||||
WSREP_DEBUG("kill IDLE for " TRX_ID_FMT, victim_trx->id);
|
||||
|
||||
if (wsrep_thd_exec_mode(thd) == REPL_RECV) {
|
||||
WSREP_DEBUG("kill BF IDLE, seqno: %lld",
|
||||
wsrep_thd_trx_seqno(thd));
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
wsrep_abort_slave_trx(bf_seqno,
|
||||
(long long)wsrep_thd_trx_seqno(thd));
|
||||
wsrep_abort_slave_trx(arg->bf_seqno,
|
||||
wsrep_thd_trx_seqno(thd));
|
||||
DBUG_VOID_RETURN;
|
||||
goto ret_unlock;
|
||||
}
|
||||
/* This will lock thd from proceeding after net_read()
|
||||
and innobase_kill_query to bail out for this thd. */
|
||||
/* This will lock thd from proceeding after net_read() */
|
||||
wsrep_thd_set_conflict_state(thd, ABORTING);
|
||||
|
||||
wsrep_lock_rollback();
|
||||
|
||||
if (wsrep_aborting_thd_contains(thd)) {
|
||||
WSREP_WARN("duplicate thd aborter %lu",
|
||||
thd_get_thread_id(thd));
|
||||
(ulong) thd_get_thread_id(thd));
|
||||
} else {
|
||||
wsrep_aborting_thd_enqueue(thd);
|
||||
DBUG_PRINT("wsrep",("enqueuing trx abort for %lu",
|
||||
thd_get_thread_id(thd)));
|
||||
WSREP_DEBUG("enqueuing trx abort for (%lu)",
|
||||
thd_get_thread_id(thd));
|
||||
thd_get_thread_id(thd));
|
||||
}
|
||||
|
||||
DBUG_PRINT("wsrep",("signalling wsrep rollbacker"));
|
||||
WSREP_DEBUG("signaling aborter");
|
||||
wsrep_unlock_rollback();
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
|
||||
break;
|
||||
goto ret_unlock;
|
||||
}
|
||||
default:
|
||||
ut_error;
|
||||
WSREP_WARN("bad wsrep query state: %d",
|
||||
wsrep_thd_query_state(thd));
|
||||
goto ret_unlock;
|
||||
}
|
||||
|
||||
ret_awake:
|
||||
awake= true;
|
||||
|
||||
ret_unlock:
|
||||
trx_mutex_exit(victim_trx);
|
||||
lock_mutex_exit();
|
||||
if (awake)
|
||||
wsrep_thd_awake(thd, arg->signal);
|
||||
wsrep_thd_UNLOCK(thd);
|
||||
|
||||
ret:
|
||||
free(arg);
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
This function is used to kill one transaction in BF. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
wsrep_innobase_kill_one_trx(
|
||||
/*========================*/
|
||||
MYSQL_THD const bf_thd,
|
||||
const trx_t * const bf_trx,
|
||||
trx_t *victim_trx,
|
||||
ibool signal)
|
||||
{
|
||||
ut_ad(bf_thd);
|
||||
ut_ad(victim_trx);
|
||||
ut_ad(lock_mutex_own());
|
||||
ut_ad(trx_mutex_own(victim_trx));
|
||||
|
||||
bg_wsrep_kill_trx_arg *arg = (bg_wsrep_kill_trx_arg*)malloc(sizeof(*arg));
|
||||
arg->thd_id = thd_get_thread_id(victim_trx->mysql_thd);
|
||||
arg->trx_id = victim_trx->id;
|
||||
arg->bf_seqno = wsrep_thd_trx_seqno((THD*)bf_thd);
|
||||
arg->signal = signal;
|
||||
|
||||
DBUG_ENTER("wsrep_innobase_kill_one_trx");
|
||||
|
||||
WSREP_LOG_CONFLICT(bf_thd, victim_trx->mysql_thd, TRUE);
|
||||
|
||||
DBUG_EXECUTE_IF("sync.wsrep_after_BF_victim_lock",
|
||||
{
|
||||
const char act[]=
|
||||
"now "
|
||||
"wait_for signal.wsrep_after_BF_victim_lock";
|
||||
DBUG_ASSERT(!debug_sync_set_action(bf_thd,
|
||||
STRING_WITH_LEN(act)));
|
||||
};);
|
||||
|
||||
|
||||
mysql_manager_submit(bg_wsrep_kill_trx, arg);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
wsrep_abort_transaction(
|
||||
/*====================*/
|
||||
handlerton* hton,
|
||||
THD *bf_thd,
|
||||
THD *victim_thd,
|
||||
|
@ -19739,66 +19779,28 @@ wsrep_abort_transaction(
|
|||
{
|
||||
DBUG_ENTER("wsrep_abort_transaction");
|
||||
|
||||
ut_ad(bf_thd);
|
||||
ut_ad(victim_thd);
|
||||
trx_t* victim_trx= thd_to_trx(victim_thd);
|
||||
trx_t* bf_trx= thd_to_trx(bf_thd);
|
||||
trx_t* victim_trx = thd_to_trx(victim_thd);
|
||||
trx_t* bf_trx = (bf_thd) ? thd_to_trx(bf_thd) : NULL;
|
||||
|
||||
/* Here we should hold THD::LOCK_thd_data to protect
|
||||
victim from concurrent usage or disconnect or delete. */
|
||||
WSREP_DEBUG("wsrep_abort_transaction: BF:"
|
||||
" thread %ld query_state %s conflict_state %s"
|
||||
" exec %s query %s trx " TRX_ID_FMT,
|
||||
thd_get_thread_id(bf_thd),
|
||||
wsrep_thd_query_state_str(bf_thd),
|
||||
wsrep_thd_conflict_state_str(bf_thd),
|
||||
wsrep_thd_exec_mode_str(bf_thd),
|
||||
wsrep_thd_query(bf_thd),
|
||||
bf_trx ? bf_trx->id : 0);
|
||||
|
||||
WSREP_DEBUG("wsrep_abort_transaction: victim:"
|
||||
" thread %ld query_state %s conflict_state %s"
|
||||
" exec %s query %s trx " TRX_ID_FMT,
|
||||
thd_get_thread_id(victim_thd),
|
||||
wsrep_thd_query_state_str(victim_thd),
|
||||
wsrep_thd_conflict_state_str(victim_thd),
|
||||
wsrep_thd_exec_mode_str(victim_thd),
|
||||
wsrep_thd_query(victim_thd),
|
||||
victim_trx ? victim_trx->id : 0);
|
||||
WSREP_DEBUG("abort transaction: BF: %s victim: %s victim conf: %d",
|
||||
wsrep_thd_query(bf_thd),
|
||||
wsrep_thd_query(victim_thd),
|
||||
wsrep_thd_conflict_state(victim_thd, FALSE));
|
||||
|
||||
if (victim_trx) {
|
||||
WSREP_DEBUG("wsrep_abort_transaction: Victim thread %ld "
|
||||
"transaction " TRX_ID_FMT " trx_state %d",
|
||||
thd_get_thread_id(victim_thd),
|
||||
victim_trx->id,
|
||||
victim_trx->state);
|
||||
/* This is necessary as correct mutexing order is
|
||||
lock_sys -> trx -> THD::LOCK_thd_data and below
|
||||
function assumes we have lock_sys and trx locked
|
||||
and takes THD::LOCK_thd_data for THD state check. */
|
||||
wsrep_thd_UNLOCK(victim_thd);
|
||||
DEBUG_SYNC(bf_thd, "wsrep_abort_victim_unlocked");
|
||||
DBUG_EXECUTE_IF("wsrep_abort_replicated_sleep",
|
||||
WSREP_DEBUG("wsrep_abort_transaction: sleeping "
|
||||
"for thread %ld ",
|
||||
thd_get_thread_id(victim_thd));
|
||||
my_sleep(100000););
|
||||
lock_mutex_enter();
|
||||
trx_mutex_enter(victim_trx);
|
||||
wsrep_innobase_kill_one_trx(bf_thd, bf_trx, victim_trx, signal);
|
||||
lock_mutex_exit();
|
||||
trx_mutex_exit(victim_trx);
|
||||
wsrep_srv_conc_cancel_wait(victim_trx);
|
||||
wsrep_thd_LOCK(victim_thd);
|
||||
DBUG_VOID_RETURN;
|
||||
} else {
|
||||
WSREP_DEBUG("wsrep_abort_transaction: Victim thread %ld "
|
||||
"no transaction",
|
||||
thd_get_thread_id(victim_thd));
|
||||
/* This will cause any call to innobase_kill_query()
|
||||
for this thd to bail out. */
|
||||
WSREP_DEBUG("victim does not have transaction");
|
||||
wsrep_thd_LOCK(victim_thd);
|
||||
wsrep_thd_set_conflict_state(victim_thd, MUST_ABORT);
|
||||
wsrep_thd_awake(victim_thd, signal);
|
||||
wsrep_thd_UNLOCK(victim_thd);
|
||||
}
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
|
|
|
@ -233,11 +233,12 @@ innobase_casedn_str(
|
|||
char* a); /*!< in/out: string to put in lower case */
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
UNIV_INTERN
|
||||
void
|
||||
wsrep_innobase_kill_one_trx(MYSQL_THD const thd_ptr,
|
||||
const trx_t * const bf_trx,
|
||||
trx_t *victim_trx,
|
||||
my_bool signal);
|
||||
ibool signal);
|
||||
int wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
|
||||
unsigned char* str, unsigned int str_length,
|
||||
unsigned int buf_length);
|
||||
|
|
Loading…
Add table
Reference in a new issue