GA

2018/10/25

MySQLのエラーコード1133、ER_PASSWORD_NO_MATCH "Can't find any matching row in the user table" について

TL;DR

  • sql_mode= NO_AUTO_CREATE_USER が指定されている時に CREATE USER せずに GRANT .. で直接ユーザーを作ろうとした
  • SET PASSWORD FOR user@host = .. で存在しないユーザーのパスワードを変更しようとした
  • mysql.user.plugin のカラムが空文字列のアカウントに GRANTALTER USER をかけようとした
  • mysql.user テーブルに INSERT なり UPDATE なりをした後、 FLUSH PRIVILEDGES をしていないのでアカウントとして認識されていない

  • sql_mode= NO_AUTO_CREATE_USER が指定されている時に CREATE USER せずに GRANT .. で直接ユーザーを作ろうとした
昔、「MySQLのアカウントは GRANT ステートメントで作るんだよ」って教えられたような気がするんだけど、それはもう過去の話になってしまったようだ。
MySQL 5.7とそれ以降はデフォルトの sql_modeNO_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 のカラムが空文字列のアカウントに GRANTALTER USER をかけようとした
MySQL 5.5とそれ以降では mysql.user テーブルに plugin というカラムが追加されていて、はここに「どのプラグインを使ってユーザー認証をするか」(パスワードハッシュ形式を指定したり、ソケット認証とかPAM認証とかを指定したりする)を記録する。
5.5, 5.6ではNULLABLEで空文字列許可だったけれど5.7から先はここが空っぽだとくだんのエラーで転けるようになる。
本来 plugin を変更するために使える ALTER USER ステートメントも失敗するようになるので、 mysql.user.pluginUPDATE して 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 件のコメント :

コメントを投稿