List:Commits« Previous MessageNext Message »
From:Luis Soares Date:July 23 2010 3:07pm
Subject:bzr push into mysql-next-mr-bugfixing branch (luis.soares:3323 to 3324)
View as plain text  
 3324 Luis Soares	2010-07-23 [merge]
      BUG 54866: automerge bzr bundle from bug report into mysql-next-mr-bugfixing.

    modified:
      mysql-test/suite/rpl/r/rpl_do_grant.result
      mysql-test/suite/rpl/r/rpl_grant.result
      mysql-test/suite/rpl/t/rpl_grant.test
      sql/sql_acl.cc
 3323 Tor Didriksen	2010-07-23
      Bug #55434 multithreaded gunit tests fail on windows
      
      On windows we need an open handle to the thread in order to join it.
     @ unittest/gunit/thread_utils.cc
        On windows: keep an open handle to a thread in order to join it safely.
        
        Use mysql_xxx() wrappers for pthread_xxx() functions.
     @ unittest/gunit/thread_utils.h
        Use mysql_mutex_t/mysql_cond_t rather than pthread_mutex_t/pthread_cond_t

    modified:
      unittest/gunit/thread_utils.cc
      unittest/gunit/thread_utils.h
=== modified file 'mysql-test/suite/rpl/r/rpl_do_grant.result'
--- a/mysql-test/suite/rpl/r/rpl_do_grant.result	2010-05-23 20:41:18 +0000
+++ b/mysql-test/suite/rpl/r/rpl_do_grant.result	2010-07-20 09:24:47 +0000
@@ -258,6 +258,5 @@ ERROR HY000: Can't revoke all privileges
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 master-bin.000001	#	Query	#	#	use `test`; grant all on *.* to foo@"1.2.3.4"
-master-bin.000001	#	Query	#	#	use `test`; revoke all privileges, grant option from "foo"
 DROP USER foo@"1.2.3.4";
 "End of test"

=== modified file 'mysql-test/suite/rpl/r/rpl_grant.result'
--- a/mysql-test/suite/rpl/r/rpl_grant.result	2010-06-22 09:34:59 +0000
+++ b/mysql-test/suite/rpl/r/rpl_grant.result	2010-07-20 09:26:49 +0000
@@ -41,3 +41,144 @@ user	host
 SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%';
 COUNT(*)
 0
+##########
+########## setup (PART I)
+##########
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE DATABASE b54866 ;
+use b54866;
+CREATE TABLE t1 ( c1 INT, c2 INT, c3 INT );
+##########
+########## GRANT ALL
+##########
+CREATE USER 'b54866_user'@'localhost';
+GRANT ALL ON b54866.* TO 'b54866_user'@'localhost';
+REVOKE ALL ON b54866.* FROM 'b54866_user'@'localhost', 'b54866_fake_user';
+ERROR 42000: There is no such grant defined for user 'b54866_fake_user' on host '%'
+****** Checking grants on the master for user: b54866_user ******
+SHOW GRANTS FOR 'b54866_user'@'localhost';
+Grants for b54866_user@localhost
+GRANT USAGE ON *.* TO 'b54866_user'@'localhost'
+*************************************************************
+****** Checking grants on the slave for user: b54866_user *******
+SHOW GRANTS FOR 'b54866_user'@'localhost';
+Grants for b54866_user@localhost
+GRANT USAGE ON *.* TO 'b54866_user'@'localhost'
+*************************************************************
+CREATE TABLE test.t2 ( i INT );
+CREATE TRIGGER test.tr AFTER INSERT ON test.t2 FOR EACH ROW INSERT INTO b54866.t1 VALUES (new.i);
+INSERT INTO test.t2 VALUES (1);
+ERROR 42000: INSERT command denied to user 'b54866_user'@'localhost' for table 't1'
+##########
+########## TABLE GRANTS
+##########
+GRANT ALTER,CREATE,DROP ON TABLE b54866.t1 TO 'b54866_user'@'localhost';
+****** Checking grants on the master for user: b54866_user ******
+SHOW GRANTS FOR 'b54866_user'@'localhost';
+Grants for b54866_user@localhost
+GRANT USAGE ON *.* TO 'b54866_user'@'localhost'
+GRANT CREATE, DROP, ALTER ON `b54866`.`t1` TO 'b54866_user'@'localhost'
+*************************************************************
+****** Checking grants on the slave for user: b54866_user *******
+SHOW GRANTS FOR 'b54866_user'@'localhost';
+Grants for b54866_user@localhost
+GRANT USAGE ON *.* TO 'b54866_user'@'localhost'
+GRANT CREATE, DROP, ALTER ON `b54866`.`t1` TO 'b54866_user'@'localhost'
+*************************************************************
+REVOKE ALTER ON TABLE b54866.t1 FROM 'b54866_user'@'localhost', 'b54866_fake_user';
+ERROR 42000: There is no such grant defined for user 'b54866_fake_user' on host '%'
+****** Checking grants on the master for user: b54866_user ******
+SHOW GRANTS FOR 'b54866_user'@'localhost';
+Grants for b54866_user@localhost
+GRANT USAGE ON *.* TO 'b54866_user'@'localhost'
+GRANT CREATE, DROP ON `b54866`.`t1` TO 'b54866_user'@'localhost'
+*************************************************************
+****** Checking grants on the slave for user: b54866_user *******
+SHOW GRANTS FOR 'b54866_user'@'localhost';
+Grants for b54866_user@localhost
+GRANT USAGE ON *.* TO 'b54866_user'@'localhost'
+GRANT CREATE, DROP ON `b54866`.`t1` TO 'b54866_user'@'localhost'
+*************************************************************
+##########
+########## setup (PART II)
+##########
+CREATE PROCEDURE b54866_p() BEGIN SELECT 1; END|
+CREATE FUNCTION b54866_f() RETURNS INT BEGIN RETURN 1; END|
+GRANT EXECUTE ON PROCEDURE b54866.b54866_p TO 'b54866_user'@'localhost';
+GRANT EXECUTE ON FUNCTION b54866.b54866_f TO 'b54866_user'@'localhost';
+****** Checking grants on the master for user: b54866_user ******
+SHOW GRANTS FOR 'b54866_user'@'localhost';
+Grants for b54866_user@localhost
+GRANT USAGE ON *.* TO 'b54866_user'@'localhost'
+GRANT CREATE, DROP ON `b54866`.`t1` TO 'b54866_user'@'localhost'
+GRANT EXECUTE ON PROCEDURE `b54866`.`b54866_p` TO 'b54866_user'@'localhost'
+GRANT EXECUTE ON FUNCTION `b54866`.`b54866_f` TO 'b54866_user'@'localhost'
+*************************************************************
+****** Checking grants on the slave for user: b54866_user *******
+SHOW GRANTS FOR 'b54866_user'@'localhost';
+Grants for b54866_user@localhost
+GRANT USAGE ON *.* TO 'b54866_user'@'localhost'
+GRANT CREATE, DROP ON `b54866`.`t1` TO 'b54866_user'@'localhost'
+GRANT EXECUTE ON PROCEDURE `b54866`.`b54866_p` TO 'b54866_user'@'localhost'
+GRANT EXECUTE ON FUNCTION `b54866`.`b54866_f` TO 'b54866_user'@'localhost'
+*************************************************************
+##########
+########## PROCEDURE
+##########
+#### PROCEDURE ASSERTION
+REVOKE EXECUTE ON PROCEDURE b54866.b54866_p FROM 'b54866_user'@'localhost', 'b54866_fake_user';
+ERROR 42000: There is no such grant defined for user 'b54866_fake_user' on host '%'
+****** Checking grants on the master for user: b54866_user ******
+SHOW GRANTS FOR 'b54866_user'@'localhost';
+Grants for b54866_user@localhost
+GRANT USAGE ON *.* TO 'b54866_user'@'localhost'
+GRANT CREATE, DROP ON `b54866`.`t1` TO 'b54866_user'@'localhost'
+GRANT EXECUTE ON FUNCTION `b54866`.`b54866_f` TO 'b54866_user'@'localhost'
+*************************************************************
+****** Checking grants on the slave for user: b54866_user *******
+SHOW GRANTS FOR 'b54866_user'@'localhost';
+Grants for b54866_user@localhost
+GRANT USAGE ON *.* TO 'b54866_user'@'localhost'
+GRANT CREATE, DROP ON `b54866`.`t1` TO 'b54866_user'@'localhost'
+GRANT EXECUTE ON FUNCTION `b54866`.`b54866_f` TO 'b54866_user'@'localhost'
+*************************************************************
+##########
+########## FUNCTION
+##########
+REVOKE EXECUTE ON FUNCTION b54866.b54866_f FROM 'b54866_user'@'localhost', 'b54866_fake_user';
+ERROR 42000: There is no such grant defined for user 'b54866_fake_user' on host '%'
+****** Checking grants on the master for user: b54866_user ******
+SHOW GRANTS FOR 'b54866_user'@'localhost';
+Grants for b54866_user@localhost
+GRANT USAGE ON *.* TO 'b54866_user'@'localhost'
+GRANT CREATE, DROP ON `b54866`.`t1` TO 'b54866_user'@'localhost'
+*************************************************************
+****** Checking grants on the slave for user: b54866_user *******
+SHOW GRANTS FOR 'b54866_user'@'localhost';
+Grants for b54866_user@localhost
+GRANT USAGE ON *.* TO 'b54866_user'@'localhost'
+GRANT CREATE, DROP ON `b54866`.`t1` TO 'b54866_user'@'localhost'
+*************************************************************
+##########
+########## empty revokes should not be binlogged
+##########
+REVOKE EXECUTE ON PROCEDURE b54866_p FROM 'fake_user'@'localhost';
+ERROR 42000: There is no such grant defined for user 'fake_user' on host 'localhost'
+REVOKE EXECUTE ON FUNCTION b54866_f FROM 'fake_user'@'localhost';
+ERROR 42000: There is no such grant defined for user 'fake_user' on host 'localhost'
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'fake_user'@'localhost';
+ERROR HY000: Can't revoke all privileges for one or more of the requested users
+### No binary log entries were detected for empty revoke operations
+##########
+########## Cleanup
+##########
+DROP PROCEDURE b54866_p;
+DROP FUNCTION b54866_f;
+DROP TABLE test.t2;
+DROP USER 'b54866_user'@'localhost';
+DROP DATABASE b54866;

=== modified file 'mysql-test/suite/rpl/t/rpl_grant.test'
--- a/mysql-test/suite/rpl/t/rpl_grant.test	2010-05-24 13:54:08 +0000
+++ b/mysql-test/suite/rpl/t/rpl_grant.test	2010-07-16 14:17:07 +0000
@@ -36,3 +36,209 @@ sync_slave_with_master;
 --echo **** On Slave ****
 SELECT user,host FROM mysql.user WHERE user like 'dummy%';
 SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%';
+
+
+######################################################
+
+#
+# BUG#54866: Partially failed REVOKE not binlogged, causes inconsistency or replication abort
+#
+
+--echo ##########
+--echo ########## setup (PART I)
+--echo ##########
+-- connection master
+-- source include/master-slave-reset.inc
+-- connection master
+
+--let $dbname= b54866
+--let $dbuser= b54866_user
+
+--eval CREATE DATABASE $dbname 
+--eval use $dbname
+CREATE TABLE t1 ( c1 INT, c2 INT, c3 INT );
+
+--echo ##########
+--echo ########## GRANT ALL
+--echo ##########
+
+## create user, grant and revoke (the last command fails partially)
+--eval CREATE USER '$dbuser'@'localhost'
+--eval GRANT ALL ON $dbname.* TO '$dbuser'@'localhost'
+--error ER_NONEXISTING_GRANT
+--eval REVOKE ALL ON $dbname.* FROM '$dbuser'@'localhost', 'b54866_fake_user'
+--sync_slave_with_master
+
+## assert that the slave did not fail: revoke grant event was logged
+## with the correct error # and when slave replays it, it runs into
+## the same error (so it is expected)
+-- source include/check_slave_no_error.inc
+
+## assert that grants are the same on master and on slave for $dbuser
+--connection master
+--echo ****** Checking grants on the master for user: $dbuser ******
+--eval SHOW GRANTS FOR '$dbuser'@'localhost'
+--echo *************************************************************
+
+--sync_slave_with_master
+--echo ****** Checking grants on the slave for user: $dbuser *******
+--eval SHOW GRANTS FOR '$dbuser'@'localhost'
+--echo *************************************************************
+
+## assert that query that fails on master because of revoked grant
+## will also fail on the slave (otherwise the slave would report
+## that the master logged the event with a failure #, but the it did
+## not run into the expected issue).
+##
+## This checks that partially revoked grants - due to master error - 
+## are revoked on the slave as well.
+--connect(con1,localhost,$dbuser,,)
+CREATE TABLE test.t2 ( i INT );
+--eval CREATE TRIGGER test.tr AFTER INSERT ON test.t2 FOR EACH ROW INSERT INTO $dbname.t1 VALUES (new.i)
+--error ER_TABLEACCESS_DENIED_ERROR
+INSERT INTO test.t2 VALUES (1);
+--disconnect con1
+
+--echo ##########
+--echo ########## TABLE GRANTS
+--echo ##########
+
+--connection master
+--eval GRANT ALTER,CREATE,DROP ON TABLE $dbname.t1 TO '$dbuser'@'localhost'
+--echo ****** Checking grants on the master for user: $dbuser ******
+--eval SHOW GRANTS FOR '$dbuser'@'localhost'
+--echo *************************************************************
+
+--sync_slave_with_master
+--echo ****** Checking grants on the slave for user: $dbuser *******
+--eval SHOW GRANTS FOR '$dbuser'@'localhost'
+--echo *************************************************************
+
+## revoke should now fail and partially succeed
+--connection master
+--error ER_NONEXISTING_GRANT
+## event must be logged with the error ER_NONEXISTING_GRANT
+--eval REVOKE ALTER ON TABLE $dbname.t1 FROM '$dbuser'@'localhost', 'b54866_fake_user'
+
+## assert that ALTER grant is revoked on slave and slave does not stop
+--connection master
+--echo ****** Checking grants on the master for user: $dbuser ******
+--eval SHOW GRANTS FOR '$dbuser'@'localhost'
+--echo *************************************************************
+
+--sync_slave_with_master
+--echo ****** Checking grants on the slave for user: $dbuser *******
+--eval SHOW GRANTS FOR '$dbuser'@'localhost'
+--echo *************************************************************
+
+## assert that the slave did not fail: revoke grant event was logged
+## with the correct error # and when slave replays it, it runs into
+## the same error (so it is expected)
+-- source include/check_slave_no_error.inc
+
+--echo ##########
+--echo ########## setup (PART II)
+--echo ##########
+
+-- connection master
+DELIMITER |;
+CREATE PROCEDURE b54866_p() BEGIN SELECT 1; END|
+CREATE FUNCTION b54866_f() RETURNS INT BEGIN RETURN 1; END|
+DELIMITER ;|
+
+--eval GRANT EXECUTE ON PROCEDURE $dbname.b54866_p TO '$dbuser'@'localhost'
+--eval GRANT EXECUTE ON FUNCTION $dbname.b54866_f TO '$dbuser'@'localhost'
+
+--echo ****** Checking grants on the master for user: $dbuser ******
+--eval SHOW GRANTS FOR '$dbuser'@'localhost'
+--echo *************************************************************
+
+--sync_slave_with_master
+--echo ****** Checking grants on the slave for user: $dbuser *******
+--eval SHOW GRANTS FOR '$dbuser'@'localhost'
+--echo *************************************************************
+
+--echo ##########
+--echo ########## PROCEDURE
+--echo ##########
+
+-- connection master
+
+-- echo #### PROCEDURE ASSERTION
+--error ER_NONEXISTING_GRANT
+--eval REVOKE EXECUTE ON PROCEDURE $dbname.b54866_p FROM '$dbuser'@'localhost', 'b54866_fake_user'
+
+## assert that ALTER grant is revoked on slave and slave does not stop
+--echo ****** Checking grants on the master for user: $dbuser ******
+--eval SHOW GRANTS FOR '$dbuser'@'localhost'
+--echo *************************************************************
+
+--sync_slave_with_master
+--echo ****** Checking grants on the slave for user: $dbuser *******
+--eval SHOW GRANTS FOR '$dbuser'@'localhost'
+--echo *************************************************************
+-- source include/check_slave_no_error.inc
+
+--echo ##########
+--echo ########## FUNCTION
+--echo ##########
+-- connection master
+
+--error ER_NONEXISTING_GRANT
+--eval REVOKE EXECUTE ON FUNCTION $dbname.b54866_f FROM '$dbuser'@'localhost', 'b54866_fake_user'
+
+## assert that ALTER grant is revoked on slave and slave does not stop
+--connection master
+--echo ****** Checking grants on the master for user: $dbuser ******
+--eval SHOW GRANTS FOR '$dbuser'@'localhost'
+--echo *************************************************************
+
+--sync_slave_with_master
+--echo ****** Checking grants on the slave for user: $dbuser *******
+--eval SHOW GRANTS FOR '$dbuser'@'localhost'
+--echo *************************************************************
+-- source include/check_slave_no_error.inc
+
+--echo ##########
+--echo ########## empty revokes should not be binlogged
+--echo ##########
+
+-- connection master
+
+## assert that failing revoke on non existing user will not 
+## be binlogged
+-- let $current_log_pos_before= query_get_value(SHOW MASTER STATUS, Position, 1)
+-- error ER_NONEXISTING_GRANT
+REVOKE EXECUTE ON PROCEDURE b54866_p FROM 'fake_user'@'localhost';
+-- error ER_NONEXISTING_GRANT
+REVOKE EXECUTE ON FUNCTION b54866_f FROM 'fake_user'@'localhost';
+-- error ER_REVOKE_GRANTS
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'fake_user'@'localhost';
+-- let $current_log_pos_after= query_get_value(SHOW MASTER STATUS, Position, 1)
+
+if (`SELECT $current_log_pos_after - $current_log_pos_before`)
+{
+  -- source include/show_rpl_debug_info.inc
+  -- die 
+}
+
+if (!`SELECT $current_log_pos_after - $current_log_pos_before`)
+{
+  --echo ### No binary log entries were detected for empty revoke operations
+}
+
+## there should be nothing to left to sync, but anyway
+-- sync_slave_with_master
+## assert that the slave is not stopped
+-- source include/check_slave_no_error.inc
+
+--echo ##########
+--echo ########## Cleanup
+--echo ##########
+--connection master
+DROP PROCEDURE b54866_p;
+DROP FUNCTION b54866_f;
+DROP TABLE test.t2;
+--eval DROP USER '$dbuser'@'localhost'
+--eval DROP DATABASE $dbname
+--sync_slave_with_master

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2010-07-16 21:00:50 +0000
+++ b/sql/sql_acl.cc	2010-07-20 09:24:47 +0000
@@ -3040,6 +3040,7 @@ int mysql_table_grant(THD *thd, TABLE_LI
   bool create_new_users=0;
   char *db_name, *table_name;
   bool save_binlog_row_based;
+  bool should_write_to_binlog= FALSE;
   DBUG_ENTER("mysql_table_grant");
 
   if (!initialized)
@@ -3213,6 +3214,15 @@ int mysql_table_grant(THD *thd, TABLE_LI
       continue;					// Add next user
     }
 
+    /*
+      Some operations below can fail and are not undone.
+      As such, we play it safe and log the statement with
+      an error to give a chance to the slave to replay this
+      statement and fail as well, hoping that it will also
+      get the same side effects.
+     */
+    should_write_to_binlog= TRUE;
+
     db_name= table_list->get_db_name();
     table_name= table_list->get_table_name();
 
@@ -3295,11 +3305,9 @@ int mysql_table_grant(THD *thd, TABLE_LI
   thd->mem_root= old_root;
   mysql_mutex_unlock(&acl_cache->lock);
 
-  if (!result) /* success */
-  {
-    result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
-  }
-
+  if (should_write_to_binlog)
+    result= result |
+            write_bin_log(thd, FALSE, thd->query(), thd->query_length());
   mysql_rwlock_unlock(&LOCK_grant);
 
   if (!result) /* success */
@@ -3339,7 +3347,7 @@ bool mysql_routine_grant(THD *thd, TABLE
   TABLE_LIST tables[2];
   bool create_new_users=0, result=0;
   char *db_name, *table_name;
-  bool save_binlog_row_based;
+  bool save_binlog_row_based, should_write_to_binlog= FALSE;
   DBUG_ENTER("mysql_routine_grant");
 
   if (!initialized)
@@ -3474,11 +3482,17 @@ bool mysql_routine_grant(THD *thd, TABLE
       result= TRUE;
       continue;
     }
+
+    /*
+      Even if there is an error, we should write to binary log.
+     */
+    should_write_to_binlog= TRUE;
+
   }
   thd->mem_root= old_root;
   mysql_mutex_unlock(&acl_cache->lock);
 
-  if (write_to_binlog)
+  if (write_to_binlog && should_write_to_binlog)
   {
     if (write_bin_log(thd, FALSE, thd->query(), thd->query_length()))
       result= TRUE;
@@ -3504,6 +3518,7 @@ bool mysql_grant(THD *thd, const char *d
   bool create_new_users=0;
   TABLE_LIST tables[2];
   bool save_binlog_row_based;
+  bool should_write_to_binlog= FALSE;
   DBUG_ENTER("mysql_grant");
   if (!initialized)
   {
@@ -3612,13 +3627,17 @@ bool mysql_grant(THD *thd, const char *d
 	result= -1;
       }
     }
+
+    /*
+      Even if there is an error, we should write to binary log.
+     */
+    should_write_to_binlog= TRUE;
   }
   mysql_mutex_unlock(&acl_cache->lock);
 
-  if (!result)
-  {
-    result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
-  }
+  if (should_write_to_binlog)
+    result= result |
+            write_bin_log(thd, FALSE, thd->query(), thd->query_length());
 
   mysql_rwlock_unlock(&LOCK_grant);
   close_thread_tables(thd);
@@ -6135,7 +6154,7 @@ bool mysql_revoke_all(THD *thd,  List <L
   int result;
   ACL_DB *acl_db;
   TABLE_LIST tables[GRANT_TABLES];
-  bool save_binlog_row_based;
+  bool save_binlog_row_based, should_write_to_binlog= FALSE;
   DBUG_ENTER("mysql_revoke_all");
 
   /*
@@ -6180,6 +6199,11 @@ bool mysql_revoke_all(THD *thd,  List <L
       continue;
     }
 
+    /*
+      Even if there is an error, we should write to binary log.
+     */
+    should_write_to_binlog= TRUE;
+
     /* Remove db access privileges */
     /*
       Because acl_dbs and column_priv_hash shrink and may re-order
@@ -6300,8 +6324,11 @@ bool mysql_revoke_all(THD *thd,  List <L
   if (result)
     my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
 
-  result= result |
-    write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+  if (should_write_to_binlog)
+  {
+    result= result |
+      write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+  }
 
   mysql_rwlock_unlock(&LOCK_grant);
   close_thread_tables(thd);


Attachment: [text/bzr-bundle] bzr/luis.soares@sun.com-20100723150507-9yzyye4b3hegvn31.bundle
Thread
bzr push into mysql-next-mr-bugfixing branch (luis.soares:3323 to 3324)Luis Soares23 Jul