Hatena::ブログ(Diary)

【はてな】ガットポンポコ RSSフィード


2009-09-10

MySQL 一度DELETEしたuserと同じ名前のuserを登録しようとすると失敗する

うーん。MySQLのバグなんだろうか、一度DELETEしたuserと同じ名前のuserを登録しようとすると失敗する。

やったことはこう。

DELETE 構文で user 'boss' を削除する。

mysql> DELETE FROM mysql.user WHERE user='boss' and host='localhost';

CREATE USER 構文で boss を再度作ろうとしたが、失敗。

mysql> CREATE USER 'boss'@'localhost' IDENTIFIED BY 'password';
ERROR 1396 (HY000): Operation CREATE USER failed for 'boss'@'localhost'

MySQLクイック・リファレンスによると、

本来のユーザ削除はこうらしい。先にREVOKEをやらなかったからいけないのかな?

REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'boss'@'localhost';
DELETE FROM mysql.user WHERE user='boss' and host='localhost';
FLUSH PRIVILEGES;

REVOKE 構文を後からやってみたが、REVOKEに失敗する。

mysql> REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'boss'@'localhost';
ERROR 1269 (HY000): Can't revoke all privileges for one or more of the requested users

困った。

ERROR 1396 (HY000)で検索したら、MySQLのbugレポートに同じ現象が投稿してあった。

http://bugs.mysql.com/bug.php?id=28331

Actually, after more frustrated testing, it seems that the real cause isn't a reserved

word - it seems to be a latent entry in the mysql.db table for a user that has been

removed from the mysql.user table.

mysql.db を調べてみる

SELECT * FROM mysql.db WHERE User='boss' G;
 *************************** 1. row ***************************
                 Host: localhost
                   Db: boss
                 User: boss
          Select_priv: Y
          Insert_priv: Y
          Update_priv: Y
          Delete_priv: Y
          Create_priv: Y
            Drop_priv: Y
           Grant_priv: N
      References_priv: Y
           Index_priv: Y
           Alter_priv: Y
Create_tmp_table_priv: Y
     Lock_tables_priv: Y
     Create_view_priv: Y
       Show_view_priv: Y
  Create_routine_priv: Y
   Alter_routine_priv: Y
         Execute_priv: Y
1 row in set (0.00 sec)

ERROR:
No query specified

確かに、mysql.db テーブルに boss ユーザが残っている。

同じページの投稿によると、 drop user でユーザ削除を行うとこのbugを回避できるらしい。

やってみる。

mysql> DROP USER boss@localhost;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM mysql.db WHERE User='boss' G;
Empty set (0.00 sec)

ERROR:
No query specified

お、できたかな。

mysql> CREATE USER 'boss'@'localhost' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)

できた。

う〜ん。以前は DELETE 文だけで削除できたような。

MySQLのリファレンスマニュアルを読む

システム管理者は、GRANT コマンドと REVOKE コマンドを使用して、ユーザを作成し、MySQL ユーザに対して次の 4 つのレベルの権限を与えたり取り消すことができます。

  • グローバルレベル グローバル権限は特定のサーバ上のすべてのデータベースに適用される。これらの権限は、mysql.user テーブルに保存される。 GRANT ALL ON *.* および REVOKE ALL ON *.* は、グローバル権限の付与および取り消しのみを行う。
  • データベースレベル データベース権限は、指定したデータベースのすべてのテーブルに適用される。これらの権限は、mysql.db テーブルおよび mysql.host テーブルに保存される。 GRANT ALL ON db.* および REVOKE ALL ON db.* は、データベース権限の付与および取り消しのみを行う。
  • テーブルレベル テーブル権限は、指定したテーブルのすべてのカラムに適用される。これらの権限は、mysql.tables_priv テーブルに保存される。 GRANT ALL ON db.table および REVOKE ALL ON db.table は、テーブル権限の付与および取り消しのみを行う。
  • カラムレベル カラム権限は、指定したテーブルの一つのカラムに適用される。これらの権限は、mysql.columns_priv テーブルに保存される。 REVOKE を使用する際は、対象となるカラムを指定することが必要である。

権限を細かく設定すればするほど、使われるテーブルが増えるのか。DELETE FROM mysql.user は当然 user テーブルからしかデータを削除しないけど、CREATE USER と DROP USER 構文は、ちゃんと他のテーブルも見てくれてるんだ。

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証