Commit f59f5c4a authored by Marko Mäkelä's avatar Marko Mäkelä

Revert MDEV-25114

Revert 88a4be75 and
9d97f92f, which had been
prematurely pushed by accident.
parent cfe1a258
......@@ -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;
#
# 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;
!include ../galera_2nodes.cnf
[mysqld.1]
wsrep_log_conflicts=ON
wsrep_debug=1
[mysqld.2]
wsrep_log_conflicts=ON
wsrep_debug=1
--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 @@ class THD :public Statement,
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
......
/* 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 */
}
......
/* 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 @@ pthread_handler_t start_wsrep_THD(void *arg)
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
......
/* 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)
*/
......
This diff is collapsed.
......@@ -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);
......
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