業務中にいつも使っているMySQLの障害が発生しまして、それを解決するため行った対応をメモしました。
問題
EC2上にMySQLのDBを作成して運用していて、最初は異常なく使ってきましたが、最近よく週一回の頻度で意図しないMySQL停止が起こされて、MySQLの再起動を行っても直らない現象がありました。
結論
InnoDBのBuffer poolのメモリが足りないことでした。
そのため、Swap領域を作ってあげて、MySQLを再起動して解決しました。
エラー調査
1. statusを確認する。
systemctl status mysqld.service
下記のようなメッセージが出てきましたので、MySQLサービスは動いてないことを確定しました。
● mysqld.service - MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: failed (Result: start-limit) since Mon 2020-08-17 09:07:45 JST; 2s ago
Docs: man:mysqld(8)
http://dev.mysql.com/doc/refman/en/using-systemd.html
Process: 3726 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=1/FAILURE)
Process: 3704 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
Main PID: 24323 (code=killed, signal=KILL)
systemd[1]: Failed to start MySQL Server.
systemd[1]: Unit mysqld.service entered failed state.
systemd[1]: mysqld.service failed.
systemd[1]: mysqld.service holdoff time over, scheduling restart.
systemd[1]: start request repeated too quickly for mysqld.service
systemd[1]: Failed to start MySQL Server.
systemd[1]: Unit mysqld.service entered failed state.
systemd[1]: mysqld.service failed.
2. mysqld.logの内容を確認する。
my.cnf
にログの保存場所を記載しています。my.cnf
の場所を忘れた場合、下記のコマンドで可能な場所を探してください。
mysql --help | grep my.cnf
order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf
my.cnf
の中に、log-error=/var/log/mysqld.logという記述がありましたので、ログの場所を確認できます。
[Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
[ERROR] InnoDB: mmap(137428992 bytes) failed; errno 12
[ERROR] InnoDB: Cannot allocate memory for the buffer pool
[ERROR] InnoDB: Plugin initialization aborted with error Generic error
buffer poolのメモリの問題でして、容量が足りないではないかと思い、一旦容量を増やす方向で対応します。
解決方法
// 空ファイルの作成
# dd if=/dev/zero of=/swapfile bs=1M count=1024
// 作成したファイルをswap領域に設定
# mkswap /swapfile
// swap領域を有効にする
# swapon /swapfile
// メモリの確認
# free -m
total used free shared buff/cache available
Mem: 479 167 11 3 300 296
Swap 1023 0 1023
// MySQL再起動
# systemctl restart mysqld.service
// MySQL status確認
# systemctl status mysqld.service
他の方法
試してないですが、一応別の方法も記載しておきます。
MySQLの設定でbuffer_pool_sizeの変更は可能みたいですので、設定値を編集してみるのも良いかもしれません。
my.cnf
に下記の記述を追加or編集してから、再起動します。
innodb_buffer_pool_size = 256M
MySQLにアクセスできる場合、下記のコマンドで設定値の確認ができます。
> SHOW VARIABLES LIKE 'innodb_buffer_pool_size'
Variable_name Value
innodb_buffer_pool_size 134217728
最後
MySQLを再起動したら、innodb_buffer_pool_size
を確認しました。
Variable_name Value
innodb_buffer_pool_size 134217728
先ほどのエラログの内容
[ERROR] InnoDB: mmap(137428992 bytes) failed; errno 12
両方を再度確認してみたら、やはり容量が足りないことがわかりました。
swap領域を作成してあげましたので、これで一旦解決できていると思います。
作業メモは以上でした。