Commit 39cc31b3 authored by unknown's avatar unknown

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''
parent 7969b6a6
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 #
# 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;
...@@ -5378,6 +5378,12 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) ...@@ -5378,6 +5378,12 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
VOID(pthread_mutex_unlock(&acl_cache->lock)); 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()) if (mysql_bin_log.is_open())
{ {
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
...@@ -5386,8 +5392,6 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) ...@@ -5386,8 +5392,6 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
rw_unlock(&LOCK_grant); rw_unlock(&LOCK_grant);
close_thread_tables(thd); close_thread_tables(thd);
if (result)
my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe());
DBUG_RETURN(result); DBUG_RETURN(result);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment