以前に、EC2上のRailsアプリを作成する際に、デフォルトのSQLite3をデータベースにしちゃったから、それをMySQLに変更するために、mysql2というgemをインストールするのにマジハマりしたというお話をしましたが・・・。
またまた、どハマりました。
今度はMySQL(データベース)で。
いや、でもこれ、自分がMySQLについて(というか、データベースについて)あまりにも無知すぎて、マジでビビったww
そもそもの発端は、自分がmysqlとMySQL、データベースのクライアントとサーバーをごっちゃにしていたところにある。
Railsで使うデータベースは、rails newコマンドの時に -d オプションで指定しなければSQLite3になるし、 -d mysql などにすればMySQLになる。
が、これってあくまでもクライアントとしてのデータベースの指定であるということに、さっき気づいたんだよーーー!!!(死)
てかさ、一番悪いのはSQLite3だ!(←人(DB)のせいにするw)
SQLite3は、サーバーレスのデータベースなのだった。それをインストールしさえすれば、即使えるのだ。SQLiteデータベースは、単一のディスクファイルだから、データベースエンジンが必要ない。
だから、rails newしたら、即データベースも使えたのであった。
最初にこれ使ったら、rails newしたらすぐデータベース使えるって思っちゃうよね!
(ちゃんと考えずに使っていた自分を棚に上げる。)
今回、Serverspecの自動テストを試してみたくて、EC2内部にデータベース(MySQL)を持つ環境を作ろうと思って、RailsアプリをMySQL指定で作成したのさ。
したらば、データベースにアクセスできない!!ってなって(当たり前だw)、なんで!?と悩んだのでありました。
mysqlはインストールされている、がmysqldは起動していない。
というとことまで分かっていたのだが、なぜrails newの時にデータベースサーバーがインストールされていなかったのかという点には気づいていなかったのだ。(データベースサーバーまで勝手にインストールされて、すぐに使えるようになると思い込んでいたわけです。QLite3のように!)
rails newでインストールされるmysql2は、あくまでもクライアントとして、サーバーにリクエストするために必要な機能やライブラリであって、データベースエンジンはそれとは別にインストールする必要がある。
EC2上に直接データベースを置いて、Railsアプリからアクセスできるようにする方法
今回は、AWS上に手動で作成したEC2(Amazon Linux2)インスタンス上で実施している。
rails new コマンドでRailsアプリを作成する。
rails new spectest_apl -d mysql
MySQLをインストールする
システムのパッケージを更新する
sudo yum update
MariaDBのパッケージを削除。MySQLはMariaDBと互換性がないため、MariaDBを削除せずにMySQLをインストールしようとすると、結局MariaDB消せって怒られるっぽい。(から先に消しとく)
sudo yum remove mariadb-libs
yumにMySQLのリポジトリを追加
mysql80-community-release(MySQL 8.0.x)がインストールされる
sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
mysql-community-server(8.0.23)をインストールする
sudo yum install --enablerepo=mysql80-community mysql-community-server
mysql-community-devel(8.0.23)をインストールする
sudo yum install --enablerepo=mysql80-community mysql-community-devel
一応インストールされたもの一覧を確認しておく
yum list installed | grep mysql
※上記は、インストールされたもの一覧から、mysql関連でグレップしたものを出力
mysql-community-client.x86_64 8.0.23-1.el7 @mysql80-community mysql-community-client-plugins.x86_64 8.0.23-1.el7 @mysql80-community mysql-community-common.x86_64 8.0.23-1.el7 @mysql80-community mysql-community-devel.x86_64 8.0.23-1.el7 @mysql80-community mysql-community-libs.x86_64 8.0.23-1.el7 @mysql80-community mysql-community-server.x86_64 8.0.23-1.el7 @mysql80-community mysql80-community-release.noarch el7-3 installed
ログが出力されるファイルを予め作成しておく
sudo touch /var/log/mysqld.log
試しに、バージョンも表示させてみるか
mysqld --version # /usr/sbin/mysqld Ver 8.0.23 for Linux on x86_64 (MySQL Community Server - GPL)
うん、OK!
mysql --versionとmysqld --versionの違いを理解していなかったんだよなぁ~・・・
今ならわかる。mysqlはクライアント側、mysqldがサーバー側。
MySQLサーバーを起動する
起動コマンド
sudo systemctl start mysqld
mysqldのステータスを確認しておく
systemctl status mysqld.service
runningになっているのでOK
● mysqld.service - MySQL Server Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled) Active: active (running) since Fri 2021-03-26 07:20:40 UTC; 8s ago Docs: man:mysqld(8) http://dev.mysql.com/doc/refman/en/using-systemd.html Process: 31260 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS) Main PID: 31335 (mysqld) Status: "Server is operational" CGroup: /system.slice/mysqld.service mq31335 /usr/sbin/mysqld Mar 26 07:20:34 ip-172-16-16-180.ap-northeast-1.compute.internal systemd[1]: ... Mar 26 07:20:40 ip-172-16-16-180.ap-northeast-1.compute.internal systemd[1]: ... Hint: Some lines were ellipsized, use -l to show in full.
MySQLにログインする
さあ、いざMySQLにログインしようとした矢先・・・
mysql -u root -p
イキナリ怒られる理不尽なわたし
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
調べてみると、MySQL8はログイン認証のプラグインが変わったらしく、現在のユーザーとログインしようとしているユーザーが異なるとログインできないらしい。(ナニソレ!)
認証処理をスキップする
ログインできないのでは、お話にならないので、認証処理をスキップしてDBにアクセスする。
まずはMySQLを停止させる
sudo systemctl stop mysqld
認証処理をスキップするセーフモードの起動には、mysqld_safe --skip-grant-tables というコマンドがあるらしいが、自分の環境では使えないようなので、別の方法で試してみる。
環境変数を設定
sudo systemctl set-environment MYSQLD_OPTS="--skip-grant-tables"
MySQLを開始
sudo systemctl start mysqld
気を取り直して、再度MySQLにログイン!
mysql -u root
やっとつながった・・・(長かった!!)
rootユーザーのパスワードを変更する
さあ、これでようやくrootユーザーのパスワードを変更することができるぜ!
mysqlデータベースを使用
mysql> use mysql;
rootユーザーのパスワードはなし(null)に設定
mysql> UPDATE mysql.user SET authentication_string=null WHERE User='root';
これで、パスワードなしのrootユーザーが設定された
exitコマンドでMySQLからログアウトしたら、今度は先ほど設定した環境変数を元に戻す
sudo systemctl unset-environment MYSQLD_OPTS
設定完了したので、MySQLを再起動
sudo systemctl restart mysqld.service
パスワードなしのrootユーザーでログインする
mysql -u root
キタ――(゚∀゚)――!!――(゚∀゚)――!!
ひとまずまず何もないDBを表示してみよう
mysql> show databases;
む?また怒られたよ
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
パスワードリセットしなさいよ、というお叱りが!(めんどくさいぜ!)
ALTER USER使って変えろって言われているから、素直に従う
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'パスワード';
※パスワードの制約が結構厳しくて、大文字小文字英数字記号入れて8文字以上みたいな感じ
パスワード変更が許可されたら、データベースが使えるようになる
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.01 sec)
うむ。よきかな。
続いて、config\database.ymlのパスワードも忘れずに変更しておく
※これ忘れると、次にmysqlでログインできなくなるよ!
default: &default adapter: mysql2 encoding: utf8mb4 database: mysql pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: ここにパスワード host: localhost
データベースもちゃんと作成できるようになりました!
rails db:create rails db:migrate
と、言うわけで、ようやくEC2上のRails環境からデータベースにアクセスする準備が整ったのでした。