MySQL バージョンはすべて、リリース前に多くのプラットフォームでテストされています。これは MySQL にバグがないというわけではありませんが、バグがあったとしても、非常に少なく見つけるのが困難です。何か問題がある場合に、システムをクラッシュさせているものを正確に調査することは、この問題の早期解決に役立ちます。
まず、問題は mysqld
デーモンが死んでいることにあるのか、または問題がクライアントに関係しているのかを判断する必要があります。mysqladmin
version
を実行して、mysqld
サーバが稼動していた時間を確認することができます。mysqld
が死んでいる場合は、ファイル
mysql-data-directory/`hostname`.err
を見ることによりその原因を見つけることができます。
See 項4.10.1. 「エラーログ」。
システムの中には、このファイルに
mysqld
が死んだ際のスタックトレースがあるものがあり、resolve_back_stack
で問題を解決できます。See
項E.1.4. 「スタックトレースの使用」。.err
ファイルに書き込まれている変数値は、常に 100
パーセント正確であるとは限りません。
MySQL
のクラッシュの多くは、インデックスファイルやデータファイルの破壊が原因です。
MySQL は、すべての SQL ステートメントの後で
write()
システムコールを呼び出し、ディスク上のデータを更新します。クライアントには、その後その結果が通知されます(delay_key_write
で実行している場合で、データの書き込みだけの場合にはこの限りではありません)。
つまり、OS
によってフラッシュされていないデータがディスクに確実に書き込まれるため、mysqld
がクラッシュした場合でもデータは安全です。--flush
を指定して mysqld
を開始することによって、各 SQL
コマンド実行後、強制的にすべてをディスクと同期させることができます。
つまり、以下のことがなければ、通常は破壊されたテーブルを得ることはありません。
誰かまたは何かが、更新中に
mysqld
またはマシンを強制終了した。
更新中に mysqld
が死ぬようなバグを見つけた。
テーブルを適切にロックしないで、mysqld 外でデータまたはインデックスフファイルを操作している。
優れたファイルシステムロック(通常、lockd
デーモンによって処理される)をサポートしていないシステム上で、同じデータに対して、多くの
mysqld
サーバを実行しているか、--skip-external-locking
で複数サーバを実行している。
mysqld
を混乱させるような不正なデータを含んだ、破損したインデックスまたはデータファイルがある。
データストレージのコードにバグを発見した。これはおそらくあり得ないことだが、可能性としてはある。この場合、修正されたテーブルのコピーに対して
ALTER TABLE
を使用して、ファイルタイプを別のデータストレージエンジンに変更することができる。
クラッシュの原因を見つけるのは非常に難しいので、まず、他で動作しているものが自分の環境でクラッシュするかどうかを確認してください。以下を試してください。
mysqladmin shutdown
で
mysqld
デーモンを停止し、全テーブルで
myisamchk --silent --force */*.MYI
を実行した後、mysqld
デーモンを再起動する。必ず、クリーンな状態から実行すること。
See 章 4. データベース管理。
mysqld --log
を使用して、ログの情報から、特定のクエリがサーバを終了させるかどうかを判断する。バグの
95%
が特定のクエリに関係している。通常、これは、MySQL
再実行直前のログファイルにある最後のクエリの
1 つである。 See 項4.10.2. 「一般クエリログ」。
クエリを実行する直前にすべてのテーブルを確認しても、クエリの
1 つで MySQL
を何度も強制終了させることができる場合、バグを突き止められているので、バグレポートを発行する必要がある。
See 項1.7.1.3. 「バグまたは問題を報告する方法」。
問題の再現に使用するテストケースを作成する。 See 項E.1.6. 「テーブルが破損した場合にテストケースを作成する」。
組み込まれている mysql-test テストと MySQL
ベンチマークを実行する。See
項13.1.2. 「MySQL テストスイート」。これによって
MySQL
を正確にテストできる。ベンチマークにアプリケーションをシミュレートするコードを追加することもできる。ベンチマークは、ソースディストリビューションまたはバイナリディストリビューションの
bench
ディレクトリか、MySQL
インストールディレクトリの
sql-bench
ディレクトリにある。
fork_test.pl
と
fork2_test.pl
を実行する。
デバッグ用に MySQL
を設定している場合は、何か問題が発生した際に、考えられるエラー情報の収集が非常に容易になる。
configure
に
--with-debug
オプションか
--with-debug=full
オプションを指定して MySQL
を再設定し、その後再コンパイルする。 See
項E.1. 「MySQL サーバのデバッグ」。
デバッグ用に MySQL を設定すると、安全なメモリアロケータが組み込まれ、エラーを見つけることができる。また、何が発生しているかについて、多くの情報が提供される。
オペレーティングシステムの最新のパッチを適用しているかどうか確認する。
mysqld
にオプション
--skip-external-locking
を指定する。システムの中には、lockd
ロックマネージャが適切に動作しないものがある。--skip-external-locking
オプションによって、mysqld
に外部ロックを使用しないように指示することができる(つまり、同じデータで
2 つの mysqld
サーバを実行することができない。myisamchk
を使用する場合は注意が必要だが、テストとしてオプションを使用する場合は有益である)。
mysqld
が動作しているように見えるのに応答がなかった時、mysqladmin
-u root processlist
を実行したか。mysqld
は消滅しているように見えても、消滅していない場合がある。すべての接続が使用中であるか、内部ロック問題の可能性がある。
mysqladmin processlist
は、通常、このような場合であっても接続を行うことができ、現在の接続数やその状況に関して有益な情報を取得できる。
他のクエリを実行中に、別のウィンドウで
mysqladmin -i 5 status
または
mysqladmin -i 5 -r status
を実行し、統計を生成する。
以下を実行してみる。
gdb
から(または別のデバッガで)、mysqld
を起動する。 See
項E.1.3. 「mysqld のデバッグ(gdb 使用)」。
テストスクリプトを実行する。
3つの最下位レベルで、バックトレースとローカル変数を出力する。gdb
では、mysqld
が gdb
内部でクラッシュした場合、以下のコマンドでこの出力を実行できる。
backtrace info local up info local up info local
gdb では、info threads
により、存在しているスレッドを調べ、thread
#
(#
はスレッド
ID)で特定のスレッドにスイッチすることができる。
Perl スクリプトでアプリケーションをシミュレートし、MySQL をクラッシュさせたり不正な動作をさせたりする。
バグレポートを送付する。See 項1.7.1.3. 「バグまたは問題を報告する方法」。詳細なレポートにすること。MySQL は多くの人が使用しているため、クラッシュがあなたのコンピュータだけにある何らかの原因に起因している可能性がある(たとえば、特定のシステムライブラリに関連するエラー)。
可変長レコードを持つテーブルに問題があり、BLOB/TEXT
カラム(BLOB/TEXT
カラムのみ)を使用していない場合、ALTER
TABLE
で VARCHAR
すべてを
CHAR
に変更することができる。これによって、MySQL
は固定サイズのレコードを使用する。
固定サイズのレコードは余分な領域を少し取るだけだが、破壊に対して非常に大きな耐性がある。
現在の可変長レコードのコードは、少なくとも 3 年間は何の問題もなく MySQL AB で使用されてきた。しかし本来、可変長レコードはエラーが発生しやすく、上記のことが役立つかどうか試してみるのも有益である。
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.