はじめに
開発環境にDockerを導入しようとして、なんやらかんやらいじっていたら、タイトルのエラーが出るようになってしまいました。
具体的には、以下のようなことをすると、タイトルのエラーメッセージが表示されるようになりました。
・rails serverを起動して、ローカルにアクセスする
・MySQLを起動してshow databasesなどのクエリを実行する
mysql> show databases;
the user specified as a definer ('mysql.infoschema'@'localhost') does not exist
今回は、このエラーを解決するまでの手順と、その途中で出くわした問題などを、自分の備忘録として、かつ同じ問題に遭遇した方へ少しでも助けになれるようにと思い、書き残していきます。
「mysql.infoschema'@'localhost」というユーザーを作成する
最初に、「the user specified as a definer ('mysql.infoschema'@'localhost') does not exist」というエラーをググってみると、どうやら 「mysql.infoschema'@'localhost」というユーザーが存在しないこと が原因であるため、 「mysql.infoschema'@'localhost」を作成し、権限を付与する ことで解決しそうだとわかりました。
そこで、
https://stackoverflow.com/questions/62127983/error-1449-hy000-the-user-specified-as-a-definer-mysql-infoschemalocalho
を参考に、まずは「mysql.infoschema’@‘localhost」というユーザーを作成しました。
mysql -u root -p
でログインし、
mysql> use mysql;
Database changed
データベースを変更し、
mysql> CREATE USER 'mysql.infoschema'@'localhost' IDENTIFIED BY 'password';
ユーザーを作成します。
*passwordは各自で変更して下さい
ところが、次に権限を付与しようとすると
mysql> GRANT SELECT ON *.* TO `mysql.infoschema`@`localhost`;
access denied for user 'root'@'localhost' (using password: yes)
というエラーが発生し、権限の付与ができませんでした、、、
新たな問題1 「mysql.infoschema'@'localhost」に権限が付与できない
access denied for user 'root'@'localhost' (using password: yes)
というエラーは様々な場面で出てくるようですが、今回の状況では、rootユーザーが「他のユーザーに権限を付与するための権限」を持っていないことが原因らしいとわかりました。(Dockerを導入しようとしていろいろといじっているうちに、rootユーザーの削除・再作成などをやってしまったのかもしれません、、、)
そのため、まずは rootユーザーに「権限を付与するための権限」を与える ことにしました。
セーフモードでMySQLを起動しrootユーザーに権限を付与する
https://killtime.blog/revive-deleted-root-user-on-mysql8/
上記のサイトを参考にさせていただきました。
rootユーザーに権限を付与するためには、権限を無視するセーフモードで起動する必要があるようなので、まずはセーフモードでMySQLを起動します。
mysqld_safe --skip-grant-tables
**ちなみに、私の場合はこの時点で
mysqld_safe A mysqld process already exists
というエラーが発生し、MySQLが起動できませんでした、、、
詳細は後述しますので、同じ問題に直面した方はそちらをご参照ください。
次に、
mysql> use mysql;
Database changed
でデータベースを変更し、
mysql> select* from user;
で各ユーザーの状態を確認しました。
すると、rootユーザーの「権限を付与するための権限であろう Grant_priv」がNとなっていたため、
mysql> update user set Grant_priv = "Y" where user = “root";
でrootユーザーに権限を付与しました。
mysql> update user set Grant_priv = "Y" where user = "root";
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
最後に、
mysql> flush privileges;
で変更を反映させ、一度quitでMysqlから抜けました。
新たな問題2 セーフモードでMySQLを起動することができない
先程の手順の中で、
mysqld_safe --skip-grant-tables
によってMySQLをセーフモードで実行するところがありましたが、その際に私のケースでは
mysqld_safe A mysqld process already exists
というエラーが発生し、MySQLを起動することができませんでした。
調べてみたところ、 以前に起動したmysqldのプロセスが残っていることが原因とのことでした。
そこで、
ps aux | grep mysqld
で実行中のmysqldに関するプロセスを取得し、
kill -9 プロセスid
でプロセスを強制終了させた後、再度
mysqld_safe --skip-grant-tables
を実行することで、セーフモードで起動することができました。
今後もこのようなことが起こらないために、最後にセーフモードのプロセスを終了させることを忘れないよう心に刻みます。
新たな問題3 MySQLに接続できない
rootユーザーへの権限付与が完了したので、rootユーザーでログイン後に「mysql.infoschema'@'localhost」に権限を付与しようとして
mysql -u root -p
を実行したところ、
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
というエラーが出て、MySQLに接続することができませんでした。
ところがこの問題の原因は単純で、 単にMySQLサーバーが起動していないだけでした、、、おそらく、mysqldに関するプロセスを終了させる際に、サーバーも停止してしまったのではないかと思います。
そこで、
mysql.server start
mysql -u root -p
を実行することで無事にログインができました。
mysql.infoschema’@‘localhostに権限を付与する
MySQLに接続し、この時点でshow databases;などのクエリを実行したところ、
mysql> show databases;
ERROR 1356 (HY000): View 'information_schema.SCHEMATA' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
というエラーが発生しました。
当初の
mysql> show databases;
the user specified as a definer ('mysql.infoschema'@'localhost') does not exist
というエラーからは変化しているので、「mysql.infoschema'@'localhost」というユーザーが存在しないという問題は解決できているようですが、「mysql.infoschema'@'localhost」に権限が付与されていないという問題が残っているようです。
そこで、
mysql> GRANT SELECT ON *.* TO `mysql.infoschema`@`localhost`;
で「mysql.infoschema'@'localhost」に権限を付与します。
mysql> GRANT SELECT ON *.* TO `mysql.infoschema`@`localhost`;
Query OK, 0 rows affected (0.01 sec)
この時点で、show tablesなどのクエリを実行すると、無事にテーブル一覧が表示されるようになりました!
また、rails serverを起動してローカルに接続することにも成功しました!
最後に、残っているセーフモードのプロセスを終了させます。
ps aux | grep mysqld
kill -9 プロセスid
おわりに
以上が「the user specified as a definer ('mysql.infoschema'@'localhost') does not exist」というエラーを解決するまでの手順になります。
間違っているところやおかしな部分などがありましたら、ぜひお教えください。
この記事が少しでもお役に立てることを願っています。ご覧いただきありがとうございました。