MySQL 8.0 リファレンスマニュアル


B.3.2.7 MySQL サーバーが存在しなくなりました

このセクションでは、関連する「クエリー中にサーバーへの接続が失われました」というエラーについても説明します。

「MySQL サーバーが存在しなくなりました」というエラーのもっとも一般的な原因は、サーバーがタイムアウトして接続が閉じられた場合です。 この場合は、通常、次のいずれかのエラーコードを受け取ります (受け取るエラーコードはオペレーティングシステムによって異なります)。

エラーコード 説明
CR_SERVER_GONE_ERROR クライアントはサーバーに問い合わせを送信できませんでした。
CR_SERVER_LOST クライアントはサーバーに書き込むときにエラーを受け取りませんでしたが、問い合わせに対する完全な応答 (または何らかの応答) が得られませんでした。

デフォルトでは、何も発生しなかった場合、サーバーは 8 時間後に接続を閉じます。 この時間制限を変更するには、mysqld を起動するときに wait_timeout 変数を設定します。 セクション5.1.8「サーバーシステム変数」を参照してください。

スクリプトがある場合、クライアントが自動再接続を行うには、クエリーを再発行する必要があるだけです。 これは、クライアントの自動再接続を有効にしている (mysql コマンド行クライアントのデフォルト) ことが前提です。

「MySQL サーバーが存在しなくなりました」というエラーのほかの一般的な原因を次に示します。

  • ユーザー (またはデータベース管理者) が実行中のスレッドを KILL ステートメントまたは mysqladmin kill コマンドを使用して強制終了した。

  • サーバーへの接続を閉じたあとにクエリーを実行しようとした。 これはアプリケーションの論理エラーを示しており、修正する必要があります。

  • 別のホスト上で実行されているクライアントアプリケーションに、そのホストから MySQL サーバーに接続するために必要な権限がない。

  • クライアント側で TCP/IP 接続がタイムアウトした。 これは、コマンド mysql_options(..., MYSQL_OPT_READ_TIMEOUT,...) または mysql_options(..., MYSQL_OPT_WRITE_TIMEOUT,...) を使用している場合に発生することがあります。 この場合は、タイムアウト値を増やすと問題が解決されることがあります。

  • サーバー側でタイムアウトが発生し、クライアントの自動再接続が無効にされている (MYSQL 構造体の reconnect フラグが 0 と等しい)。

  • Windows クライアントを使用していて、コマンドが発行される前にサーバーによって接続がドロップされた (おそらく wait_timeout が期限切れになったため)。

    Windows での問題は、TCP/IP 接続をサーバーに書き込むときに MySQL が OS からエラーを受け取らず、接続から応答を読み取ろうとしたときにエラーを受け取ることです。

    この問題の解決策は、最後のクエリーから長い時間がたっている場合に接続に対して mysql_ping() を実行するか (これは Connector/ODBC が行なっていることです)、mysqld サーバーで wait_timeout に事実上タイムアウトすることがないような高い値を設定することです。

  • 間違ったクエリーまたは長すぎるクエリーをサーバーに送信した場合にも、これらのエラーを受け取ることがあります。 mysqld が長すぎるパケットまたは順序が間違っているパケットを受け取ると、クライアントで何らかの問題が発生していると見なして、接続を閉じます。 大きなクエリーが必要な場合 (たとえば、大きな BLOB カラムを操作している場合)、クエリーの制限を緩和するには、サーバーの max_allowed_packet 変数 (デフォルト値は 64M バイト) を設定します。 クライアント側の最大パケットサイズも増やす必要がある場合もあります。 パケットサイズの設定については、セクションB.3.2.8「パケットが大きすぎます」を参照してください。

    多数の行を挿入する INSERT ステートメントまたは REPLACE ステートメントも、これらの種類のエラーの原因となることがあります。 これらのステートメントのいずれかは、挿入される行数に関係なくサーバーに単一の要求を送信します。このため、1 つの INSERT または REPLACE で送信される行数を減らすことによって多くの場合エラーを防ぐことができます。

  • ホスト名のルックアップが失敗した場合に、このエラーが発生することもあります (たとえば、サーバーまたはネットワークが依存する DNS サーバーが停止した場合)。 これは、MySQL が名前解決についてホストシステムに依存しているが、それが動作しているかどうかは知ることができないためです。MySQL が認識している範囲では、この問題はほかのネットワークタイムアウトと区別が付きません。

    skip_networking システム変数を有効にして MySQL を起動すると、MySQL server has gone away エラーが表示されることもあります。

    MySQL のポート (デフォルトは 3306) がファイアウォールによってブロックされていて、MySQL サーバーへのすべての接続が遮断される場合、このエラーの原因となることがある別のネットワークの問題が発生します。

  • アプリケーションで複数の子プロセスがフォークされ、すべての子プロセスが MySQL サーバーへの同じ接続を使用しようとした場合に、このエラーが発生することもあります。 これは、各子プロセスが個別の接続を使用することによって防ぐことができます。

  • クエリーの実行中にサーバーが停止するバグが発生した。

MySQL サーバーが停止して再起動されたかどうかを確認するには、mysqladmin version を実行してサーバーの稼働時間を検査します。 mysqld がクラッシュして再起動されたためにクライアント接続が切断された場合は、そのクラッシュの原因を見つけることに集中してください。 クエリーを再び発行するとサーバーが再び強制終了されるかどうかを確認することから始めます。 セクションB.3.3.3「MySQL が繰り返しクラッシュする場合の対処方法」を参照してください。

失われた接続の詳細を取得するには、log_error_verbosity システム変数を 3 に設定して mysqld を起動します。 これにより、切断メッセージの一部が hostname.err ファイルに記録されます。 セクション5.4.2「エラーログ」 を参照してください。

この問題に関するバグレポートを作成する場合は、次の情報を含めてください。

  • MySQL サーバーが停止したかどうかを示します。 これに関する情報はサーバーのエラーログにあります。 セクションB.3.3.3「MySQL が繰り返しクラッシュする場合の対処方法」を参照してください。

  • 特定のクエリーによって mysqld が強制終了し、クエリーを実行する前に関係するテーブルが CHECK TABLE でチェックされていた場合は、再現可能なテストケースを提供してください。 セクション5.9「MySQL のデバッグ」を参照してください。

  • MySQL サーバーの wait_timeout システム変数の値 (mysqladmin variables を使用すると、この変数の値を取得できます。)

  • 一般クエリーログを有効にして mysqld を実行し、問題のクエリーがログに出力されるかどうかを確認することを試みましたか。 (セクション5.4.3「一般クエリーログ」を参照してください。)

セクションB.3.2.9「通信エラーおよび中止された接続」およびセクション1.6「質問またはバグをレポートする方法」も参照してください。


関連キーワード:  サーバー, 接続, エラー, クエリー, 一般, セクション, 発生, テーブル, 方法, 参照