#執筆背景
ローカル環境で作成中のWebアプリを立ち上げようと、
$ rails s
を入力し、ブラウザからWebアプリにアクセスしたところ、突然
Completed 500 Internal Server Error in 7ms (ActiveRecord: 0.3ms | Allocations: 5953)
という謎のエラーが発生。
直訳では、内部サーバーエラー500。
とりあえず、パソコンを再起動し、再びアプリを再起動すると、
Mysql2 :: Error :: ConnectionError
の文字が表示された。
よく分からないがとりあえずmysql2で何か問題があると考えられる。
※なお、今回のrailsのバージョンは6.0.2.2です。
また、Yay! You’re on Rails!のページ(以下画像)にはアクセスできました。
#結論
このエラーは、
クライアント側とMySQLサーバー側で設定されている最大バケット値(これはmax_allowed_packetという変数で指定される)よりも転送時のバケット数の方が高い場合
に起こるエラーです。
今回行った作業内容として、
・ MySQLの公式ドキュメントに掲載されている方法
(mysqld_safeドキュメントの最初の行にulimit -d 256000を追加したのちmysqlを再起動)
・ MySQLをアンインストールしたのち、再インストール
・ データベースを削除したのち、再作成
などを試したが、直らなかった。
そのため、
アプリのバックアップを作成しアプリを一から作り直したのち、バックアップを反映させてアプリを再起動
したところ直った。
(2020/04/01:追記)
後日、ファイルのアップロード機能の動作確認をしていたところ、アップロードボタンを押した後に
TypeError (no implicit conversion of nil into String)
というエラーが発生した(以下のリンク参照)。
https://qiita.com/hasegawa-naoto/items/895dc96bb5aed93d769a
こちらのエラーの頭行に
Completed 500 Internal Server Error
と同様のエラーが示されていたため、エラー対処の結果、
アップローダーのfilenameメソッドが正しく機能していなかったこと
が本記事のエラー原因ではないかと考えている。
#エラーが出る直前で行なっていたこと
ファイルのアップロード機能を実装しており、ファイルをアップロードしてファイルを削除して再びアップロードして…みたいなことの動作チェックをしていた。
ここから連想されるに、mysqlサーバーに負荷がかかりすぎてしまったのかな…?という1つの推測が浮かび上がった。
#作業内容
以下では、実際の作業内容を示していきます。
##MySQLの公式ドキュメントに掲載されている方法を試す
Mysql2 :: Error :: ConnectionErrorで調査したところ、公式ドキュメントを発見。
https://dev.mysql.com/doc/refman/5.6/ja/packet-too-large.html
どうやら、
クライアント側とMySQLサーバー側で設定されている最大バケット値(これはmax_allowed_packetという変数で指定される)よりもアップロード時のバケット数の方が高い場合
に接続が失われるようになっているらしい。
対処法として、mysqld_safeドキュメントファイルの最初の行にulimit -d 256000を追加したのち、MySQLを再起動してみてください
と書いてあったため、指示通りに試してみる。
sudo find / -name mysqld_safe #mysqld_safeファイルがどこにあるか検索
/usr/local/bin/mysqld_safe
sudo vim /usr/local/bin/mysqld_safe #mysqld_safeファイルを開く
ulimit -d 256000 #追加
#!/bin/sh
# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
…以下略
:wq!コマンドで保存しようとすると、Read Only File(読み込み専用ファイル)と表示され、保存できないため、以下のコマンドを打つことで保存した。
:w !sudo tee % #このコマンドを入力する
W12: Warning: File "mysqld_safe" has changed and the buffer was changed in Vim a
s well
See ":help W12" for more info.
[O]K, (L)oad File:o #OKを選択する
"mysqld_safe" [readonly] 1040L, 29923C
:q! #上書き保存を入力する
MySQLを再起動。
$ mysql.server restart
Shutting down MySQL
. SUCCESS!
Starting MySQL
. SUCCESS!
その後、railsを再起動し接続を試みるも直らない(笑)
#MySQLの再インストールを試す
仕方がないので、MySQLをアンインストールする方針で進めることにする。
$ brew uninstall mysql
Uninstalling /usr/local/Cellar/mysql/8.0.19... (294 files, 291.4MB)
$ brew install mysql
$ rails db:migrate
$ rails s
しかし、直らず。
#データベースの再作成を試す
仕方がないので、データも大したことなかったということもありデータベースそのものを削除することにした。
$ mysql -u user_name -p
$ enter password
mysql > drop database database_name;
query OK,1 row affected
mysql> create database database_name;
query OK,1 row affected
しかし、結局直らなかった…。
#アプリを再作成
他のアプリでは起動することができ、MySQLも正常に動作したので、一旦、このアプリのバックアップを作成しておき、アプリを作り直すことにした。
$ rails new app_name
この後、コピーしておいたアプリの情報を新規で作成したアプリに反映させたのち、
$ rails s
#まとめ
今回は、簡易なアプリかつローカル環境下だったから良かったものの大規模なアプリ開発かつ本番環境下の場合、このエラーが出たときはかなり苦渋の選択を強いられそう。
調査した感じだとこのエラーは割とrailsで開発してる中では多いみたいだが、
どの記事をみても原因が不明瞭なことが多く修復方法も(アンインストールなどの)強行突破な方法が多い。
ただ、公式ドキュメントによれば、
クライアント側とMySQLサーバー側で設定されている最大バケット値(これはmax_allowed_packetという変数で指定される)よりも転送時のバケット数の方が高い場合
に起こるエラーであることは確かなので、転送時のバケット数に気を配りながら動作チェックをするなどを気構えておく必要があるのかなと思う。
(2020/04/01:追記)
結論でも述べたが、このエラーの原因は
アップローダーのfilenameメソッドが正しく機能していなかったこと
だと考えており、正しく機能しなかった理由は
fileが添付されていないにも関わらずcarrierwave.rbのfile_nameメソッドを呼び出していたため
です。
そのため、file_nameメソッドの中身の後ろに
if original_filename.present?
をつけてファイルが添付されているときのみメソッドを呼び出すようにすることで解決すると考えています。
詳細は以下の記事からお願いします。
https://qiita.com/hasegawa-naoto/items/895dc96bb5aed93d769a