MySQLが勝手に落ちるのを解決する

##はじめに
MySQLを利用したアプリを運用し始めたのですが定期的にMySQLが落ちる現象が発生。
解決までのアプローチを記録に残したいと思います。

##環境
AWS EC2 RHEL8.0 t2.micro
MySQL ver 8.0.17

##問題
MySQLが定期的に落ちてしまい、データベースにアクセスできないことでアプリ上で例外が発生していた。
落ちたときのステータスを見てみるとこんな感じ
![スクリーンショット 2019-09-23 10.21.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137041/1018229e-a04f-f44e-7776-a9e838fecb16.png)


わからん。

ひとまずmysqlを再起動すると、正常に機能する。
が、またしばらくたつと落ちる。といった現象が発生していた。
restartしたら再起動するってことから、メモリを圧迫して落ちてるんじゃないか？
と思い、topコマンドで見てみる。
![スクリーンショット 2019-09-23 10.22.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137041/ec54c767-2c7d-24aa-7fa6-8fb27f7e2c55.png)

mysqlが半分近くのメモリ使ってるやん...、原因これじゃない？

##解決策
2つのことを試した。
1.table_definition_cacheの値を変更
2.swap領域の作成

###1.table_definition_cacheの値を変更
こっちは割とググると出てくる。
[メモリ食い過ぎてたのは、mysqlの設定が原因だった](https://qiita.com/m-shin/items/6be2dab071e87fee9f4f)

MySQL8.0だと若干パラメータファイルの場所が違っていたので記載
[mysqld]の下にtable_definication_cacheの定義を追加

```:/etc/my.cnf.d/mysql-server.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
table_definition_cache = 400
log-error=/var/log/mysql/mysqld.log
pid-file=/run/mysqld/mysqld.pid
```

400という値が適正かどうかはわからなが、みんな400にしてたのでとりあえず。
ちなみにデフォルトの値は2000となっていた。

MySQLのパラメータはmysqlにログインして以下のコマンドを叩けば一覧が表示される。

```
show variables;
```

このパラメータを追加してmysqlを再起動。
改めてメモリ使用量を確認すると

![スクリーンショット 2019-09-23 16.12.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137041/c6288047-c699-e85d-ce30-93336b08d2e3.png)

減ってる！！...けどまだ高くない？
これで解決するかわからないので、「2.swap領域の作成」へ

###2.swap領域の作成
こっちの解決策をあとで見つけたのだが、こちらの方が直結する解決策のような気がする。
[AmazonAWSで、MySQL がよく落ちる？ そんな時はSWAP領域をチェック！](https://qiita.com/madaran0805/items/ae0532a7436e1c684e72)


とりあえず記事の言われるがままにやったけど
知識ない人間からすると分からないことが多かったので理解しながら進めていきます。

まずswap領域とはなんぞや？ということで
**「一時的に利用していないメモリを格納しておく領域」**...というイメージです。

例えば100MB利用するアプリがあったとします。ただ常に100MBフルで使用しているわけではない。
そしたら使っていない部分でメモリを圧迫するのはもったいないですよね。
そういう時、例えば100MBのうち20MBをHDに避けておきます。
この端によけておくHDの一部の領域がswap領域です。

このswap領域の容量を確認するために、まずfreeコマンドを実行
これはメモリの空き状況を確認できるコマンド。
現状、swap領域確保ちゃっていますが最初確かめた時にはswap領域の空き容量が0でした。

つまりアプリ内で使っていない部分もすべてメモリでまかなっている状況ですね。
これを退避するswap領域を作ってあげる。

まずddコマンドでswap領域用の空ファイルを作ってあげる。

```
dd if=/dev/zero of=/swapfile bs=1M count = 1024
```
[if=/dev/zero]]:このコマンドで空ファイルが作れるとのこと。
[of=/swapfile]:空ファイルの場所
[bs=1M]:1回に読み書きするブロックサイズ
[count=1024]:bsで指定したサイズのブロックを入力から個数分だけコピーする(要は容量)

次にここに実際にswap領域を作成します。
swap領域を作成するのがmkswapコマンド。
さっき作った空ファイルの場所にswap領域を作ってあげます。
swapってコマンドにすらなってる常識的なものだったんですね、知らなかった...。

```
mkswap /swapfile
```

次に作ったswap領域を有効にします。

```
swapon /swapfile
```

このタイミングで一旦MySQLを再起動。

再びfreeコマンドを実行するとswap領域が確保されてます。
早速swap領域使われてる。
![スクリーンショット 2019-09-23 16.36.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137041/b1c4b083-82d7-33cb-5785-f7b7c601be48.png)

この状態だと再起動時した時にマウントされないようなので```/etc/fstab```を編集します。
この```/etc/fstab```は起動時に関することが書かれているファイルらしいです。
つまりここにswap領域のことを記載しておくど、起動時にうまくやってくれるようです。

この```/etc/fstab```の中に以下のコマンドを追加します。

```
/swapfile    swap    swap   defaults   0   0
```

中身を見ていくと
最初の```/swapfile```はファイルシステムです
次の```swap```はマウントポイントを表します。ファイルシステムのマウント先になるディレクトリです。
2つ目の```swap```がファイルシステムの種類を表します。swapってのが用意されてるのでswapですね。
```defaults```はマウントオプションです。マウントするときのオプションですね。色々用意されてるみたいですが今回はdefaultsで。
次の```0```はdumpフラグを表します。swapコマンドは0でいいみたいです。
最後の```0```はfsckがチェックする順番を表しており、0を指定するとチェックされません。

fsckとは？...Linuxのファイルシステムをチェックするコマンドのようです。

##最後に
今の所この2つを実行してからMySQLは落ちてません。
また落ちるようなことがあれば対策考えたいと思います。