ロケ地
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
でログインして変更するんじゃなかったっけ? と公式を見るとどうも違う模様。
こうして解決した
既存の 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 の設定なにか間違ってるんじゃねえか? と思ったけど別の障害出て調査で疲れちゃったので、これにて平定。