Bug #78085 Documentation says CURRENT_USER is expanded when it's not
Submitted: 15 Aug 2015 17:27 Modified: 17 Apr 2018 10:01
Reporter: Elena Stepanova Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Replication Severity:S3 (Non-critical)
Version:5.1, 5.5, 5.6, 5.7 OS:Any
Assigned to: CPU Architecture:Any

[15 Aug 2015 17:27] Elena Stepanova
Description:
https://dev.mysql.com/doc/refman/5.6/en/replication-features-current-user.html

<quote>
 CURRENT_USER() or CURRENT_USER is also expanded prior to being written to the binary log when used in DROP USER, RENAME USER, GRANT, REVOKE, or ALTER EVENT.
</quote>

Partial binlog contents from the test case in 'How to repeat' section on 5.6:

| wheezy-64-bin.000001 |  697 | Query       |         1 |         817 | use `test`; grant select on db.* to current_user                                  |
| wheezy-64-bin.000001 |  817 | Query       |         1 |         940 | use `test`; revoke select on db.* from current_user                               |
| wheezy-64-bin.000001 |  940 | Query       |         1 |        1076 | use `test`; SET PASSWORD FOR 'u1'@'%'='*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29' |
| wheezy-64-bin.000001 | 1076 | Query       |         1 |        1187 | use `test`; rename user current_user to u2                                        |
| wheezy-64-bin.000001 | 1187 | Query       |         1 |        1298 | use `test`; rename user u2 to current_user                                        |
| wheezy-64-bin.000001 | 1298 | Query       |         1 |        1401 | use `test`; drop user current_user                                                |

... and on 5.7:

| wheezy-64-bin.000001 |  606 | Anonymous_Gtid |         1 |         671 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                   |
| wheezy-64-bin.000001 |  671 | Query          |         1 |         789 | use `test`; GRANT SELECT ON `db`.* TO 'u1'@'%'                                                                         |
| wheezy-64-bin.000001 |  789 | Anonymous_Gtid |         1 |         854 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                   |
| wheezy-64-bin.000001 |  854 | Query          |         1 |         977 | use `test`; revoke select on db.* from current_user                                                                    |
| wheezy-64-bin.000001 |  977 | Anonymous_Gtid |         1 |        1042 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                   |
| wheezy-64-bin.000001 | 1042 | Query          |         1 |        1215 | use `test`; ALTER USER 'u1'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29' |
| wheezy-64-bin.000001 | 1215 | Anonymous_Gtid |         1 |        1280 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                   |
| wheezy-64-bin.000001 | 1280 | Query          |         1 |        1391 | use `test`; rename user current_user to u2                                                                             |
| wheezy-64-bin.000001 | 1391 | Anonymous_Gtid |         1 |        1456 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                   |
| wheezy-64-bin.000001 | 1456 | Query          |         1 |        1567 | use `test`; rename user u2 to current_user                                                                             |
| wheezy-64-bin.000001 | 1567 | Anonymous_Gtid |         1 |        1632 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                   |
| wheezy-64-bin.000001 | 1632 | Query          |         1 |        1735 | use `test`; drop user current_user                                                                                 

So, in 5.6 CURRENT_USER is only expanded in SET PASSWORD, in all other statements it goes into the binary log as is. 

In 5.7, it's also expanded for GRANT (or rather, original GRANT is substituted by a generated event); but for other statements it is not. 

It still replicates all right, some internal magic allows to work with the right CURRENT_USER; but replaying the binlog via mysqlbinlog => mysql breaks the contents. 

Maybe it's just a documentation issue (then please re-qualify it as such), although not being able to restore from the binlog is sad. 

How to repeat:
--source include/master-slave.inc
--source include/have_binlog_format_mixed.inc

--enable_connect_log

create user u1;
grant all on *.* to u1 with grant option;

--connect(con1,localhost,u1,,)

grant select on db.* to current_user;
revoke select on db.* from current_user;
set password for current_user = password('test');
rename user current_user to u2;
rename user u2 to current_user;
select current_user;
drop user current_user;

show binlog events;

--disconnect con1

--connection master

select user, host from mysql.user;

--sync_slave_with_master

select user, host from mysql.user;
[17 Aug 2015 9:16] MySQL Verification Team
Hello Elena,

Thank you for the report.
Observed this with 5.6.26, 5.7.9 and 5.8.0.

Thanks,
Umesh
[17 Apr 2018 10:01] Margaret Fisher
Posted by developer:
 
Changed final paragraph to read

 When binary logging is enabled and CURRENT_USER() or CURRENT_USER is used as the definer in any of these statements, MySQL Server ensures that the statement is applied to the same user on both the master and the slave when the statement is replicated. In some cases, such as statements that change passwords, the function reference is expanded before it is written to the binary log, so that the statement includes the user name. For all other cases, the name of the current user on the master is replicated to the slave as metadata, and the slave applies the statement to the current user named in the metadata, rather than to the current user on the slave.