Cope with failure to run MySQL on Rails application

When I upgraded MySQL version to 8.0.14 from 5.7, I faced with failure to operate for the database.

TL;DR

Solution:

  1. Re-install mysql2 gem.
  2. Run mysql_upgrade -u root -p

Environments

% echo $OSTYPE
darwin18.2.0
% mysql --version
mysql  Ver 8.0.14 for osx10.14 on x86_64 (Homebrew)
% bundle exec rails --version
Rails 5.2.2

What was happened?

After uprading MySQL 5.7 to 8.0 with homebrew, run rake db:migrate for my Rails application, then LoadError occurred as follows:

% bundle exec rake db:migrate
rake aborted!
LoadError: dlopen(/Users/akito/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2/lib/mysql2/mysql2.bundle, 9): Library not loaded: /usr/local/opt/mysql/lib/libmysqlclient.20.dylib
  Referenced from: /Users/akito/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2/lib/mysql2/mysql2.bundle
  Reason: image not found - /Users/akito/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2/lib/mysql2/mysql2.bundle
...

It seemed not to find libmysqlclient.20.dylib.

Then run command as follow:

% bundle doctor
...
The following gems are missing OS dependencies:
 * mysql2: /usr/local/opt/mysql/lib/libmysqlclient.20.dylib

Fix the problem

Literally, libmysqlclient is a client library for MySQL. This library communicates over a network connection.

libmysqlclient20 has been bundled with MySQL 5.7. You can confirm it when MySQL mirror page, for example, MySQL 5.7 mirror page

However, in MySQL 8.0, libmysql21 has been bundled: MySQL 8.0 mirror page

Both pages above have been hosted in Japan.

By the way, although libmysqlclient.so is for most UNIX sytems, .dylib is for macOS. As for the static link library of this is .a as the extension.

Anyway, I checked /usr/local/opt/mysql/lib, then I got:

% ll /usr/local/opt/mysql/lib
total 37616
drwxr-xr-x  14 akito  staff      448 Dec 21 05:31 ./
drwxr-xr-x  17 akito  staff      544 Feb  9 13:56 ../
-rw-r--r--   1 akito  staff  5419384 Feb  9 13:56 libmysqlclient.21.dylib
-r--r--r--   1 akito  staff  6052712 Dec 21 05:31 libmysqlclient.a
lrwxr-xr-x   1 akito  staff       23 Dec 21 05:31 libmysqlclient.dylib@ -> libmysqlclient.21.dylib
-rw-r--r--   1 akito  staff   565184 Feb  9 13:56 libmysqlharness.1.dylib
-r--r--r--   1 akito  staff  1060048 Dec 21 05:31 libmysqlharness.a
lrwxr-xr-x   1 akito  staff       23 Dec 21 05:31 libmysqlharness.dylib@ -> libmysqlharness.1.dylib
-r--r--r--   1 akito  staff  6140608 Feb  9 13:56 libmysqlrouter.1.dylib
lrwxr-xr-x   1 akito  staff       22 Dec 21 05:31 libmysqlrouter.dylib@ -> libmysqlrouter.1.dylib
-r--r--r--   1 akito  staff     9760 Dec 21 05:31 libmysqlservices.a
drwxr-xr-x   7 akito  staff      224 Dec 21 05:31 mysqlrouter/
drwxr-xr-x   3 akito  staff       96 Feb  9 13:56 pkgconfig/
drwxr-xr-x  98 akito  staff     3136 Dec 21 05:31 plugin/

It is true that the directory has libmysqlclient21 but does not have libmysqlclient20.

Hence, I tried to re-install mysql2 gem.

% gem uninstall mysql2
% bundle // I use it on project root of Rails app.
% bundle doctor
...
No issues found with the installed bundle

Error message was gone! Yet, another problem came up.

% bundle exec rake db:migrate
rake aborted!
ActiveRecord::StatementInvalid: Mysql2::Error: The user specified as a definer ('mysql.infoschema'@'localhost') does not exist: SELECT table_name FROM information_schema.tables WHERE table_schema = database() AND table_name = 'schema_migrations' AND table_type = 'BASE TABLE'
/Users/akito/.rbenv/versions/2.5.3/bin/bundle:23:in `load'
/Users/akito/.rbenv/versions/2.5.3/bin/bundle:23:in `<main>'

Caused by:
Mysql2::Error: The user specified as a definer ('mysql.infoschema'@'localhost') does not exist
/Users/akito/.rbenv/versions/2.5.3/bin/bundle:23:in `load'
/Users/akito/.rbenv/versions/2.5.3/bin/bundle:23:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

'mysql.infoschema'@'localhost' is a new user that has added since MySQL 8.0.4.

The release notes of MySQL 8.0.4 said:

If the MySQL root user account was renamed, a query that accessed an INFORMATION_SCHEMA view returned an error stating that the user specified as the definer does not exist. To avoid this error, a new system user account, ‘mysql.infoschema’@’localhost’, is now the DEFINER for INFORMATION_SCHEMA views. (Bug #25185947, Bug #84027)

I upgraded MySQL simply, so user information might be taken over from older MySQL.

Therefore, I ran mysql_upgrade.

% mysql_upgrade -u root -p
Enter password:
Checking if update is needed.
Checking server version.
Running queries to upgrade MySQL server.
Upgrading system table data.
Checking system database.
mysql.columns_priv                                 OK
mysql.component                                    OK
mysql.db                                           OK
mysql.default_roles                                OK
mysql.engine_cost                                  OK
mysql.func                                         OK
mysql.general_log                                  OK
mysql.global_grants                                OK
mysql.gtid_executed                                OK
mysql.help_category                                OK
mysql.help_keyword                                 OK
mysql.help_relation                                OK
mysql.help_topic                                   OK
mysql.innodb_index_stats                           OK
mysql.innodb_table_stats                           OK
mysql.ndb_binlog_index                             OK
mysql.password_history                             OK
mysql.plugin                                       OK
mysql.procs_priv                                   OK
mysql.proxies_priv                                 OK
mysql.role_edges                                   OK
mysql.server_cost                                  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
Found outdated sys schema version 1.5.1.
Upgrading the sys schema.
Checking databases.

... suspension points ...

sys.sys_config                                     OK
Upgrade process completed successfully.
Checking if update is needed.

Finally, I could run rake db:migrate!!

References


@a_ksi19 QR code
https://akito19.com/blog/2019/cope-with-failure-to-run-mysql-on-rails/
14-Feb-19
BY-NC-SA 4.0 https://akito19.com/disclosure
https://akito19.com/blog/2019/cope-with-failure-to-run-mysql-on-rails/
Older Newer