Bug #29030 DROP USER command that errors still gets written to binary log and replicated
Submitted: 11 Jun 2007 20:59 Modified: 23 Jul 2007 20:16
Reporter: Chris Calender Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Replication Severity:S2 (Serious)
Version:5.0 OS:Any
Assigned to: Mats Kindahl
Tags: bfsm_2007_06_21, binary log, binlog, drop user, replicated, replication

[11 Jun 2007 20:59] Chris Calender
Description:
If you issue a DROP USER command that returns an error (i.e., user does not exist), it still gets written to the binary log and replicated, which breaks replication.

How to repeat:
Make sure you do not have a user called 'xxx' @ 'localhost'

Then try to drop that user with binary logging enabled and/or replication going.

DROP USER 'xxx'@'localhost';
ERROR 1396 (HY000): Operation DROP USER failed for 'xxx'@'localhost'

You'll see it is written to the binary log.

And SHOW SLAVE STATUS:

Error 'Operation DROP USER failed for 'xxx'@'localhost'' on query. Default database: ''. Query: 'drop user 'xxx'@'localhost''

Suggested fix:
Well, after a review of the code, it appears that this is in place because DROP USER can accept more than 1 user, and the logic is that some could fail, while some could succeed.

So I suggest that a check be done whether the command is executed or not, and then write it to the binlog accordingly.
[20 Jun 2007 12:24] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/29184

ChangeSet@1.2494, 2007-06-20 14:24:31+02:00, mats@kindahl-laptop.dnsalias.net +3 -0
  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.
[21 Jun 2007 20:12] Bugs System
Pushed into 5.0.46
[21 Jun 2007 20:15] Bugs System
Pushed into 5.1.20-beta
[3 Jul 2007 13:02] Lars Thalmann
Sinisa, it should properly drop things in exactly the same manner on
slave as on master, provided that they have same info.  The error code
from master will be shipped to slave and the slave must generate
exactly the same error code.  It if doesn't then the slave will stop.

Verifier, can you please verify that:
1. The same bug does not exist for CREATE USER.
2. That slave drops the user in the way it should on the slave.
[9 Jul 2007 5:24] Mats Kindahl
Sinisa,

The test case supplied as part of the patch above contain three versions of the DROP USER command: one with no user existing, one with one existing and one non-existing, and one with all users existing.

There is no test for CREATE USER as part of this bug.
[23 Jul 2007 20:16] Paul Dubois
Noted in 5.0.46, 5.1.20 changelogs.

DROP USER statements that named multiple users, only some of which
could be dropped, were replicated incorrectly.