AR ホームベーカリー

オイラのアウトプット用ホームベーカリー!

MySQL の root パスワードが設定されている

ロケ地

  • macos 11 Big Sur
  • Homebrew
  • MySQL 8.0.22_1
  • ${USER} は自分のユーザ名に相当します

MySQL がこわれた

データベースの id が重複しているなど .err に出力されるようになり、確認するとたしかに直近で流した rails db:create で作成したデータベースと、以前から利用していたデータベースが競合している模様。 datadir 以下から影響度の小さいデータベースを直接 rm して一旦復旧したので、 mysqldump でデータベース毎にバックアップ取得して MySQL を再インストールすることにした。

再インストール

[user@localhost ~]$ mysql.server stop
[user@localhost ~]$ brew uninstall mysql
[user@localhost ~]$ brew update
[user@localhost ~]$ brew cleanup -s
[user@localhost ~]$ brew install mysql

mysql_secure_install が実行できない

インストールできたので mysql_secure_installation を流して初期設定をする。

[user@localhost ~]$ mysql.server start
[user@localhost ~]$ mysql_secure_installation
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

ええっ? おまえ brew install 終わったあとに「root にパスワード設定してないから mysql_secure_installation 流してパスワード設定しろ」って言ってたじゃねえか。 しょうがねえな、設定されてる以上ログに temporary なパスワード出てるはずだし確認すっか、なんだよもー。

[user@localhost ~]$ cd /usr/local/var/mysql/
[user@localhost ~]$ cat ./${ホスト名}.err

……あれ書いてない?!

どういうこと?

using password: YES と出ている以上、パスワードは設定されているはずで、しかしインストール完了の出力ではパスワードは設定してないという。 この場合、動いている動作が正しいのでインストール完了の出力は一旦嘘である (実はパスワード設定されている) という前提で調査します。

権限が悪い

${USER}:staff の一般ユーザではなく、 sudo つけて起動する (datadir は _mysql:_mysql に権限を変更する)。

[user@localhost ~]$ sudo chown -R _mysql:_mysql /usr/local/var/mysql/
[user@localhost ~]$ sudo mysql.server start
[user@localhost ~]$ sudo mysql_secure_installation
 .. ERROR! The server quit without updating PID file ()

そうですよね。権限によって動作しないとか、一貫して設定されてれば早々無いし。

物理的に再起動してみる

macos 自体を再起動してみる。

#=> macos 再起動
[user@localhost ~]$ sudo chown -R ${USER}:staff /usr/local/var/mysql/
[user@localhost ~]$ mysql.server start
[user@localhost ~]$ mysql_secure_installation
 .. ERROR! The server quit without updating PID file ()

マーわかってましたよ。

権限を無視して起動する

確か --skip-grant-tables とかいうオプションが合ったはずなので、 mysqld_safe を用いて「そもこの MySQL は動いてるのか?」を試してみる。

[user@localhost ~]$ cd /usr/local/Cellar/mysql/8.0.22_1/bin/
[user@localhost ~]$ mysqld_safe --skip-grant-tables
[user@localhost ~]$ mysql -u root
mysql>

おっ動いた、じゃあここで mysql_secure_installation 流せば設定書き換えられるのでは?

[user@localhost ~]$ mysql_secure_install
#=> パスワードの強度を 0 (LOW) にして設定するも「 skip-grant-tables で起動しているから書き換えられない」と言われる

くっそ……なんだこいつ。 root パスワード忘れた時って --skip-grant-tables でログインして変更するんじゃなかったっけ? と公式を見るとどうも違う模様。

こうして解決した

dev.mysql.com

既存の mysqld プロセスを停止する

[user@localhost ~]$ kill `cat /usr/local/var/mysql/${ホスト名}.pid`

必要なら my.cnf のパスワード強度を下げる

[user@localhost ~]$ vi /usr/local/etc/my.cnf

my.cnf

[mysqld]

...

# password policy
validate_password.length=4
validate_password.policy=LOW

mysqld 起動時に実行されるクエリでパスワードを弄る

--init-file というロングオプションで指定するファイルに記述されたクエリが、プロセス起動時に実行されるようなので、ここで内部的に root のパスワードを変更してしまう。 これでログインできるはずや!

[user@localhost ~]$ cd /usr/local/Cellar/mysql/8.0.22_1/bin/
[user@localhost ~]$ mysqld --init-file=~/Desktop/tmp-init

tmp-init

パスワード強度下げてる前提なので、デフォルトのままなら指定する新しいパスワードは 大文字小文字記号数字混じり 12 (16) 文字以上? じゃないとダメかな。

ALTER USER 'root'@'localhost' IDENTIFIED BY '4文字以上の新しいパスワード';

MySQL にログインする

設定したパスワードを利用することで無事に root ログインできた。

[user@localhost ~]$ mysql -u root -p ${ALTER で設定したパスワード}
mysql>

これでヨイ。 あとは ps ax|grep mysqld で pid 調べて kill してやれば専有されているターミナルが開放されるので、 brew なり mysql.server で改めて立ち上げ直せばデーモン化して使えるようになる。

いやー、ググっても同様の症状の人がいない (だいたい再インストールしなおせば解決してた) ので解決までにめっちゃ時間かかってしまった。 結局よくわかんないけど「 brew でインストールしたら root パスワード設定されている」に気付けたのでなんとかなった感じですね。

Formula の設定なにか間違ってるんじゃねえか? と思ったけど別の障害出て調査で疲れちゃったので、これにて平定。