Description:
I notice when doing an upgrade that the latest version is stored in $datadir/mysql_upgrade_info
mysql_upgrade seems to _require_ write access to this file yet everything else it does it does unless I'm mistaken by talking to the mysqld process.
How to repeat:
Upgrading 5.7.5 to 5.7.6 gave me:
I ran sudo mysql_upgrade rather than mysql_upgrade as root and see:
...
mydb.table1 OK
mydb.table2 OK
mydb.table3 OK
mydb.table4 OK
mydb.table5 OK
sys.sys_config
Warning : Trigger sys.sys_config.sys_config_update_set_user does not have CREATED attribute.
Warning : Trigger sys.sys_config.sys_config_insert_set_user does not have CREATED attribute.
status : OK
sys.truncation_time OK
Upgrade process completed successfully.
Could not create the upgrade info file '/path/to/datadir/mysql_upgrade_info' in the MySQL Servers datadir, errno: 13
[myuser@myhost ~]$ perror 13
OS error code 13: Permission denied
[myuser@myhost ~]$ sudo /etc/init.d/mysqld restart
Stopping mysqld: [ OK ]
Starting mysqld: [ OK ]
[myuser@myhost ~]$ ls -la /path/to/datadir/mysql_upgrade_info
-rw-r--r-- 1 mysql mysql 23 Jan 28 12:39 /path/to/datadir/mysql_upgrade_info
[myuser@myhost ~]$
For what it's worth this is running on:
CentOS 6.5, mysql-community-server-5.7.6
Suggested fix:
A quick look at the mysql_upgrade(1) man page does not make it clear that _file_ access is required to the server. The non-root user _did_ have full MySQL access to the server and the upgrade process worked fine. So it's just access to this particular file that failed.
Suggestion: add the mysql upgrade information to a mysql table. (MyISAM so it doesn't have to be transactional?)
Append the latest upgrade run to the end of the table.
Probably include the server's hostname to give some sort of reference to which server was updated.
I clone servers a lot so this mysql table would probably end up with different server names depending on when the upgrade took place and that history could be useful. So I'd like to see:
CREATE TABLE mysql_upgrade_log (
upgrade_timestamp timestamp
upgrade_version varchar(50) # to take into account any special version numbers
hostname varchar(64)
upgrade_status int / or varchar to indicate if the process ran and if it worked
upgrade_comment
datadir varchar(64) # handy maybe ?
The "root" MySQL user should always be able to create this table (if missing) in the mysql db and then insert a new run when the mysql_upgrade process has run.
Failing that _check_ you have all needed permissions prior to starting and alert the DBA if you don't.