Commit 81d71ee6 authored by Jan Lindström's avatar Jan Lindström

MDEV-12009: Allow to force kill user threads/query which are flagged as high priority by Galera

As noted on kill_one_thread SUPER should be able to kill even
system threads i.e. threads/query flagged as high priority or
wsrep applier thread. Normal user, should not able to kill
threads/query flagged as high priority (BF) or wsrep applier
thread.
parent 21b2fada
...@@ -112,6 +112,7 @@ extern struct wsrep_service_st { ...@@ -112,6 +112,7 @@ extern struct wsrep_service_st {
int (*wsrep_trx_order_before_func)(MYSQL_THD, MYSQL_THD); int (*wsrep_trx_order_before_func)(MYSQL_THD, MYSQL_THD);
void (*wsrep_unlock_rollback_func)(); void (*wsrep_unlock_rollback_func)();
void (*wsrep_set_data_home_dir_func)(const char *data_dir); void (*wsrep_set_data_home_dir_func)(const char *data_dir);
my_bool (*wsrep_thd_is_applier_func)(THD *thd);
} *wsrep_service; } *wsrep_service;
#ifdef MYSQL_DYNAMIC_PLUGIN #ifdef MYSQL_DYNAMIC_PLUGIN
...@@ -155,6 +156,7 @@ extern struct wsrep_service_st { ...@@ -155,6 +156,7 @@ extern struct wsrep_service_st {
#define wsrep_trx_order_before(T1,T2) wsrep_service->wsrep_trx_order_before_func(T1,T2) #define wsrep_trx_order_before(T1,T2) wsrep_service->wsrep_trx_order_before_func(T1,T2)
#define wsrep_unlock_rollback() wsrep_service->wsrep_unlock_rollback_func() #define wsrep_unlock_rollback() wsrep_service->wsrep_unlock_rollback_func()
#define wsrep_set_data_home_dir(A) wsrep_service->wsrep_set_data_home_dir_func(A) #define wsrep_set_data_home_dir(A) wsrep_service->wsrep_set_data_home_dir_func(A)
#define wsrep_thd_is_applier(T) wsrep_service->wsrep_thd_is_applier_func(T)
#define wsrep_debug get_wsrep_debug() #define wsrep_debug get_wsrep_debug()
#define wsrep_log_conflicts get_wsrep_log_conflicts() #define wsrep_log_conflicts get_wsrep_log_conflicts()
...@@ -214,6 +216,7 @@ void wsrep_thd_set_conflict_state(THD *thd, enum wsrep_conflict_state state); ...@@ -214,6 +216,7 @@ void wsrep_thd_set_conflict_state(THD *thd, enum wsrep_conflict_state state);
bool wsrep_thd_ignore_table(THD *thd); bool wsrep_thd_ignore_table(THD *thd);
void wsrep_unlock_rollback(); void wsrep_unlock_rollback();
void wsrep_set_data_home_dir(const char *data_dir); void wsrep_set_data_home_dir(const char *data_dir);
my_bool wsrep_thd_is_applier(THD *thd);
#endif #endif
......
CREATE USER foo@localhost;
GRANT SELECT on test.* TO foo@localhost;
# Open connection to the 1st node using 'test_user1' user.
Got one of the listed errors Got one of the listed errors
Got one of the listed errors Got one of the listed errors
Got one of the listed errors Got one of the listed errors
Got one of the listed errors Got one of the listed errors
DROP USER foo@localhost;
!include ../galera_2nodes.cnf
[mysqld.1]
wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
auto_increment_offset=1
[mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'
auto_increment_offset=2
# #
# This test checks that applier threads are immune to KILL QUERY and KILL STATEMENT # This test checks that applier threads are immune to KILL QUERY and KILL STATEMENT
# when USER is not SUPER
# #
--source include/galera_cluster.inc --source include/galera_cluster.inc
--source include/have_innodb.inc
--connection node_1 --connection node_1
CREATE USER foo@localhost;
GRANT SELECT on test.* TO foo@localhost;
--let $applier_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE != 'wsrep aborter idle' OR STATE IS NULL LIMIT 1` --let $applier_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE != 'wsrep aborter idle' OR STATE IS NULL LIMIT 1`
--let $aborter_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep aborter idle' LIMIT 1`
--echo # Open connection to the 1st node using 'test_user1' user.
--let $port_1= \$NODE_MYPORT_1
--connect(foo_node_1,localhost,foo,,test,$port_1,)
--connection foo_node_1
--disable_query_log --disable_query_log
--error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR --error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR
--eval KILL $applier_thread --eval KILL $applier_thread
...@@ -16,11 +27,48 @@ ...@@ -16,11 +27,48 @@
--error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR --error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR
--eval KILL QUERY $applier_thread --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`
--error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR --error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR
--eval KILL $aborter_thread --eval KILL $aborter_thread
--error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR --error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR
--eval KILL QUERY $aborter_thread --eval KILL QUERY $aborter_thread
--enable_query_log --enable_query_log
#
# SUPER can kill applier threads
#
--connection node_2
--let $applier_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE != 'wsrep aborter idle' OR STATE IS NULL LIMIT 1`
--disable_query_log
--eval KILL $applier_thread
--enable_query_log
--let $aborter_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep aborter idle' LIMIT 1`
--disable_query_log
--eval KILL $aborter_thread
--enable_query_log
--source include/restart_mysqld.inc
--connection node_2
--let $applier_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE != 'wsrep aborter idle' OR STATE IS NULL LIMIT 1`
--disable_query_log
--eval KILL QUERY $applier_thread
--enable_query_log
--let $aborter_thread = `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep aborter idle' LIMIT 1`
--disable_query_log
--eval KILL QUERY $aborter_thread
--enable_query_log
--source include/restart_mysqld.inc
--connection node_1
--disconnect foo_node_1
DROP USER foo@localhost;
...@@ -8292,11 +8292,19 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ ...@@ -8292,11 +8292,19 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
It's ok to also kill DELAYED threads with KILL_CONNECTION instead of It's ok to also kill DELAYED threads with KILL_CONNECTION instead of
KILL_SYSTEM_THREAD; The difference is that KILL_CONNECTION may be KILL_SYSTEM_THREAD; The difference is that KILL_CONNECTION may be
faster and do a harder kill than KILL_SYSTEM_THREAD; faster and do a harder kill than KILL_SYSTEM_THREAD;
Note that if thread is wsrep Brute Force or applier thread we
allow killing it only when we're SUPER.
*/ */
if (((thd->security_ctx->master_access & SUPER_ACL) || if ((thd->security_ctx->master_access & SUPER_ACL) ||
thd->security_ctx->user_matches(tmp->security_ctx)) && (thd->security_ctx->user_matches(tmp->security_ctx)
!wsrep_thd_is_BF(tmp, false)) #ifdef WITH_WSREP
&&
!tmp->wsrep_applier &&
!wsrep_thd_is_BF(tmp, false)
#endif
))
{ {
tmp->awake(kill_signal); tmp->awake(kill_signal);
error=0; error=0;
......
...@@ -181,7 +181,8 @@ static struct wsrep_service_st wsrep_handler = { ...@@ -181,7 +181,8 @@ static struct wsrep_service_st wsrep_handler = {
wsrep_trx_is_aborting, wsrep_trx_is_aborting,
wsrep_trx_order_before, wsrep_trx_order_before,
wsrep_unlock_rollback, wsrep_unlock_rollback,
wsrep_set_data_home_dir wsrep_set_data_home_dir,
wsrep_thd_is_applier,
}; };
static struct thd_specifics_service_st thd_specifics_handler= static struct thd_specifics_service_st thd_specifics_handler=
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
my_bool wsrep_thd_is_BF(THD *, my_bool) my_bool wsrep_thd_is_BF(THD *, my_bool)
{ return 0; } { return 0; }
my_bool wsrep_thd_is_applier(THD *)
{ return 0; }
int wsrep_trx_order_before(THD *, THD *) int wsrep_trx_order_before(THD *, THD *)
{ return 0; } { return 0; }
......
...@@ -2470,7 +2470,6 @@ extern "C" void wsrep_thd_set_exec_mode(THD *thd, enum wsrep_exec_mode mode) ...@@ -2470,7 +2470,6 @@ extern "C" void wsrep_thd_set_exec_mode(THD *thd, enum wsrep_exec_mode mode)
thd->wsrep_exec_mode= mode; thd->wsrep_exec_mode= mode;
} }
extern "C" void wsrep_thd_set_query_state( extern "C" void wsrep_thd_set_query_state(
THD *thd, enum wsrep_query_state state) THD *thd, enum wsrep_query_state state)
{ {
......
...@@ -596,6 +596,15 @@ my_bool wsrep_thd_is_BF(THD *thd, my_bool sync) ...@@ -596,6 +596,15 @@ my_bool wsrep_thd_is_BF(THD *thd, my_bool sync)
return status; return status;
} }
my_bool wsrep_thd_is_applier(THD *thd)
{
my_bool ret = FALSE;
if (thd) {
ret = thd->wsrep_applier;
}
return ret;
}
extern "C" extern "C"
my_bool wsrep_thd_is_BF_or_commit(void *thd_ptr, my_bool sync) my_bool wsrep_thd_is_BF_or_commit(void *thd_ptr, my_bool sync)
{ {
......
...@@ -37,6 +37,7 @@ int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr, ...@@ -37,6 +37,7 @@ int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr,
*/ */
extern void wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe); extern void wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe);
extern my_bool wsrep_thd_is_BF(THD *thd, my_bool sync); extern my_bool wsrep_thd_is_BF(THD *thd, my_bool sync);
extern my_bool wsrep_thd_is_applier(THD *thd);
extern my_bool wsrep_thd_is_wsrep(void *thd_ptr); extern my_bool wsrep_thd_is_wsrep(void *thd_ptr);
enum wsrep_conflict_state wsrep_thd_conflict_state(void *thd_ptr, my_bool sync); enum wsrep_conflict_state wsrep_thd_conflict_state(void *thd_ptr, my_bool sync);
...@@ -47,6 +48,7 @@ extern "C" int wsrep_thd_in_locking_session(void *thd_ptr); ...@@ -47,6 +48,7 @@ extern "C" int wsrep_thd_in_locking_session(void *thd_ptr);
#else /* WITH_WSREP */ #else /* WITH_WSREP */
#define wsrep_thd_is_BF(T, S) (0) #define wsrep_thd_is_BF(T, S) (0)
#define wsrep_thd_is_applier(T) (0)
#define wsrep_abort_thd(X,Y,Z) do { } while(0) #define wsrep_abort_thd(X,Y,Z) do { } while(0)
#define wsrep_create_appliers(T) do { } while(0) #define wsrep_create_appliers(T) do { } while(0)
......
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