B.5.4.2 MySQL が繰り返しクラッシュする場合の対処方法

各 MySQL バージョンは、リリース前に多くのプラットフォームでテストされています。これは、MySQL にバグがないということではありませんが、バグがあってもごく少数であり、見つかることはまれです。問題が発生した場合は、システムがクラッシュした正確な原因を探すことが常に役に立ちます。問題の修正が迅速に得られる可能性が高まるためです。

まず、問題は mysqld サーバーが停止したことであるかどうか、またはクライアントに関連しているかどうかを判別してください。mysqld サーバーが稼働している時間を確認するには、mysqladmin version を実行します。mysqld が停止して再起動された場合は、サーバーのエラーログを確認すると原因が見つかる可能性があります。セクション5.2.2「エラーログ」 を参照してください。

一部のシステムでは、mysqld が停止したときのスタックトレースがエラーログに出力され、それを resolve_stack_dump プログラムを使用して変換できます。セクション24.4「MySQL のデバッグおよび移植」 を参照してください。エラーログに書き込まれる変数値は、常に 100% 正しいとは限りません。

多くのサーバーのクラッシュは、破損したデータファイルまたはインデックスファイルによって発生します。MySQL は、各 SQL ステートメントの実行後、クライアントに結果を通知する前に、ディスク上のファイルを write() システムコールを使用して更新します。(データファイルは書き込まれるがインデックスファイルは書き込まれない --delay-key-write を指定して実行している場合は異なります。)これは、mysqld がクラッシュしてもデータファイルのコンテンツは安全であることを意味します。フラッシュされていないデータがオペレーティングシステムによってディスクに書き込まれることが保証されているためです。各 SQL ステートメントのあとに MySQL がすべてのデータをディスクにフラッシュするようにするには、--flush オプションを指定して mysqld を起動します。

これは、通常、次のいずれかが発生していなければ、データが損なわれたテーブルができることはないことを意味します。

  • MySQL サーバーまたはサーバーのホストが更新中に強制終了された。

  • 更新の途中に mysqld が停止するバグが見つかった。

  • 一部の外部プログラムは、テーブルを適切にロックせずに、mysqld と同時にデータファイルまたはインデックスファイルを操作しています。

  • 適切なファイルシステムのロック (通常は lockd ロックマネージャーによって処理されます) をサポートしていないシステムで同じデータディレクトリを使用して多数の mysqld サーバーを実行しているか、外部ロックを無効にして複数のサーバーを実行している。

  • 大きく破損したデータが含まれているクラッシュしたデータファイルまたはインデックスファイルがあり、mysqld が混乱した。

  • データストレージのコードにバグが見つかった。可能性は低いですがあり得ることです。この場合は、修復されたテーブルのコピーに対して ALTER TABLE を使用することによって、別のエンジンへのストレージエンジンの変更を試みることができます。

何かがクラッシュした原因を判別するのは非常に難しいことであるため、まず、ほかの環境で動作する操作でも問題の環境ではクラッシュが発生するのかどうかを確認してください。次のことを試してください。

  • mysqladmin shutdown を使用して mysqld サーバーを停止し、データディレクトリから myisamchk --silent --force */*.MYI を実行して、すべての MyISAM テーブルを確認し、mysqld を再起動します。これにより、クリーンな状態から実行していることが保証されます。第5章「MySQL サーバーの管理 を参照してください。

  • 一般クエリーログを有効にして (セクション5.2.3「一般クエリーログ」を参照してください) mysqld を起動します。ログに書き込まれた情報から、特定のクエリーによってサーバーが強制終了したかどうかを判別してください。すべてのバグの 95% は特定のクエリーに関連しています。通常、これは、サーバーが再起動される前のログファイルの最後のクエリーのいずれかです。セクション5.2.3「一般クエリーログ」を参照してください。クエリーを発行する前にすべてのテーブルを確認しても、特定のクエリーによって MySQL が繰り返し強制終了される場合は、バグとして判別されましたのでバグレポートを送信してください。セクション1.7「質問またはバグをレポートする方法」を参照してください。

  • 問題を再現するために使用できるテストケースを作成してください。セクション24.4「MySQL のデバッグおよび移植」 を参照してください。

  • mysql-test ディレクトリおよび MySQL ベンチマークでテストを実行してください。セクション24.1.2「MySQL テストスイート」を参照してください。それらの環境では MySQL がよりよくテストされます。アプリケーションをシミュレートするコードをベンチマークに追加することもできます。ベンチマークは、ソース配布の場合は sql-bench ディレクトリ、バイナリ配布の場合は MySQL のインストールディレクトリの下の sql-bench ディレクトリにあります。

  • fork_big.pl スクリプトを試してください。(ソース配布の tests ディレクトリにあります。)

  • MySQL をデバッグ用に構成すると、何らかの問題がある場合に、考えられるエラーに関する情報を収集しやすくなります。-DWITH_DEBUG=1 オプションを指定して MySQL を再構成し、CMake を実行して再コンパイルします。セクション24.4「MySQL のデバッグおよび移植」 を参照してください。

  • オペレーティングシステムに最新のパッチが適用されていることを確認してください。

  • --skip-external-locking オプションを使用して mysqld を起動します。一部のシステムでは lockd ロックマネージャーが正常に動作しません。--skip-external-locking オプションは mysqld に外部ロックを使用しないように通知します。(これは、同じデータディレクトリで 2 つの mysqld サーバーは実行できず、myisamchk を使用する場合は注意する必要があることを意味します。それでも、テストとしてこのオプションを試すことには価値があります。)

  • mysqld は実行されているが応答しない場合は、mysqladmin -u root processlist を試してください。mysqld が応答しないように見えても、ハングアップしていないことがあります。すべての接続が使用されているか、内部ロックの問題である可能性があります。mysqladmin -u root processlist は、通常、これらの場合でも接続を確立することができ、現在の接続数およびそのステータスに関する役に立つ情報が表示されます。

  • ほかのクエリーを実行しているときに、別のウィンドウで mysqladmin -i 5 status コマンドまたは mysqladmin -i 5 -r status コマンドを実行して統計を生成します。

  • 次の手順を試してください。

    1. gdb (または別のデバッガ) から mysqld を起動します。セクション24.4「MySQL のデバッグおよび移植」 を参照してください。

    2. テストスクリプトを実行します。

    3. もっとも低い 3 つのレベルでバックトレースおよびローカル変数を出力します。gdb でこれを行うには、mysqldgdb 内でクラッシュしたときに、次のコマンドを使用します。

      backtrace
      info local
      up
      info local
      up
      info local
      

      gdb で、info threads を使用して存在するスレッドを検査し、thread N (ここで N はスレッド ID です) を使用して特定のスレッドに切り替えることもできます。

  • Perl スクリプトを使用してアプリケーションをシミュレートし、MySQL をクラッシュまたは誤動作させてください。

  • 通常のバグレポートを送信します。セクション1.7「質問またはバグをレポートする方法」を参照してください。通常より詳しく記述してください。MySQL は多くのユーザーの環境では動作しているため、クラッシュは問題となっているコンピュータにのみ存在する何かによって発生している可能性があります (たとえば、特定のシステムライブラリに関連するエラー)。

  • 動的長の行を含むテーブルで問題があり、VARCHAR カラム (BLOB カラムまたは TEXT カラムではなく) のみを使用している場合は、ALTER TABLE を使用して、すべての VARCHARCHAR に変更してみてください。これにより、MySQL が固定長の行を使用するようになります。固定長の行では若干追加の領域が使用されますが、破損に対してより耐性があります。

    現在の動的行のコードは数年使用されており、問題はほとんど発生していませんが、動的長の行はその性質のためエラーが発生しやすい傾向があるので、この方法がうまくいくかどうかを試すのは良い考えである可能性があります。

  • 問題を診断する場合は、ハードウェアの障害の可能性を考慮に入れてください。欠陥のあるハードウェアは、データ破損の原因となることがあります。ハードウェアをトラブルシューティングする場合は、メモリーおよびディスクのサブシステムに特に注意してください。


User Comments
Sign Up Login You must be logged in to post a comment.