From 1b7c5dedf7266d73c9c402cefee681251aea1e18 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Wed, 24 Aug 2016 15:32:48 -0400 Subject: [PATCH] MDEV-10566: Create role statement replicated inconsistently in Galera Cluster In galera cluster, the definer (and thus binlog invoker) must be set for CREATE ROLE before Query_log_event is created during TOI on the originating node. --- mysql-test/suite/galera/r/galera_roles.result | 41 ++++++++++++++++++- mysql-test/suite/galera/t/galera_roles.test | 32 +++++++++++++++ sql/sql_class.cc | 4 ++ sql/wsrep_mysqld.cc | 6 +++ 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/galera/r/galera_roles.result b/mysql-test/suite/galera/r/galera_roles.result index c0cdbc0e338..d8c13758797 100644 --- a/mysql-test/suite/galera/r/galera_roles.result +++ b/mysql-test/suite/galera/r/galera_roles.result @@ -69,8 +69,8 @@ SET ROLE role1; FLUSH TABLES; SELECT * FROM mysql.roles_mapping; Host User Role Admin_option - role1 Y localhost foo role1 N +localhost root role1 Y SHOW TABLES FROM test1; Tables_in_test1 t1 @@ -153,4 +153,43 @@ role1 # Connect with node_1 DROP USER foo@localhost; DROP DATABASE test1; +# +# MDEV-10566: Create role statement replicated inconsistently in Galera Cluster +# + +# On node_1 +CREATE USER foo@localhost; +CREATE ROLE role1; +CREATE ROLE role2 WITH ADMIN CURRENT_USER; +CREATE ROLE role3 WITH ADMIN foo@localhost; +CREATE ROLE role4 WITH ADMIN role1; +SELECT * FROM mysql.roles_mapping; +Host User Role Admin_option + role1 role4 Y +localhost foo role3 Y +localhost root role1 Y +localhost root role2 Y +SELECT * FROM INFORMATION_SCHEMA.APPLICABLE_ROLES; +GRANTEE ROLE_NAME IS_GRANTABLE +role1 role4 YES +root@localhost role1 YES +root@localhost role2 YES + +# On node_2 +SELECT * FROM mysql.roles_mapping; +Host User Role Admin_option + role1 role4 Y +localhost foo role3 Y +localhost root role1 Y +localhost root role2 Y +SELECT * FROM INFORMATION_SCHEMA.APPLICABLE_ROLES; +GRANTEE ROLE_NAME IS_GRANTABLE +role1 role4 YES +root@localhost role1 YES +root@localhost role2 YES +DROP ROLE role1; +DROP ROLE role2; +DROP ROLE role3; +DROP ROLE role4; +DROP USER foo@localhost; # End of test diff --git a/mysql-test/suite/galera/t/galera_roles.test b/mysql-test/suite/galera/t/galera_roles.test index f9a15126e5e..16e417d1fdb 100644 --- a/mysql-test/suite/galera/t/galera_roles.test +++ b/mysql-test/suite/galera/t/galera_roles.test @@ -163,5 +163,37 @@ disconnect foo_node_2; DROP USER foo@localhost; DROP DATABASE test1; +--echo # +--echo # MDEV-10566: Create role statement replicated inconsistently in Galera Cluster +--echo # +--echo +--echo # On node_1 +--connection node_1 +CREATE USER foo@localhost; +CREATE ROLE role1; +CREATE ROLE role2 WITH ADMIN CURRENT_USER; +CREATE ROLE role3 WITH ADMIN foo@localhost; +CREATE ROLE role4 WITH ADMIN role1; + +--sorted_result +SELECT * FROM mysql.roles_mapping; +--sorted_result +SELECT * FROM INFORMATION_SCHEMA.APPLICABLE_ROLES; + +--echo +--echo # On node_2 +--connection node_2 +--sorted_result +SELECT * FROM mysql.roles_mapping; +--sorted_result +SELECT * FROM INFORMATION_SCHEMA.APPLICABLE_ROLES; + +# Cleanup +DROP ROLE role1; +DROP ROLE role2; +DROP ROLE role3; +DROP ROLE role4; +DROP USER foo@localhost; + --source include/galera_end.inc --echo # End of test diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 37bacc986f7..76f8b98c55e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5249,7 +5249,11 @@ void THD::get_definer(LEX_USER *definer, bool role) { binlog_invoker(role); #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) +#ifdef WITH_WSREP + if ((wsrep_applier || slave_thread) && has_invoker()) +#else if (slave_thread && has_invoker()) +#endif { definer->user = invoker_user; definer->host= invoker_host; diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 91a9a1f210d..4117d5231f4 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1236,6 +1236,12 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_, case SQLCOM_ALTER_EVENT: buf_err= wsrep_alter_event_query(thd, &buf, &buf_len); break; + case SQLCOM_CREATE_ROLE: + if (sp_process_definer(thd)) + { + WSREP_WARN("Failed to set CREATE ROLE definer for TOI."); + } + /* fallthrough */ default: buf_err= wsrep_to_buf_helper(thd, thd->query(), thd->query_length(), &buf, &buf_len);