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.
This commit is contained in:
parent
21b2fada7a
commit
81d71ee6b2
@ -112,6 +112,7 @@ extern struct wsrep_service_st {
|
||||
int (*wsrep_trx_order_before_func)(MYSQL_THD, MYSQL_THD);
|
||||
void (*wsrep_unlock_rollback_func)();
|
||||
void (*wsrep_set_data_home_dir_func)(const char *data_dir);
|
||||
my_bool (*wsrep_thd_is_applier_func)(THD *thd);
|
||||
} *wsrep_service;
|
||||
|
||||
#ifdef MYSQL_DYNAMIC_PLUGIN
|
||||
@ -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_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_thd_is_applier(T) wsrep_service->wsrep_thd_is_applier_func(T)
|
||||
|
||||
#define wsrep_debug get_wsrep_debug()
|
||||
#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);
|
||||
bool wsrep_thd_ignore_table(THD *thd);
|
||||
void wsrep_unlock_rollback();
|
||||
void wsrep_set_data_home_dir(const char *data_dir);
|
||||
my_bool wsrep_thd_is_applier(THD *thd);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
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
|
||||
DROP USER foo@localhost;
|
||||
|
10
mysql-test/suite/galera/t/galera_kill_applier.cnf
Normal file
10
mysql-test/suite/galera/t/galera_kill_applier.cnf
Normal file
@ -0,0 +1,10 @@
|
||||
!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
|
||||
|
@ -1,14 +1,25 @@
|
||||
#
|
||||
# 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/have_innodb.inc
|
||||
|
||||
--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 $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
|
||||
--error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR
|
||||
--eval KILL $applier_thread
|
||||
@ -16,11 +27,48 @@
|
||||
--error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR
|
||||
--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
|
||||
--eval KILL $aborter_thread
|
||||
|
||||
--error ER_KILL_DENIED_ERROR,ER_KILL_DENIED_ERROR
|
||||
--eval KILL QUERY $aborter_thread
|
||||
--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
|
||||
It's ok to also kill DELAYED threads with KILL_CONNECTION instead of
|
||||
KILL_SYSTEM_THREAD; The difference is that KILL_CONNECTION may be
|
||||
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) ||
|
||||
thd->security_ctx->user_matches(tmp->security_ctx)) &&
|
||||
!wsrep_thd_is_BF(tmp, false))
|
||||
if ((thd->security_ctx->master_access & SUPER_ACL) ||
|
||||
(thd->security_ctx->user_matches(tmp->security_ctx)
|
||||
#ifdef WITH_WSREP
|
||||
&&
|
||||
!tmp->wsrep_applier &&
|
||||
!wsrep_thd_is_BF(tmp, false)
|
||||
#endif
|
||||
))
|
||||
{
|
||||
tmp->awake(kill_signal);
|
||||
error=0;
|
||||
|
@ -181,7 +181,8 @@ static struct wsrep_service_st wsrep_handler = {
|
||||
wsrep_trx_is_aborting,
|
||||
wsrep_trx_order_before,
|
||||
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=
|
||||
|
@ -20,6 +20,9 @@
|
||||
my_bool wsrep_thd_is_BF(THD *, my_bool)
|
||||
{ return 0; }
|
||||
|
||||
my_bool wsrep_thd_is_applier(THD *)
|
||||
{ return 0; }
|
||||
|
||||
int wsrep_trx_order_before(THD *, THD *)
|
||||
{ return 0; }
|
||||
|
||||
|
@ -2470,7 +2470,6 @@ extern "C" void wsrep_thd_set_exec_mode(THD *thd, enum wsrep_exec_mode mode)
|
||||
thd->wsrep_exec_mode= mode;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void wsrep_thd_set_query_state(
|
||||
THD *thd, enum wsrep_query_state state)
|
||||
{
|
||||
|
@ -596,6 +596,15 @@ my_bool wsrep_thd_is_BF(THD *thd, my_bool sync)
|
||||
return status;
|
||||
}
|
||||
|
||||
my_bool wsrep_thd_is_applier(THD *thd)
|
||||
{
|
||||
my_bool ret = FALSE;
|
||||
if (thd) {
|
||||
ret = thd->wsrep_applier;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
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,
|
||||
*/
|
||||
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_applier(THD *thd);
|
||||
extern my_bool wsrep_thd_is_wsrep(void *thd_ptr);
|
||||
|
||||
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);
|
||||
#else /* WITH_WSREP */
|
||||
|
||||
#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_create_appliers(T) do { } while(0)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user