MySQL5.0.87を現在利用していて、「MySQL server has gone away」というエラーメッセージと共に接続が途絶える事象が多発する事があります。

もう少し詳しく申し上げると、PHPなWebアプリからMySQLにその都度接続している所、時々そのエラーが起こりクエリを発行する事が出来なくなります。
どうすればこういった事が起こらずに安定して接続できるようになるのでしょうか?

マニュアルによると以下の可能性が記載されていましたが、どれにも該当しません。
・クエリが長すぎる可能性がある…3行ほどの短いクエリでも発生します。
・wait_timeoutを超えてしまっている…設定としては90秒ですが、数秒で起きるときは発生します。
また、統計を見る限り同時最大接続数がmy.cnfで設定した数を叩いているという訳でもないようです。

もし解決法をご存じの方いらっしゃいましたら教えて頂けますでしょうか。
よろしくお願いいたします。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2010/03/14 23:20:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答5件)

id:km1967 No.1

回答回数541ベストアンサー獲得回数40

ポイント20pt

まずはお願いなのですが、

お使いのパソコンのOSやPHPのバージョンなど、

何も判らないと原因の特定は難しくなりますので、必須だとご記憶ください。

不適当な回答が集まっても混乱をきたしますから、私への返信欄か、

あるいは、コメント欄に書き加えておくことを勧めます。

それから、PHPのエラーログは確認されましたか?

id:ko-takada

大変失礼しました。CentOS 5.3や5.4です。

PHPは5.2.6や5.2.13などを利用し、MDB2やPDO等で接続しています。

なお、いずれの環境においても、OSを再インストールしてもマシン(ラックマウントサーバ)を変えてもごくまれに発生する状況です。

PHPのエラーログにはMDB2_Errorという記述がございました。この中身が、「MySQL server has gone away」となっています。

2010/03/08 00:55:21
id:Km1967 No.2

回答回数224ベストアンサー獲得回数35

ポイント20pt

MySQLが逃げ出した時のSQLを照らし合わせていくと同じようなパターンに遭遇するとは思うが面倒だ。

一通りの条件テストはしたみたいだから、それでもダメなら単純な推敲になるがindexかtableがぶっ壊れてそうな気がする。

reindexでもいいかもしれないがバックアップ取ってからrepairするのが近道だろ思う。

http://dev.mysql.com/doc/refman/5.1/ja/mysqlcheck.html

id:ko-takada

1年以上追っていますが、なぜかパターン性がありません。そして、壊れていると言うことはありません。

というのもindex等が壊れた場合にはmysqld.logに記述されるほか、その後の読み出しが出来なくなるためです。

なお、別地域のデータセンタにある別サービスのサーバにおいても、「MySQL server has gone away」が時折発生しています。

何か参照しておいた方が良い情報はありますでしょうか?

もし何かお気づきの点がございましたら教えて頂けると幸いです。

2010/03/08 00:52:29
id:km1967 No.3

回答回数541ベストアンサー獲得回数40

ポイント20pt

disconnectしていないというオチではないよね?


とりあえず、REPAIR TABLE コマンドを発行して様子を見てみ

id:ko-takada

> disconnect

どのタイミングででしょうか?

スクリプト終了時には自動的に発行されると思っていますので、行っておりません。

> REPAIR TABLE

パターン性がないのですが、過去に起こったことのあるテーブルで実行してみたいと思います。

2010/03/08 08:59:27
id:JULY No.5

回答回数966ベストアンサー獲得回数247

ポイント20pt

英語ですが、下記のページがまとまっていると思います。

http://blog.taragana.com/index.php/archive/mysql-tip-mysql-serve...

ざっくり概要を訳してみると(間違っていたらゴメンナサイ...)

  1. 保持しているコネクションが、デフォルトでは8時間以上、やりとりが無かった時に切断される。PHP でコネクションプーリングしている場合が多い。
  2. ロジックの誤りでコネクションを閉じちゃっている場合。例えば、マルチスレッドのアプリケーションで、別のスレッドが閉じている、とか。
  3. クライアント側からタイムアウトが通知された場合。
  4. クライアント側の自動再接続機能が無効にされている状態で、サーバ側でタイムアウトが発生した場合。
  5. 巨大なクエリーや誤ったクエリーを投げた場合。
  6. INSERT や REPLACE で、大量の行をソートしなければいけないような場合。
  7. クライアントバージョンが 4.0.8 より古くて、サーババージョンが 4.0.8 以降の場合に、16MB 以上のパケットを送った場合。

稀なケースとして、

  1. 管理者が MySQL のサーバを止めちゃった場合。
  2. クライアントがサーバと別のホストで動いていて、接続するための権限を十分に持っていない場合。
  3. Windows の場合、たぶん、タイムアウトが起きてコネクションが閉じられたんだけど、OS から十分なエラー情報が得られないので、結果、このエラーメッセージになる。
  4. 5.0.19 よりで、自動再接続フラグが有効になっていても、うまく再接続出来ない場合がある。
  5. 名前解決に失敗しているケース。
  6. --skipe-network オプション付きでサーバが起動されている場合。
  7. アプリケーションの全ての子プロセスが、同じコネクションを使おうとしている場合。
  8. ファイヤーウォールで MySQL サーバが使うポートがブロックされた場合。
  9. クエリーを処理中のサーバが死んじゃった場合。

というのが挙げられています。

関係ありそうなもの、無さそうなもの、玉石混交ですが、参考まで。

# なんとなく、PHP のコネクションプーリングの問題のような気がするけど。

  • id:Km1967
    複数のシステムで同じ状況という事は基本設計の部分で問題があるとは思うのだが
    ・アクセス集中やcron等で一時的に負荷があがった
    ・テーブルロックを制御できていない
    などが頭に残ってしまって他を考えられない状態に陥ってしまった。
    キャッシュ関連やメッセージキュー関連などが怪しいとも思っているのだが考えがまとまらない。
  • id:km1967
    >> disconnect
    > どのタイミングででしょうか?
    > スクリプト終了時には自動的に発行されると思っていますので、行っておりません。

    そりゃプログラムの不備だわ
    MySQLへのアクセスが終わったらdisconnectを発行しなきゃ!

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません