TL;DR
sql_mode= NO_AUTO_CREATE_USERが指定されている時にCREATE USERせずにGRANT ..で直接ユーザーを作ろうとしたSET PASSWORD FOR user@host = ..で存在しないユーザーのパスワードを変更しようとしたmysql.user.pluginのカラムが空文字列のアカウントにGRANTやALTER USERをかけようとしたmysql.userテーブルにINSERTなりUPDATEなりをした後、FLUSH PRIVILEDGESをしていないのでアカウントとして認識されていない
sql_mode= NO_AUTO_CREATE_USERが指定されている時にCREATE USERせずにGRANT ..で直接ユーザーを作ろうとした
昔、「MySQLのアカウントは
GRANT ステートメントで作るんだよ」って教えられたような気がするんだけど、それはもう過去の話になってしまったようだ。
MySQL 5.7とそれ以降はデフォルトの sql_mode に
NO_AUTO_CREATE_USER が指定されており、これが有効だと「存在しないアカウントに対する GRANT 」が転けるようになる。
先に
CREATE USER でアカウントを作ってから GRANT するか、sql_modeから NO_AUTO_CREATE_USER を取り除いてやれるかばいいんだけど、MySQL 8.0.11とそれ以降では sql_mode からそもそも NO_AUTO_CREATE_USER が なくなっており 、今後常に「存在しないアカウントに対する GRANT 」は転け続けるので、sql_modeから取り除く方はお勧めしない。SET PASSWORD FOR user@host = ..で存在しないユーザーのパスワードを変更しようとした
これはエラーメッセージそのまま。ユーザーテーブル(=
mysql.user のこと)に行が見つからないよ、ってこと。mysql.user.pluginのカラムが空文字列のアカウントにGRANTやALTER USERをかけようとした
MySQL 5.5とそれ以降では
mysql.user テーブルに plugin というカラムが追加されていて、はここに「どのプラグインを使ってユーザー認証をするか」(パスワードハッシュ形式を指定したり、ソケット認証とかPAM認証とかを指定したりする)を記録する。
5.5, 5.6ではNULLABLEで空文字列許可だったけれど5.7から先はここが空っぽだとくだんのエラーで転けるようになる。
本来
本来
plugin を変更するために使える ALTER USER ステートメントも失敗するようになるので、 mysql.user.plugin を UPDATE して FLUSH PRIVILEGES することになる。mysql57 4> SELECT plugin FROM mysql.user WHERE user = 'yoku0825';
+--------+
| plugin |
+--------+
| |
+--------+
1 row in set (0.00 sec)
mysql57 4> GRANT SELECT ON *.* TO yoku0825;
ERROR 1133 (42000): Can't find any matching row in the user table
mysql57 4> UPDATE mysql.user SET plugin = 'mysql_native_password' WHERE user = 'yoku0825';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql57 4> SELECT plugin FROM mysql.user WHERE user = 'yoku0825';
+-----------------------+
| plugin |
+-----------------------+
| mysql_native_password |
+-----------------------+
1 row in set (0.00 sec)
mysql57 4> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql57 4> GRANT SELECT ON *.* TO yoku0825;
Query OK, 0 rows affected (0.00 sec)
mysql.userテーブルにINSERTなりUPDATEなりをした後、FLUSH PRIVILEDGESをしていないのでアカウントとして認識されていない
mysqldump --all-databases からのリストアにありがちなこと。mysql.user テーブルへの更新ステートメントはACLを更新しないので、リストアして再起動も FLUSH PRIVILEGES も叩かないと mysql.user 上には存在するけどACL上には存在しないので (;・3・) アルェ ってなるやつになったりする。mysql.user テーブルと、実際に認証に使われるACLの関係については↓の アカウント情報と mysql.user テーブルの同期 のあたりで詳しく(?)解説しています。
( ´-`).oO(結構前の記事だけど割と的を射てると思う…おきにいり。
0 件のコメント :
コメントを投稿