diff --git a/mysql-test/suite/galera/r/galera_kill_applier.result b/mysql-test/suite/galera/r/galera_kill_applier.result index a47f486b5fb..65b6096db2e 100644 --- a/mysql-test/suite/galera/r/galera_kill_applier.result +++ b/mysql-test/suite/galera/r/galera_kill_applier.result @@ -6,13 +6,13 @@ SELECT @@wsrep_slave_threads; 1 SET GLOBAL wsrep_slave_threads=2; KILL ID; -Got one of the listed errors +ERROR HY000: This is a high-priority thread/query and cannot be killed without compromising the consistency of the cluster KILL QUERY ID; -Got one of the listed errors +ERROR HY000: This is a high-priority thread/query and cannot be killed without compromising the consistency of the cluster KILL ID; -Got one of the listed errors +ERROR HY000: This is a high-priority thread/query and cannot be killed without compromising the consistency of the cluster KILL QUERY ID; -Got one of the listed errors +ERROR HY000: This is a high-priority thread/query and cannot be killed without compromising the consistency of the cluster SET GLOBAL wsrep_slave_threads=DEFAULT; connection node_1; create table t1(a int not null primary key) engine=innodb; diff --git a/mysql-test/suite/galera/r/galera_kill_bf.result b/mysql-test/suite/galera/r/galera_kill_bf.result new file mode 100644 index 00000000000..c5b76560933 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_kill_bf.result @@ -0,0 +1,25 @@ +connection node_2; +connection node_1; +connect con1,127.0.0.1,root,,test,$NODE_MYPORT_1; +call mtr.add_suppression("WSREP: ALTER TABLE isolation failure"); +CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT) ENGINE=InnoDB; +INSERT into t1 values (1,1); +SET DEBUG_SYNC = 'alter_table_after_open_tables SIGNAL bf_started WAIT_FOR bf_continue'; +ALTER TABLE t1 DROP COLUMN c2;; +connection node_1; +SET SESSION wsrep_sync_wait = 0; +SET DEBUG_SYNC = 'now WAIT_FOR bf_started'; +KILL ID; +ERROR HY000: This is a high-priority thread/query and cannot be killed without compromising the consistency of the cluster +KILL QUERY ID; +ERROR HY000: This is a high-priority thread/query and cannot be killed without compromising the consistency of the cluster +connection node_1; +SET DEBUG_SYNC = 'now SIGNAL bf_continue'; +connection con1; +SET DEBUG_SYNC = 'RESET'; +SELECT * FROM t1; +c1 +1 +connection node_1; +DROP TABLE t1; +disconnect con1; diff --git a/mysql-test/suite/galera/t/galera_kill_applier.test b/mysql-test/suite/galera/t/galera_kill_applier.test index 88ec55ed0c1..eb05551b334 100644 --- a/mysql-test/suite/galera/t/galera_kill_applier.test +++ b/mysql-test/suite/galera/t/galera_kill_applier.test @@ -17,21 +17,21 @@ SET GLOBAL wsrep_slave_threads=2; --let $applier_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle' LIMIT 1` --replace_result $applier_thread ID ---error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR +--error ER_KILL_DENIED_HIGH_PRIORITY --eval KILL $applier_thread --replace_result $applier_thread ID ---error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR +--error ER_KILL_DENIED_HIGH_PRIORITY --eval KILL QUERY $applier_thread --let $aborter_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep aborter idle' LIMIT 1` --replace_result $aborter_thread ID ---error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR +--error ER_KILL_DENIED_HIGH_PRIORITY --eval KILL $aborter_thread --replace_result $aborter_thread ID ---error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR +--error ER_KILL_DENIED_HIGH_PRIORITY --eval KILL QUERY $aborter_thread SET GLOBAL wsrep_slave_threads=DEFAULT; diff --git a/mysql-test/suite/galera/t/galera_kill_bf.test b/mysql-test/suite/galera/t/galera_kill_bf.test new file mode 100644 index 00000000000..7a5d2ef512a --- /dev/null +++ b/mysql-test/suite/galera/t/galera_kill_bf.test @@ -0,0 +1,41 @@ +--source include/galera_cluster.inc +--source include/have_debug_sync.inc +--source include/have_debug.inc + +--connect con1,127.0.0.1,root,,test,$NODE_MYPORT_1 + +call mtr.add_suppression("WSREP: ALTER TABLE isolation failure"); + +CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT) ENGINE=InnoDB; +INSERT into t1 values (1,1); + +SET DEBUG_SYNC = 'alter_table_after_open_tables SIGNAL bf_started WAIT_FOR bf_continue'; +--send ALTER TABLE t1 DROP COLUMN c2; + +--connection node_1 +SET SESSION wsrep_sync_wait = 0; +SET DEBUG_SYNC = 'now WAIT_FOR bf_started'; +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'debug sync point: alter_table_after_open_tables' +--source include/wait_condition.inc + +--let $applier_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'debug sync point:%' LIMIT 1` + +--replace_result $applier_thread ID +--error ER_KILL_DENIED_HIGH_PRIORITY +--eval KILL $applier_thread + +--replace_result $applier_thread ID +--error ER_KILL_DENIED_HIGH_PRIORITY +--eval KILL QUERY $applier_thread + +--connection node_1 +SET DEBUG_SYNC = 'now SIGNAL bf_continue'; + +--connection con1 +--reap +SET DEBUG_SYNC = 'RESET'; +SELECT * FROM t1; + +--connection node_1 +DROP TABLE t1; +--disconnect con1 diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 13642a62c73..9c9b9ea734f 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -9111,3 +9111,5 @@ ER_NOT_ALLOWED_IN_THIS_CONTEXT eng "'%-.128s' is not allowed in this context" ER_DATA_WAS_COMMITED_UNDER_ROLLBACK eng "Engine %s does not support rollback. Changes were committed during rollback call" +ER_KILL_DENIED_HIGH_PRIORITY + eng "This is a high-priority thread/query and cannot be killed without compromising the consistency of the cluster" diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 559af2fc813..96aad2e01bf 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -9415,17 +9415,21 @@ kill_one_thread(THD *thd, my_thread_id id, killed_state kill_signal, killed_type mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from concurrent usage -#ifdef WITH_WSREP - if (((thd->security_ctx->master_access & PRIV_KILL_OTHER_USER_PROCESS) || - thd->security_ctx->user_matches(tmp->security_ctx)) && - !wsrep_thd_is_BF(tmp, false) && !tmp->wsrep_applier) -#else if ((thd->security_ctx->master_access & PRIV_KILL_OTHER_USER_PROCESS) || thd->security_ctx->user_matches(tmp->security_ctx)) -#endif /* WITH_WSREP */ { - { #ifdef WITH_WSREP + if (wsrep_thd_is_BF(tmp, false) || tmp->wsrep_applier) + { + error= ER_KILL_DENIED_HIGH_PRIORITY; + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_KILL_DENIED_HIGH_PRIORITY, + "Thread %lld is %s and cannot be killed", + tmp->thread_id, + (tmp->wsrep_applier ? "wsrep applier" : "high priority")); + } + else + { if (WSREP(tmp)) { /* Object tmp is not guaranteed to exist after wsrep_kill_thd() @@ -9435,7 +9439,9 @@ kill_one_thread(THD *thd, my_thread_id id, killed_state kill_signal, killed_type #endif /* WITH_WSREP */ tmp->awake_no_mutex(kill_signal); error= 0; +#ifdef WITH_WSREP } +#endif /* WITH_WSREP */ } else error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR : @@ -9565,7 +9571,9 @@ void sql_kill(THD *thd, my_thread_id id, killed_state state, killed_type type) thd->send_kill_message(); } else + { my_error(error, MYF(0), id); + } }