Bug #72896 mysql_upgrade calls mysqlcheck again after flush privileges
Submitted: 6 Jun 2014 7:32 Modified: 10 Jun 2014 9:02
Reporter: Peiran Song Email Updates:
Status: Analyzing Impact on me:
None 
Category:MySQL Server: Installing Severity:S3 (Non-critical)
Version:5.6.17 OS:Any
Assigned to: CPU Architecture:Any

[6 Jun 2014 7:32] Peiran Song
Description:
During upgrade, mysql_upgrade should be able to run successfully against the new server started with --skip-grant-tables. In 5.6, this feature is broken. The problem seems that mysqlcheck is invoked again after flush privileges. 

Output from failed run on 5.6.17
-----------------------------
$ ./mysql_upgrade --defaults-file=/path/to/my.sandbox.cnf --verbose
Looking for 'mysql' as: ./mysql
Looking for 'mysqlcheck' as: ./mysqlcheck
Running 'mysqlcheck' with connection arguments: '--port=56171' '--socket=/tmp/mysql_sandbox56171.sock'
Running 'mysqlcheck' with connection arguments: '--port=56171' '--socket=/tmp/mysql_sandbox56171.sock'
mysql.columns_priv OK
...
mysql.time_zone_transition_type OK
mysql.user OK
Running 'mysql_fix_privilege_tables'...
Running 'mysqlcheck' with connection arguments: '--port=56171' '--socket=/tmp/mysql_sandbox56171.sock'
./mysqlcheck: Got error: 1045: Access denied for user 'root'@'localhost' (using password: NO) when trying to connect
FATAL ERROR: Upgrade failed

Output from successful run on 5.5.37:
-------------------------------
Looking for 'mysql' as: ./mysql
Looking for 'mysqlcheck' as: ./mysqlcheck
Running 'mysqlcheck' with connection arguments: '--port=5537' '--socket=/tmp/mysql_sandbox5537.sock'
Running 'mysqlcheck' with connection arguments: '--port=5537' '--socket=/tmp/mysql_sandbox5537.sock'
mysql.columns_priv OK
... ...
mysql.user OK
test.a OK
test.company OK
Running 'mysql_fix_privilege_tables'...
OK

How to repeat:
- Install a 5.6.17 sandbox
- Install a 5.5.37 sandbox
- Stop both servers
- Copy 5.5.37 data dir to 5.6.17 data dir
- Start 5.6.17 with --skip-grant-tables
- Run the mysql_upgrade from the 5.6.17 bin directory. Comment out user/password in my.cnf file.
[9 Jun 2014 12:12] Umesh Shastry
Hello Peiran,

Thank you for the report.
I didn't see this issue when upgrading from 5.5.38 to 5.6.17 and to 5.6.20.
Could you please tell me how you are starting 5.6? Also, pass on the conf file you are using for both 5.5.x and 5.6.17.

// 5.5.38 -> 5.6.20

(1) Stopped, 5.5.38, 5.6.20's datadir pointed to the one used in 5.5.38, started with

bin/mysqld_safe --defaults-file=/path/to/my.cnf --skip-grant-tables --user=<user_Name> &

[root@cluster-repo mysql-advanced-5.6.20]# bin/mysql_upgrade --defaults-file=./my.cnf --verbose
Looking for 'mysql' as: bin/mysql
Looking for 'mysqlcheck' as: bin/mysqlcheck
Running 'mysqlcheck with default connection arguments
Running 'mysqlcheck with default connection arguments
mysql.columns_priv                                 OK
mysql.db                                           OK
mysql.event                                        OK
mysql.func                                         OK
mysql.general_log                                  OK
mysql.help_category                                OK
mysql.help_keyword                                 OK
mysql.help_relation                                OK
mysql.help_topic                                   OK
mysql.host                                         OK
mysql.innodb_index_stats                           OK
mysql.innodb_table_stats                           OK
mysql.ndb_binlog_index                             OK
mysql.plugin                                       OK
mysql.proc                                         OK
mysql.procs_priv                                   OK
mysql.proxies_priv                                 OK
mysql.servers                                      OK
mysql.slave_master_info                            OK
mysql.slave_relay_log_info                         OK
mysql.slave_worker_info                            OK
mysql.slow_log                                     OK
mysql.tables_priv                                  OK
mysql.time_zone                                    OK
mysql.time_zone_leap_second                        OK
mysql.time_zone_name                               OK
mysql.time_zone_transition                         OK
mysql.time_zone_transition_type                    OK
mysql.user                                         OK
Running 'mysql_fix_privilege_tables'...
Running 'mysqlcheck with default connection arguments
Running 'mysqlcheck with default connection arguments
test.t1                                            OK
OK

// 5.5.38 -> 5.6.17

[root@cluster-repo mysql-5.6.17]# bin/mysql_upgrade --defaults-file=./my.cnf --verbose
Looking for 'mysql' as: bin/mysql
Looking for 'mysqlcheck' as: bin/mysqlcheck
Running 'mysqlcheck with default connection arguments
Running 'mysqlcheck with default connection arguments
mysql.columns_priv                                 OK
mysql.db                                           OK
mysql.event                                        OK
mysql.func                                         OK
mysql.general_log                                  OK
mysql.help_category                                OK
mysql.help_keyword                                 OK
mysql.help_relation                                OK
mysql.help_topic                                   OK
mysql.host                                         OK
mysql.innodb_index_stats                           OK
mysql.innodb_table_stats                           OK
mysql.ndb_binlog_index                             OK
mysql.plugin                                       OK
mysql.proc                                         OK
mysql.procs_priv                                   OK
mysql.proxies_priv                                 OK
mysql.servers                                      OK
mysql.slave_master_info                            OK
mysql.slave_relay_log_info                         OK
mysql.slave_worker_info                            OK
mysql.slow_log                                     OK
mysql.tables_priv                                  OK
mysql.time_zone                                    OK
mysql.time_zone_leap_second                        OK
mysql.time_zone_name                               OK
mysql.time_zone_transition                         OK
mysql.time_zone_transition_type                    OK
mysql.user                                         OK
Running 'mysql_fix_privilege_tables'...
Running 'mysqlcheck with default connection arguments
Running 'mysqlcheck with default connection arguments
test.t1                                            OK
OK
============

Thanks,
Umesh
[10 Jun 2014 8:28] Peiran Song
Hi Umesh,

Thanks for testing. The reason that your command succeeded was that you likely have user/password stored in ./my.cnf file. Though grant table was back in effect, the mysqlcheck was still able to connect with the stored credential. 
 
If you don't specify defaults file, for example, run the program as "root", you will see the error. One note, your mysql "root" user's password must not be empty to be able to fail the connection. 

If you compare the mysql_upgrade output from 5.5 and 5.6, you will notice that with 5.5, mysqlcheck is only called at the beginning of mysql_upgrade, while with 5.6, it was called again after Running 'mysql_fix_privilege_tables'. The problem is that at that time, "flush privileges" has been issued and grant table is back in effect. 

It is ok if mysql_upgrade requires a defaults file to define user/password, but that would be a new thing in 5.6 and better to be specified in the manual, I think. 

Thanks,
Peiran
[1 Dec 2014 15:13] Shannon Wade
See also http://bugs.mysql.com/bug.php?id=40717 for similar behavior

flush privs turns on grant checking  with skip-grant-tables