From 39cc31b3077e245128f36293abb6e4c03faf6b65 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Jun 2007 14:24:31 +0200 Subject: [PATCH 1/2] BUG#29030 (DROP USER command that errors still gets written to binary log and replicated): A DROP USER statement with a non-existing user was correctly written to the binary log (there might be users that were removed, but not all), but the error code was not set, which caused the slave to stop with an error. The error reporting code was moved to before the statement was logged to ensure that the error information for the thread was correctly set up. This works since my_error() will set the fields net.last_errno and net.last_error for the thread that is reporting the error, and this will then be picked up when the Query_log_event is created and written to the binary log. sql/sql_acl.cc: Moving error reporting code to ensure that thd->net.last_err{or,no} is set and adding debug printout. mysql-test/r/rpl_grant.result: New BitKeeper file ``mysql-test/r/rpl_grant.result'' mysql-test/t/rpl_grant.test: New BitKeeper file ``mysql-test/t/rpl_grant.test'' --- mysql-test/r/rpl_grant.result | 77 +++++++++++++++++++++++++++++++++++ mysql-test/t/rpl_grant.test | 38 +++++++++++++++++ sql/sql_acl.cc | 8 +++- 3 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/rpl_grant.result create mode 100644 mysql-test/t/rpl_grant.test diff --git a/mysql-test/r/rpl_grant.result b/mysql-test/r/rpl_grant.result new file mode 100644 index 00000000000..7610deca51a --- /dev/null +++ b/mysql-test/r/rpl_grant.result @@ -0,0 +1,77 @@ +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; +**** On Master **** +CREATE USER dummy@localhost; +CREATE USER dummy1@localhost, dummy2@localhost; +SELECT user, host FROM mysql.user; +user host +root 127.0.0.1 +dummy localhost +dummy1 localhost +dummy2 localhost +root localhost +root romeo.kindahl.net +**** On Slave **** +SELECT user,host FROM mysql.user; +user host +root 127.0.0.1 +dummy localhost +dummy1 localhost +dummy2 localhost +root localhost +root romeo.kindahl.net +**** On Master **** +DROP USER nonexisting@localhost; +ERROR HY000: Operation DROP USER failed for 'nonexisting'@'localhost' +DROP USER nonexisting@localhost, dummy@localhost; +ERROR HY000: Operation DROP USER failed for 'nonexisting'@'localhost' +DROP USER dummy1@localhost, dummy2@localhost; +SELECT user, host FROM mysql.user; +user host +root 127.0.0.1 +root localhost +root romeo.kindahl.net +**** On Slave **** +SELECT user,host FROM mysql.user; +user host +root 127.0.0.1 +root localhost +root romeo.kindahl.net +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 609 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 609 +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # diff --git a/mysql-test/t/rpl_grant.test b/mysql-test/t/rpl_grant.test new file mode 100644 index 00000000000..592cf7630da --- /dev/null +++ b/mysql-test/t/rpl_grant.test @@ -0,0 +1,38 @@ +# Tests of grants and users + +source include/master-slave.inc; +source include/not_embedded.inc; + +--echo **** On Master **** +connection master; + +CREATE USER dummy@localhost; +CREATE USER dummy1@localhost, dummy2@localhost; + +SELECT user, host FROM mysql.user; +sync_slave_with_master; +--echo **** On Slave **** +SELECT user,host FROM mysql.user; + +--echo **** On Master **** +connection master; + +# No user exists +error ER_CANNOT_USER; +DROP USER nonexisting@localhost; + +# At least one user exists, but not all +error ER_CANNOT_USER; +DROP USER nonexisting@localhost, dummy@localhost; + +# All users exist +DROP USER dummy1@localhost, dummy2@localhost; + +SELECT user, host FROM mysql.user; +sync_slave_with_master; +--echo **** On Slave **** +SELECT user,host FROM mysql.user; + +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 8 # 9 # 23 # 33 # +query_vertical SHOW SLAVE STATUS; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index cae1f6eb243..f9bd2c6ba0d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5378,6 +5378,12 @@ bool mysql_drop_user(THD *thd, List &list) VOID(pthread_mutex_unlock(&acl_cache->lock)); + if (result) + my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe()); + + DBUG_PRINT("info", ("thd->net.last_errno: %d", thd->net.last_errno)); + DBUG_PRINT("info", ("thd->net.last_error: %s", thd->net.last_error)); + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); @@ -5386,8 +5392,6 @@ bool mysql_drop_user(THD *thd, List &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); - if (result) - my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe()); DBUG_RETURN(result); } From 8b3c5753c7961297d43a5fd87481bca06bcc245d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Jun 2007 16:55:52 +0200 Subject: [PATCH 2/2] Test fix --- mysql-test/r/rpl_grant.result | 32 ++++++++++++++++---------------- mysql-test/t/rpl_grant.test | 12 ++++++++---- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/mysql-test/r/rpl_grant.result b/mysql-test/r/rpl_grant.result index 7610deca51a..4d7ad298ce4 100644 --- a/mysql-test/r/rpl_grant.result +++ b/mysql-test/r/rpl_grant.result @@ -7,40 +7,40 @@ start slave; **** On Master **** CREATE USER dummy@localhost; CREATE USER dummy1@localhost, dummy2@localhost; -SELECT user, host FROM mysql.user; +SELECT user, host FROM mysql.user WHERE user != 'root'; user host -root 127.0.0.1 dummy localhost dummy1 localhost dummy2 localhost -root localhost -root romeo.kindahl.net +SELECT COUNT(*) FROM mysql.user; +COUNT(*) +6 **** On Slave **** -SELECT user,host FROM mysql.user; +SELECT user,host FROM mysql.user WHERE user != 'root'; user host -root 127.0.0.1 dummy localhost dummy1 localhost dummy2 localhost -root localhost -root romeo.kindahl.net +SELECT COUNT(*) FROM mysql.user; +COUNT(*) +6 **** On Master **** DROP USER nonexisting@localhost; ERROR HY000: Operation DROP USER failed for 'nonexisting'@'localhost' DROP USER nonexisting@localhost, dummy@localhost; ERROR HY000: Operation DROP USER failed for 'nonexisting'@'localhost' DROP USER dummy1@localhost, dummy2@localhost; -SELECT user, host FROM mysql.user; +SELECT user, host FROM mysql.user WHERE user != 'root'; user host -root 127.0.0.1 -root localhost -root romeo.kindahl.net +SELECT COUNT(*) FROM mysql.user; +COUNT(*) +3 **** On Slave **** -SELECT user,host FROM mysql.user; +SELECT user,host FROM mysql.user WHERE user != 'root'; user host -root 127.0.0.1 -root localhost -root romeo.kindahl.net +SELECT COUNT(*) FROM mysql.user; +COUNT(*) +3 SHOW SLAVE STATUS; Slave_IO_State # Master_Host 127.0.0.1 diff --git a/mysql-test/t/rpl_grant.test b/mysql-test/t/rpl_grant.test index 592cf7630da..71e36342584 100644 --- a/mysql-test/t/rpl_grant.test +++ b/mysql-test/t/rpl_grant.test @@ -9,10 +9,12 @@ connection master; CREATE USER dummy@localhost; CREATE USER dummy1@localhost, dummy2@localhost; -SELECT user, host FROM mysql.user; +SELECT user, host FROM mysql.user WHERE user != 'root'; # root host non-determ +SELECT COUNT(*) FROM mysql.user; sync_slave_with_master; --echo **** On Slave **** -SELECT user,host FROM mysql.user; +SELECT user,host FROM mysql.user WHERE user != 'root'; # root host non-determ +SELECT COUNT(*) FROM mysql.user; --echo **** On Master **** connection master; @@ -28,10 +30,12 @@ DROP USER nonexisting@localhost, dummy@localhost; # All users exist DROP USER dummy1@localhost, dummy2@localhost; -SELECT user, host FROM mysql.user; +SELECT user, host FROM mysql.user WHERE user != 'root'; # root host non-determ +SELECT COUNT(*) FROM mysql.user; sync_slave_with_master; --echo **** On Slave **** -SELECT user,host FROM mysql.user; +SELECT user,host FROM mysql.user WHERE user != 'root'; # root host non-determ +SELECT COUNT(*) FROM mysql.user; --replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 8 # 9 # 23 # 33 #