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

jan jan.lindstrom at mariadb.com
Thu Jan 31 09:49:53 EET 2019


revision-id: 100fd3e4c66a6e066e1ba5e2b1dafccbee301c2e (mariadb-10.1.37-80-g100fd3e4c66)
parent(s): 27f1de5cb3ededcea5a54d43047b5c38c2965075
author: Jan Lindström
committer: Jan Lindström
timestamp: 2019-01-31 09:45:32 +0200
message:

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.

---
 .../galera/r/galera_ist_mysqldump,debug.rdiff      | 19 ++------
 .../suite/galera/r/galera_kill_applier.result      |  4 ++
 mysql-test/suite/galera/t/galera_kill_applier.test | 56 ++++++++++++++++++++--
 sql/sql_parse.cc                                   | 14 ++++--
 4 files changed, 72 insertions(+), 21 deletions(-)

diff --git a/mysql-test/suite/galera/r/galera_ist_mysqldump,debug.rdiff b/mysql-test/suite/galera/r/galera_ist_mysqldump,debug.rdiff
index 141b1ebd25f..c168a8abdd1 100644
--- a/mysql-test/suite/galera/r/galera_ist_mysqldump,debug.rdiff
+++ b/mysql-test/suite/galera/r/galera_ist_mysqldump,debug.rdiff
@@ -1,12 +1,11 @@
---- r/galera_ist_mysqldump.result	2018-11-22 14:25:28.551554055 +0200
-+++ r/galera_ist_mysqldump.reject	2018-11-22 15:46:33.119441931 +0200
-@@ -200,6 +200,114 @@
+--- r/galera_ist_mysqldump.result	2018-11-19 14:10:26.307031336 +0200
++++ r/galera_ist_mysqldump.reject	2019-01-30 11:57:13.199102357 +0200
+@@ -180,6 +180,103 @@
  DROP TABLE t1;
  COMMIT;
  SET AUTOCOMMIT=ON;
 +Performing State Transfer on a server that has been killed and restarted
 +while a DDL was in progress on it
-+connection node_1;
 +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB;
 +SET AUTOCOMMIT=OFF;
 +START TRANSACTION;
@@ -15,7 +14,6 @@
 +INSERT INTO t1 VALUES ('node1_committed_before');
 +INSERT INTO t1 VALUES ('node1_committed_before');
 +INSERT INTO t1 VALUES ('node1_committed_before');
-+connection node_2;
 +START TRANSACTION;
 +INSERT INTO t1 VALUES ('node2_committed_before');
 +INSERT INTO t1 VALUES ('node2_committed_before');
@@ -24,12 +22,9 @@
 +INSERT INTO t1 VALUES ('node2_committed_before');
 +COMMIT;
 +SET GLOBAL debug_dbug = 'd,sync.alter_opened_table';
-+connection node_1;
 +ALTER TABLE t1 ADD COLUMN f2 INTEGER;
-+connection node_2;
 +SET wsrep_sync_wait = 0;
 +Killing server ...
-+connection node_1;
 +SET AUTOCOMMIT=OFF;
 +START TRANSACTION;
 +INSERT INTO t1 (f1) VALUES ('node1_committed_during');
@@ -44,7 +39,6 @@
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
-+connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1;
 +SET AUTOCOMMIT=OFF;
 +START TRANSACTION;
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
@@ -52,9 +46,7 @@
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
-+connection node_2;
 +Performing --wsrep-recover ...
-+connection node_2;
 +Starting server ...
 +Using --wsrep-start-position when starting mysqld ...
 +SET AUTOCOMMIT=OFF;
@@ -65,7 +57,6 @@
 +INSERT INTO t1 (f1) VALUES ('node2_committed_after');
 +INSERT INTO t1 (f1) VALUES ('node2_committed_after');
 +COMMIT;
-+connection node_1;
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
@@ -80,7 +71,6 @@
 +INSERT INTO t1 (f1) VALUES ('node1_committed_after');
 +INSERT INTO t1 (f1) VALUES ('node1_committed_after');
 +COMMIT;
-+connection node_1a_galera_st_kill_slave_ddl;
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
 +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
@@ -98,7 +88,6 @@
 +1
 +COMMIT;
 +SET AUTOCOMMIT=ON;
-+connection node_1;
 +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
 +COUNT(*) = 2
 +1
@@ -112,6 +101,6 @@
 +COMMIT;
 +SET AUTOCOMMIT=ON;
 +SET GLOBAL debug_dbug = $debug_orig;
- connection node_1;
  CALL mtr.add_suppression("Slave SQL: Error 'The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement' on query");
  DROP USER sst;
+ CALL mtr.add_suppression("Slave SQL: Error 'The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement' on query");
diff --git a/mysql-test/suite/galera/r/galera_kill_applier.result b/mysql-test/suite/galera/r/galera_kill_applier.result
index fe4911639ed..89f8ead0b65 100644
--- a/mysql-test/suite/galera/r/galera_kill_applier.result
+++ b/mysql-test/suite/galera/r/galera_kill_applier.result
@@ -1,4 +1,8 @@
+CREATE USER foo at localhost;
+GRANT SELECT on test.* TO foo at 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 at localhost;
diff --git a/mysql-test/suite/galera/t/galera_kill_applier.test b/mysql-test/suite/galera/t/galera_kill_applier.test
index e14a8b9af23..48a411d2cf2 100644
--- a/mysql-test/suite/galera/t/galera_kill_applier.test
+++ b/mysql-test/suite/galera/t/galera_kill_applier.test
@@ -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 at localhost;
+GRANT SELECT on test.* TO foo at 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,50 @@
 --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
+
+--disable_query_log
+--eval KILL $applier_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 $aborter_thread
+--enable_query_log
+
+--source include/restart_mysqld.inc
+
+--connection node_2
+
+--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 at localhost;
+
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 3f6ce8356ce..83278559a9c 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -8297,11 +8297,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;


More information about the commits mailing list