MySQL で誰にも GRANT がなくなってしまった場合の対処方法(Ubuntu 16.04 LTS)

結論(概略)

mysqld_safeで起動してrootでログインし、権限を付与する。

具体的手順

順を追って手順を見ていきましょう。

1. 現在動いている MySQL を止める

止めないとどうしようもないので止めます。

$ sudo service mysql stop

2. MySQL をセーフモード、かつ、権限を無視するモードで立ち上げる

以下のようにしてMySQLを実行し直します。裏側で動かすために最後に & をつけてやります。

$ mysqld_safe --skip-grant-tables &
2-補足. もし /var/run/mysqld が存在しないと怒られたら

上記のmysqld_safeの実行時に/var/run/mysqldが存在しないと怒られることがあります*1。そのときは以下のようにして/var/run/mysqldを作ります。

$ sudo mkdir -p /var/run/mysqld
$ sudo chown mysql:mysql /var/run/mysqld/

3. root でログインする

無事MySQLがセーフモードで起ち上がったらrootでログインしましょう。

$ mysql -u root

4. use mysql と実行して、使用するデータベースを mysql にする

MySQLのコマンドラインにログインできたらまずはuse mysqlを実行して、使用するデータベース(操作する対象のデータベース)としてmysqlを選択しましょう。

mysql> use mysql
Database changed

5. UPDATE コマンドで権限を付与する(権限一覧の確認)

あとはrootに対して権限を付与するだけです。まず、権限一覧は以下のとおりです。SELECT * FROM mysql.user WHERE User='root' \Gというコマンドで確認できます。

mysql> SELECT * FROM mysql.user WHERE User='root' \G
*************************** 1. row ***************************
                  Host: 127.0.0.1
                  User: root
           Select_priv: Y
           Insert_priv: Y
           Update_priv: Y
           Delete_priv: Y
           Create_priv: Y
             Drop_priv: Y
           Reload_priv: Y
         Shutdown_priv: Y
          Process_priv: Y
             File_priv: Y
            Grant_priv: Y
       References_priv: Y
            Index_priv: Y
            Alter_priv: Y
          Show_db_priv: Y
            Super_priv: Y
 Create_tmp_table_priv: Y
      Lock_tables_priv: Y
          Execute_priv: Y
       Repl_slave_priv: Y
      Repl_client_priv: Y
      Create_view_priv: Y
        Show_view_priv: Y
   Create_routine_priv: Y
    Alter_routine_priv: Y
      Create_user_priv: Y
            Event_priv: Y
          Trigger_priv: Y
Create_tablespace_priv: Y
              ssl_type:
            ssl_cipher:
           x509_issuer:
          x509_subject:
         max_questions: 0
           max_updates: 0
       max_connections: 0
  max_user_connections: 0
                plugin: mysql_native_password
 authentication_string: foobar
      password_expired: N
 password_last_changed: 2000-01-01 12:00:00
     password_lifetime: NULL
        account_locked: N
1 row in set (0.00 sec)

mysql>

上記の表示では全ての権限が Y となっています。しかし権限が適切に付与されていない場合は N が並ぶと思います。

6. UPDATE コマンドで権限を付与する(UPDATE コマンドを実行)

権限一覧が分かったので、UPDATE コマンドで権限を付与します。以下のようになります。ここでは全権限を付与しているので長ったらしくなっていますが、全ての権限に Y とセットしているだけです。

mysql> UPDATE user SET Select_priv='Y',Insert_priv='Y',Update_priv='Y',Delete_priv='Y',Create_priv='Y',Drop_priv='Y',Reload_priv='Y',Shutdown_priv='Y',Process_priv='Y',File_priv='Y',Grant_priv='Y',References_priv='Y',Index_priv='Y',Alter_priv='Y',Show_db_priv='Y',Super_priv='Y',Create_tmp_table_priv='Y',Lock_tables_priv='Y',Execute_priv='Y',Repl_slave_priv='Y',Repl_client_priv='Y',Create_view_priv='Y',Show_view_priv='Y',Create_routine_priv='Y',Alter_routine_priv='Y',Create_user_priv='Y',Event_priv='Y',Trigger_priv='Y',Create_tablespace_priv='Y' WHERE User='root';

最後に念のためFLUSH PRIVILEGESして反映させます。

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

7. MySQL のセーフモードを終了させる

「6.」で正常にコマンドが実行されれば権限は復活したはずです。MySQLのコマンドラインから抜けてセーフモードでの起動を終了し、改めて通常モードでMySQLを起動し直しましょう。

まずはMySQLのコマンドラインから抜けます。

mysql > exit
Bye

セーフモードで起動しているMySQLを止めます。実行ファイル名はmysqld_safeです。psコマンドでプロセスを見つけてkillしましょう。

$ ps aux | grep mysqld_safe

上記コマンドで2つのプロセスがヒットするかと思いますので、そのプロセスをkillします。

$ sudo kill -9 プロセス番号

8. MySQL を通常モードで起動する

セーフモードのプロセスを全てkillできたならば、通常どおりにMySQLを起動します。

$ sudo service mysql start

9. root でログインすれば権限が復活している

あとはrootでログインすれば権限が復活しているはずです。

補足

ある日、なぜそうなったのかは不明ですが*2、気がつくとrootGRANTできなくなっていました。

自分自身にGRANT権限を与えることは、そもそも自分自身がGRANTできないので不可能という、「鶏が先か卵が先か」状態になっており、もはやMySQLの再インストールしか無いのかと絶望していました。

しかしながら、この方法で復活できました。

*1:私は怒られました

*2:「いつのまにか動かなくなって~」と同じで、とてもよろしくないセリフ

Powered by はてなブログ