PHPで MySQL server has gone away エラーが出た時の対処法

ある日、 mysqli からクエリ発行するとこんなエラーが・・・

server has gone away ・・・?

あまり見かけないエラーだったので困惑、解決策を見つけるのにかなり苦戦しました。

ここでは同じようなエラーが悩む人のために、
MySQLで MySQL server has gone away エラーが出た時の対処法をまとめます。

このエラーに遭遇したのは multi_query を使った時

PHPの myslqi では mysqli::multi_query  を使うと複数クエリが実行できます。

▼この記事で詳しく解説したやつ

このエラーに遭遇したのは、それを使って大規模クエリを実行しようとしたとき

 

例えばこんな感じでクエリ実行のコードを書いてたんです。

まあ実際はこんなコードじゃないですが・・・

こういう風に セミコロン( ;  ) で区切ったクエリは muitl_query  から実行できます。

 

それで問題だったのが、実行すべきクエリがものすごく多かったことですね。

多分少なくても 1000 以上はあったと思います。

そのせいでサーバーに負荷がかかりすぎたのか、このエラーが出たみたいです。

こういう初めて見るエラーに遭遇すると、解決策を見つけるのに苦労します。

でもいくつか解決策を試したところ、無事クエリ実行できるようになりました。

MySQL server has gone away の3つの対処法

その対処法は「これだ!」って断言はできません、いろんな原因があるので

でも最低限、次のいずれかを試せば解決するはず

解決策1.パケットサイズを必要なだけ拡張する

大規模なクエリを実行したい場合、
例えばさっきの例だと大量の INSERT をしてエラーが出てしまいました。

パケットサイズが小さすぎると、SQL実行が拒否されてしまうみたいです。

なので対処法1つめは max_allowed_packet のサイズ拡張

 

やり方は SQL 発行前に次のクエリを実行すればいいです(オブジェクト指向型の場合)

この max_allowed_packet  にはパケットの上限をバイト数で渡せばOK

上の例だと 33554423バイト = 約32MB まで拡張させてます。

巨大なクエリを実行できないなら、このパケットサイズをまず疑いましょう。

 

あとちなみに・・・

この max_allowed_packet   の値は次クエリを実行すれば確認可能

▼上コードの出力結果

まあ 32MB もあれば、大規模なクエリでも実行できると思います。

対処法2.MySQLのタイムアウト時間を長くする

処理に時間がかかるようなクエリの場合、
あまりにも時間がかかりすぎると、MySQL側で勝手にタイムアウトしてしまいます。

それを伸ばすには wait_timeout の値を変更が必要

 

例えば大規模なクエリ発行前に、
次みたいに書けば wait_timeout  の値を変更できます。

この wait_timeout  の時間単位は秒(s)

上の例だと 3600秒 なので1時間 に設定してます。

このタイムアウト時間は、大規模なら1時間以上 に設定するのが安全かもしれません。

対処法3.ini_setでタイムアウト設定も必要かも...

あとそれから、念のため・・・

自分はタイムアウト時間も init_set から設定してます。

▼ 例えばこんな感じで

これは必ずしも必要ないと思いますけどね。

でもこの設定が聞いてくる場面もあると思うので、
心配ならこの設定も書いておくと問題解決につながるかも(確証はできない)

ここまでのまとめ

ということで、簡単にエラーの対処法まとめ

  • パケットサイズを拡張する
    クエリ実行前に max_allowed_packet  の値からバイト数で指定する。大体 10MB ~ 20MB 以上にしておけば問題ないはず(ただしクエリの大きさによる)
  • MySQLのタイムアウト時間を長くする
    クエリ実行前に wait_timeout   の値を秒で指定する。もしパケットサイズが十分大きいのに実行できないなら、この値を変更すると上手くいくはず
  • ini_setでタイムアウト設定
    タイムアウト時間を ini_set  を使ってPHP側からも設定しておく。念のため

もし server has gone away... エラーが出てしまったら、
この3つのいずれかを試せばクエリ実行ができるようになるはずです。

以上、PHPで MySQL server has gone away.. が発生したときの対処法でした。ではまた

PHP

Commentsこの記事についたコメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください