目次
この付録は、MySQL を他のオペレーティングシステムに移植する際に役立ちます。 現時点でサポートされているオペレーティングシステムの一覧を最初に確認してください。 See 項2.2.3. 「MySQL がサポートしているオペレーティングシステム」。 MySQL の移植版を新たに作成した場合はお知らせください。このマニュアルと当社 Web サイト(http://www.mysql.com/)に新規移植版を掲載し、他のユーザに推奨させていただきます。
注意: 作成した MySQL 移植版は GPL
ライセンスの下で自由に複製および配布することができますが、これによって
MySQL の所有権が付与されるものではありません。
移植先のサーバには、有効な Posix
スレッドライブラリが必要です。我々は、Solaris 2.5
については Sun の PThread(2.4
以前のバージョンにおけるネイティブスレッドのサポートは不十分でした)、Linux
については Xavier
Leroy(<Xavier.Leroy@inria.fr>
)による LinuxThread
を使用しています。
ネイティブスレッドに関する十分なサポートがない状態で新種の
Unix に移植する際に難しいのは、MIT-pthread
の移植であると考えられます。mit-pthreads/README
と「Programming POSIX
Threads」(http://www.humanfactor.com/pthreads/)を参照してください。
MySQL 4.0.2 まで、MySQL のディストリビューションには Chris Provenzano の MIT Pthread(MIT Pthread の Web ページ(http://www.mit.edu/afs/sipb/project/pthreads/)と プログラミング入門(http://www.mit.edu:8001/people/proven/IAP_2000/))パッチ適用バージョンが含まれていました。 これらは POSIX スレッドを持たない一部のオペレーティングシステムでも使用可能です。 See 項2.3.6. 「MIT-pthreads に関する注意事項」。
別のユーザレベルスレッドパッケージである FSU Pthread (http://moss.csc.ncsu.edu/~mueller/pthreads/ を参照)を使用することもできます。 この実装は SCO への移植に使用されています。
これらの問題のテストや実例については、mysys
ディレクトリの thr_lock.c
および
thr_alarm.c
プログラムを参照してください。
サーバとクライアントのどちらにも C++
コンパイラが必要です。我々は、多くのプラットフォームで
gcc
を使用しています。上記以外で有効と確認されたコンパイラは、SPARCworks、Sun
Forte、Irix cc
、HP-UX
aCC
、IBM AIX xlC_r
)、Intel
ecc
、Compaq cxx
) です。
クライアントのみコンパイルするには、./configure
--without-server
を使用します。
サーバのみのコンパイルは、現時点ではサポートされておらず、格別の理由がない限り追加されないものと思われます。
Makefile
または configure
スクリプトを変更する必要がある場合、GNU Automake
および Autoconf も必要です。 See
項2.3.4. 「開発ソースツリーからのインストール」。
最も基本的なファイルからすべてを再作成するために必要な手順。
/bin/rm */.deps/*.P /bin/rm -f config.cache aclocal autoheader aclocal automake autoconf ./configure --with-debug=full --prefix='your installation directory' # The makefiles generated above need GNU make 3.75 or newer. # (called gmake below) gmake clean all install init-db
移植に関して問題が起きた場合、MySQL をデバッグしなければならないことがあります。 See 項E.1. 「MySQL サーバのデバッグ」。
注意: mysqld
のデバッグを開始する前に、テストプログラム
mysys/thr_alarm
および
mysys/thr_lock
を起動してください。これによって、スレッドのインストールが実行される可能性も多少あります。
MySQL
の新機能を使用している場合、以下を指定して
mysqld
の実行を試みることができます。--skip-new
を指定すると、安全でない可能性のある新機能がすべて無効になります。--safe-mode
を指定すると、問題を引き起こす可能性のある最適化の大部分が無効になります。
See 項A.4.1. 「MySQL が何度もクラッシュする場合に行うこと」。
mysqld
が起動しない場合、いずれかの
my.cnf
ファイルがセットアップの妨げとなっていないか確認する必要があります。
my.cnf
引数を mysqld
--print-defaults
でチェックし、これらの引数が使用されないように、mysqld
--no-defaults ...
で起動することができます。
mysqld
がCPU
またはメモリを消費し始めたか ``ハング''
した場合、mysqladmin processlist status
を使用して、時間のかかるクエリを実行しているユーザを確認することができます。mysqladmin
-i10 processlist status
をウィンドウで実行すると有益なケースもあります。たとえば、新しいクライアントに接続できないときにパフォーマンスの問題が起きている場合です。
コマンド mysqladmin debug
を実行すると、使用中のロック、メモリの使用容量、およびクエリの用途に関する情報が
mysql
ログファイルにダンプされ、問題解決につながることがあります。また、デバッグのために
MySQL
をコンパイルしていなくても、有益な情報を得られることもあります。
一部のテーブルの処理速度が低下する問題が起きた場合、OPTIMIZE
TABLE
または myisamchk
でテーブルの最適化を試みてください。See
章?4. データベース管理。
また、遅いクエリを EXPLAIN
でチェックする必要があります。
このマニュアルにおける OS 固有のセクションを参照し、使用環境に特有な問題について確認する必要もあります。 See 項2.6. 「オペレーティングシステム固有の注意事項」。
極めて固有な問題が起きた場合は、いつでも
MySQL
のデバッグを試みることができます。デバッグするには、--with-debug
または --with-debug=full
オプションを指定して MySQL
を設定する必要があります。 MySQL
がコンパイルされたかどうかをチェックするには、mysqld
--help
を実行します。--debug
オプションが表示されたらデバッグは有効です。この場合、mysqladmin
ver
を実行すると、mysqld
バージョンが mysql ... --debug
として表示されます。
gcc または egcs の使用時には、以下の configure 行が推奨されています。
CC=gcc CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors \ -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql \ --with-debug --with-extra-charsets=complex
これによって、libstdc++
ライブラリと C++
例外に関する問題が回避され(多くのコンパイラでは、スレッドコードで
C++
例外が発生します)、すべてのキャラクタセットのサポート付きで
MySQL がコンパイルされます。
メモリオーバーランエラーの疑いがある場合、--with-debug=full
オプションを指定して MySQL
を設定し、メモリ割当(SAFEMALLOC
)チェッカをインストールできます。ただし、SAFEMALLOC
を指定して実行すると非常に遅くなるので、パフォーマンスの問題が生じたときには
mysqld
を --skip-safemalloc
オプションで起動してください。これによって、malloc()
と free()
に対する呼び出しのたびにメモリオーバーランのチェックが無効になります。
mysqld
が --with-debug
付きのコンパイル時にクラッシュしなくなった場合、コンパイラバグまたはタイミングバグが
MySQL
で検出されたと考えられます。この場合、上記の
CFLAGS
および CXXFLAGS
変数に -g
を追加し、--with-debug
を指定しない方法を試みることができます。mysqld
がクラッシュした場合、少なくとも
gdb
を使用してアタッチするか、コアファイル上で
gdb
を実行して何が起きたか確認することは可能です。
デバッグ用に MySQL
を設定すると、多くの特別なチェック関数が自動的に有効になり、これらによって
mysqld
の状態が監視されます。
``予期しない''
状態が検出された場合、stderr
にエントリが書き込まれ、mysqld_safe
によってエラーログに送信されます。つまり、予期しない問題が
MySQL
で発生したときにソースディストリビューションを使用している場合、まず
MySQL
をデバッグ用に設定する必要があります。その後は
MySQL
メーリングリストにメールを送信し、ヘルプを依頼してください。
See 項1.7.1.1. 「MySQL メーリングリスト」。 ご利用の MySQL
バージョンに関するバグレポートまたは質問については、mysqlbug
を使用してください。
Windows 版 MySQL
ディストリビューションでは、mysqld.exe
がデフォルトでコンパイルされています(トレースファイルのサポート付き)。
mysqld
サーバが起動しないか
mysqld
サーバですぐにクラッシュが起きる場合、トレースファイルを作成して問題の検出を試みることができます。
そのためには、mysqld
をデバッグ用にコンパイルしておく必要があります。そのようにコンパイルされているか確認するには、mysqld
-V
を実行します。バージョン番号の末尾が
-debug
である場合、トレースファイルのサポート付きでコンパイルされています。
/tmp/mysqld.trace
(Windows では
C:\mysqld.trace
)内のトレースログを指定して
mysqld
サーバを起動します。
mysqld --debug
Windows では、--standalone
フラグを使用し、mysqld
がサービスとして起動されないようにする必要もあります。
コンソールウィンドウで以下を実行します。
mysqld --debug --standalone
この後、mysql.exe
コマンドラインツールを 2
番目のコンソールウィンドウで実行し、問題を再現することができます。mysqladmin
shutdown
では、mysqld
サーバを強制終了することができます。
注意: トレースファイルは非常に大きなサイズになります。 トレースファイルのサイズを小さくしたい場合、たとえば以下のように指定することができます。
mysqld
--debug=d,info,error,query,general,where:O,/tmp/mysqld.trace
(この場合、最も興味深いタグの付いた情報のみが
/tmp/mysqld.trace
に出力されます。)
これに関するバグレポートを作成する場合、不具合があると思われる行のみをトレースファイルから選択し、適切なメーリングリスト宛てに送信してください。不具合の場所を特定できない場合には、トレースファイルと完全なバグレポートを ftp://support.mysql.com/pub/mysql/secret/ まで ftp で送信してください。MySQL の開発者側で確認させていただきます。
トレースファイルは、Fred Fish による DBUG パッケージで作成されています。 See 項E.3. 「DBUG パッケージ」。
多くのシステムでは、mysqld
がクラッシュした際に、mysqld
を
gdb
から起動することで、より多くの情報を取得することもできます。
Linux で使用される旧バージョンの
gdb
の一部では、mysqld
スレッドをデバッグする際に run
--one-thread
を使用しなければなりません。この場合、一度にアクティブにできるスレッドは
1 つだけです。速やかに gdb 5.1
にアップグレードすることをお奨めします。このバージョンでは、スレッドデバッグの処理が大幅に改善されるからです。
gdb で mysqld
を実行する場合、スタックトレースを
--skip-stack-trace
で無効化し、gdb
内部で segfault
を捕捉できるようにする必要があります。
MySQL 4.0.14 以降では、mysqld に対して
--gdb
オプションを使用してください。このオプションを使用すると、SIGINT
(mysqld
を ^C
で終了し、ブレークポイントを設定するために必要)の割り込みハンドラがインストールされ、スタックトレースとコアファイル処理が無効になります。
gdb
で MySQL
をデバッグするのが非常に困難な場合があります。たとえば、古いスレッドに対するメモリが
gdb
によって解放されず、デバッグ中に大量の新規接続を連続して確立しなければならない場合です。この問題を回避するには、-O
thread_cache_size= 'max_connections +1'
を指定して mysqld
を起動します。多くの場合、-O
thread_cache_size=5'
を指定するだけで状況は大幅に改善します。
SIGSEGV シグナルで mysqld
がクラッシュした場合、Linux
上でコアダンプを取得するには、--core-file
オプションを指定して mysqld
を起動します。
このコアファイルを使用してバックトレースを作成し、mysqld
がクラッシュした理由を特定することもできます。
shell> gdb mysqld core
gdb> backtrace full
gdb> exit
See 項A.4.1. 「MySQL が何度もクラッシュする場合に行うこと」。
gdb 4.17.x 以降を Linux
で使用している場合、.gdb
ファイルを以下の情報と共にカレントディレクトリにインストールする必要があります。
set print sevenbit off handle SIGUSR1 nostop noprint handle SIGUSR2 nostop noprint handle SIGWAITING nostop noprint handle SIGLWP nostop noprint handle SIGPIPE nostop handle SIGALRM nostop handle SIGHUP nostop handle SIGTERM nostop noprint
gdb でスレッドのデバッグに問題が起きた場合、gdb 5.x をダウンロードして代用してみてください。gdb の新規バージョンでは、スレッドの処理が飛躍的に改善されています。
以下の例は、mysqld をデバッグする方法を示します。
shell> gdb /usr/local/libexec/mysqld
gdb> run
...
backtrace full # Do this when mysqld crashes
mysqlbug
で生成された上記の出力内容をメールに取り込み、通常の
MySQL
メーリングリスト宛てに送信してください。 See
項1.7.1.1. 「MySQL メーリングリスト」。
mysqld
がハングした場合、strace
や
/usr/proc/bin/pstack
のようなシステムツールを使用し、mysqld
がハングした場所を調べることができます。
strace /tmp/log libexec/mysqld
Perl DBI
インタフェースを使用している場合、デバッグ情報を有効にするには、trace
メソッドを使用するか DBI_TRACE
環境変数を設定します。 See
項11.5.2. 「DBI
インタフェース」。
一部のオペレーティングシステムでは、mysqld
が突然クラッシュするとスタックトレースがエラーログに記録されます。この情報を使用すると、mysqld
がクラッシュした場所(および理由)を確認することができます。See
項4.10.1. 「エラーログ」。
スタックトレースを取得する場合、mysqld
のコンパイルを -fomit-frame-pointer
オプション付き gcc で行わないでください。 See
項E.1.1. 「MYSQL のコンパイル(デバッグ用)」。
エラーファイルの内容が以下のとおりであるとします。
mysqld got signal 11; The manual section 'Debugging a MySQL server' tells you how to use a stack trace and/or the core file to produce a readable backtrace that may help in finding out why mysqld died Attemping backtrace. You can use the following information to find out where mysqld died. If you see no messages after this, something went terribly wrong stack range sanity check, ok, backtrace follows 0x40077552 0x81281a0 0x8128f47 0x8127be0 0x8127995 0x8104947 0x80ff28f 0x810131b 0x80ee4bc 0x80c3c91 0x80c6b43 0x80c1fd9 0x80c1686
mysqld
がクラッシュした場所を特定するには、以下を実行します。
上記の番号をファイル(たとえば
mysqld.stack
)にコピーする。
mysqld
サーバのシンボルファイルを作成する。
nm -n libexec/mysqld > /tmp/mysqld.sym
注意: 多くの MySQL
バイナリディストリビューション(この情報がバイナリ自体の内部に含まれている
"デバッグ"
パッケージは除外)には、上記のファイルが
mysqld.sym.gz
という名称で同梱されています。
ここでは、このファイルを以下のように簡単に解凍できます。
gunzip < bin/mysqld.sym.gz > /tmp/mysqld.sym
resolve_stack_dump -s /tmp/mysqld.sym -n
mysqld.stack
を実行する。
実行すると、mysqld
がクラッシュした場所が出力されます。mysqld
がクラッシュした原因をこの方法で特定できない場合には、バグレポートを作成し、上記コマンドの出力結果をバグレポートに含める必要があります。
ただし、多くの場合、スタックトレースだけでは問題の理由を特定できません。バグを見つけるか次善策を講じるには、多くの場合、mysqld
のクラッシュを引き起こしたクエリのほか、可能であれば問題を再現できるテストテースについても知る必要があります。
See 項1.7.1.3. 「バグまたは問題を報告する方法」。
注意: --log
を指定して
mysqld
を起動する前に、すべてのテーブルを
myisamchk
でチェックしてください。 See
章?4. データベース管理。
mysqld
がクラッシュまたはハングした場合、--log
を指定して mysqld
を起動する必要があります。mysqld
が再度クラッシュした場合、ログファイルの末尾を参照し、mysqld
のクラッシュを引き起こしたクエリの有無を確認できます。
ファイル名なしで --log
を使用している場合、ログは 'hostname'.log
としてデータベースディレクトリに格納されます。多くの場合、ログファイル内の最後のクエリが原因で
mysqld
がクラッシュしています。ただし、実際にそうであったかどうかを確認するため、mysqld
を再起動し、検出されたクエリを
mysql
コマンドラインツールから実行する必要があります(可能な場合)。この方法が有効な場合、完了しなかった複雑なクエリをすべてテストする必要もあります。
時間がかかる SELECT
ステートメントのすべてに対してコマンド
EXPLAIN
を実行し、インデックスが
mysqld
によって適切に使用されているかどうかを確認することもできます。
See 項5.2.1. 「EXPLAIN
構文(SELECT
に関する情報の取得)」。
実行時間の長いクエリを検索するには、--log-slow-queries
を指定して mysqld
を実行します。
See 項4.10.5. 「スロークエリログ」。
テキスト mysqld restarted
がエラーログファイル(通常は
hostname.err
という名称)に含まれている場合、mysqld
のクラッシュを引き起こしたクエリが検出されたと考えられます。この場合、myisamchk
(see
章?4. データベース管理)でテーブルをすべてチェックします。また、MySQL
ログファイル内のクエリをテストし、いずれかが無効かどうかを確認します。そのようなクエリが見つかった場合、最新バージョンの
MySQL
へのアップグレードを試みてください。アップグレードしても問題が解決せず、mysql
メールアーカイブにも有益な情報がない場合、MySQL
メーリングリストにバグをレポートする必要があります。
このメーリングリストが掲載されている
http://lists.mysql.com/
には、オンラインリストアーカイブもリンクされています。
myisam-recover
を指定して
mysqld
を起動した際、MyISAM
テーブルが
'正しく閉じられなかった' または
'クラッシュした'
とマークされている場合、そのテーブルは自動的にチェックされ、修復が試行されます。この場合、hostname.err
ファイルに 'Warning: Checking table ...'
と書き込まれます。また、テーブルの修復が必要であれば、Warning:
Repairing table
が続いて書き込まれます。これらのエラーが大量に発生した際、直前に
mysqld
が突然クラッシュしていない場合は異常であり、さらに調査しなければなりません。
See 項4.1.1. 「mysqld
コマンドラインオプション」。
mysqld
が突然クラッシュするのは、もちろん正常ではありません。ただし、その場合には、Checking
table...
メッセージを調べるのではなく、mysqld
がクラッシュした原因を探してください。
テーブルが破損しているか、更新コマンドの後に
mysqld
が必ずエラーになる場合、この問題が再現されるかテストするには以下を実行します。
MySQL
デーモンを強制終了する(mysqladmin
shutdown
を使用)。
テーブルのバックアップを作成する(修復による悪影響が生じた場合に備えるため)。
すべてのテーブルを myisamchk -s
database/*.MYI
でチェックする。問題の起きたテーブルがあれば
myisamchk -r database/table.MYI
で修復する。
テーブルの 2 次バックアップを作成する。
空き容量を増やす必要がある場合、古いログファイルを MySQL データディレクトリから削除または移動する。
mysqld
を --log-bin
で起動する。 See 項4.10.4. 「バイナリログ」。
mysqld
のクラッシュを引き起こすクエリを検索する場合、--log
--log-bin
を使用する。
テーブルがクラッシュした場合、mysqld
server
を終了する。
バックアップをリストアする。
--log-bin
を指定しないで
mysqld
サーバを起動する。
mysqlbinlog update-log-file | mysql
を指定してコマンドを再実行する。
更新ログは、hostname-bin.#
という名称で MySQL
データベースディレクトリに保存される。
テーブルが再度破損したか、上記のコマンドで
mysqld
が終了する場合、再現可能なバグが検出されている。そのようなバグは、容易に修正することが可能。テーブルとバイナリログを
ftp://support.mysql.com/pub/mysql/secret/
FTP
で送信し、当社のバグシステム(http://bugs.mysql.com/)に入力する。
サポートユーザの場合、<support@mysql.com>
で MySQL
チームに問題を通知し、迅速な修正を依頼することもできる。
スクリプト mysql_find_rows
で一部の更新ステートメントのみを実行し、問題を絞り込むこともできます。
MySQL
クライアントを統合デバッグパッケージによってデバッグするには、--with-debug
または --with-debug=full
を指定して MySQL
を設定する必要があります。 See
項2.3.3. 「一般的な configure
オプション」。
クライアントを実行する前に、MYSQL_DEBUG
環境変数を指定してください。
shell>MYSQL_DEBUG=d:t:O,/tmp/client.trace
shell>export MYSQL_DEBUG
その結果、クライアントによってトレースファイルが
/tmp/client.trace
に生成されます。
ユーザ自身のクライアントコードで問題が起きた場合、サーバに接続し、有効と確認されているクライアントでクエリを実行してみてください。そのためには、mysql
をデバッグモードで実行します(デバッグを有効にして
MySQL をコンパイルしてあることが前提)。
shell> mysql --debug=d:t:O,/tmp/client.trace
バグレポートをメール送信する場合、上記によって有益な情報を得ることができます。 See 項1.7.1.3. 「バグまたは問題を報告する方法」。
'有効と思われる'
コードでクライアントがクラッシュした場合、mysql.h
インクルードファイルが mysql
ライブラリファイルと一致するかどうかを確認する必要があります。
一般的な誤りとしては、古いバージョンの MySQL
の mysql.h
ファイルを新しい MySQL
ライブラリと共に使用することがあります。
MySQL サーバと多くの MySQL クライアントは、DBUG パッケージ(オリジナル開発者は Fred Fish)によってコンパイルされています。デバッグ用に MySQL を設定した場合、デバッグされている内容に関するトレースファイルを取得できます。 See 項E.1.2. 「トレースファイルの作成」。
デバッグパッケージを使用するには、--debug="..."
または -#...
オプションを指定してプログラムを起動します。
多くの MySQL
プログラムにはデフォルトのデバッグ文字列があり、--debug
に対してオプションを指定しなかった場合に使用されます。デフォルトのトレースファイルは通常、Unix
では /tmp/programname.trace
、Windows では
\programname.trace
です。
デバッグコントロール文字列は、以下のようにコロンで区切られた一連のフィールドです。
<field_1>:<field_2>:...:<field_N>
各フィールドの構成要素は、フラグ文字列(必須)と、後続する "," およびコンマ区切り修飾子一覧(任意)です。
flag[,modifier,modifier,...,modifier]
現時点で認識されるフラグ文字は以下のとおりです。
フラグ | 説明 |
d | 現在の状態に対して DBUG_<N> マクロからの出力を有効にする。キーワードを伴う DBUG マクロに関する出力のみが選択されるキーワード一覧が後続する場合がある。キーワード一覧が空白になっている場合、すべてのマクロに関する出力であることを示す。 |
D | 各デバッガ出力行の後の遅延。引数は遅延する時間(1/10
秒単位の数)。マシンの性能によって異なる。つまり、-#D,20
は 2 秒遅延することを示す。 |
f | デバッグとトレースの一方または両方を制限し、指定された関数の一覧にプロファイルを設定する。注意: 一覧が空白になっている場合、すべての関数が無効になる。適切な "d" または "t" フラグの指定が依然として必要。このフラグによって関数の動作が制限されるのは、関数が有効になっている場合に限られる。 |
F | デバッグまたはトレース出力の各行に対応したソースファイル名を識別する。 |
i | デバッグまたはトレース出力の各行に対応した PID またはスレッド ID を持つプロセスを識別する。 |
g | プロファイルを有効にする。プログラムのプロファイルに使用できる情報を含むファイル 'dbugmon.out' を作成する。一覧の関数のみに対してプロファイルを選択するキーワードの一覧が後続する場合がある。一覧が空白になっている場合、すべての関数が考慮される。 |
F | デバッグまたはトレース出力の各行に対応したソースファイル行番号を識別する。 |
n | デバッグまたはトレース出力の各行に対応した現在の関数のネスト深度を印刷する。 |
N | dbug 出力の各行に番号を設定する。 |
o | デバッガ出力ストリームを指定ファイルにリダイレクトする。デフォルト出力は stderr である。 |
O | o
と同様。ただし、書き込みのたびにファイルが実際にフラッシュされる。必要に応じて、ファイルは閉じられ、各書き込みの間に再度開かれる。 |
p | デバッガの操作を指定プロセスに制限する。プロセスは、DBUG_PROCESS マクロで識別され、実行されるデバッガ操作の一覧に含まれるものと一致しなければならない。 |
P | デバッグまたはトレース出力の各行に対応した現在のプロセス名を印刷する。 |
r | 新しいステータスに移行する際に、以前のステータスの関数ネストレベルを継承しない。.出力の開始位置が左マージンである場合に有効。 |
S | 0 以外の値が _sanity() から返されるまで、デバッグ対象の各関数で関数 _sanity(_file_,_line_) を実行する(メモリリークを検出するために safemalloc と共に使用されることが多い)。 |
t | 関数呼び出しの有効化/トレース行の終了。最大トレースレベルを数値で指定する一覧(修飾子が 1 つだけ含まれている)が後続する場合がある。このレベルを超えると、デバッグマクロとトレースマクロのいずれに対しても出力は実行されない。デフォルトはコンパイル時間オプションである。 |
シェルコマンドラインに表示されるデバッグコントロール文字列("-#" の一般的な用途は、アプリケーションプログラムに対するコントロール文字列の導入)の例を以下に示します。
-#d:t -#d:f,main,subr1:F:L:t,20 -#d,input,output,files:n -#d:t:i:O,\\mysqld.trace
MySQL
で出力するための一般的なタグ(d
オプション付き)は、enter
、exit
、error
、warning
、info
、loop
です。
ISAM
/MyISAM
および
HEAP
テーブルのテーブルロック、BDB
テーブルのページレベルロック、InnoDB
テーブルの行レベルロックのみが、MySQL
で現在サポートされています。 See
項5.3.1. 「MySQL のテーブルロック方法」。 INSERT
ステートメント間に競合がない場合(レコードまたはデータの削除による空き領域を埋めるのではなく、テーブルファイル末尾に追加する場合はいつでも)、MyISAM
テーブルでは INSERT
と
SELECT
をロックなしで自由に組み合わせることができます。
バージョン 3.23.33
からは、システムにおけるテーブルロックの競合を
Table_locks_waited
および
Table_locks_immediate
環境変数を確認して分析できるようになりました。
テーブル型を行レベルロックと共に使用するかどうかを決定するには、アプリケーションの処理内容とデータの選択/更新パターンを確認する必要があります。
行ロックの利点:
多数のスレッド内の異なったレコードにアクセスする際にロックの競合が少ない。
ロールバックの変更が少ない。
単一レコードを長時間ロックすることができる。
行ロックの欠点:
ページレベルロックまたはテーブルロックよりも多くのメモリを消費する。
テーブルの広範囲で実行する場合、多数のロックが必要になるため、ページレベルロックまたはテーブルロックよりも処理速度が低下する。
データの大部分で GROUP BY
を頻繁に実行するか、テーブル全体を頻繁にスキャンする必要がある場合、他のロックよりも明らかに効率が悪化する。
高いロックレベルを使用すると、タイプの異なるロックをサポートし、行レベルロックの場合と同様にロックオーバーヘッドが減少するようにアプリケーションを調整するのも容易である。
以下の場合、ページレベル/行レベルロックよりもテーブルロックの方が適しています。
大部分が読み込み
厳密なキーでの読み込みおよび更新。この場合、1 つのキー読み込みで取得できる 1 つのレコードを更新または削除する。
UPDATE table_name SET column=value WHERE unique_key# DELETE FROM table_name WHERE unique_key=#
SELECT
と
INSERT
(ならびに少数の
UPDATE
および DELETE
ステートメント)を組み合わせる。
多数のスキャンまたは GROUP BY
をテーブル全体で実行する(書き込みなし)。
行レベル/ページレベルロック以外の他のオプション:
バージョン管理(MySQL では並列 INSERT に使用)。多数の読み取りと同時に単一の書き込みが可能です。つまり、データベース/テーブルでは、ユーザがアクセスを開始した時期に基づき、異なるビューが同じデータに関してサポートされます。これはタイムトラベルにたとえることも、書き込み時コピー、コピーオンデマンドと呼ぶこともできます。
多くの場合、コピーオンデマンドは、ページレベルまたは行レベルのロックよりもはるかに優れています。ただし、最悪の場合、通常のロックよりもはるかに大量のメモリを消費します。
行レベルロックの代わりに、アプリケーションレベルロック(MySQL での get_lock/release_lock と同様)を使用することができます。言うまでもなく、このロックが役立つのは正常に動作するアプリケーションに限られます。
多くの場合、アプリケーションに最適なロックタイプは経験に基づき推測できます。しかし、指定されたロックタイプが別のロックタイプよりも好ましいと判断するのは一般的に極めて困難です。すべてがアプリケーションに依存しており、アプリケーションにおける異なった部分には異なったロックタイプが必要とされるからです。
MySQL でのロックに関するヒントを以下に示します。
多くの Web アプリケーションでは、多くの選択、一部の削除、更新が主としてキーで実行され、挿入が特定のテーブルに対して実行されます。 MySQL の基本設定は、上記に適した状態になっています。
同一テーブル内のレコードを大量に確認する必要のある更新と選択を併用しない場合、同時ユーザは問題になりません。
同一テーブルで挿入と削除を併用する場合、INSERT
DELAYED
が役立つことがあります。
また、LOCK TABLES
を使用して処理速度を向上させることもできます(単一ロックでの多数の更新は、ロックなしの更新よりもはるかに高速です)。複数のテーブルに分割するのも有効な対策です。
MySQL
でのテーブルロックに処理速度の問題がある場合、テーブルの一部をInnoDB
または BDB
テーブルに変換して解決できることもあります。
See 項7.5. 「InnoDB
テーブル」。 See 項7.6. 「BDB
または BerkeleyDB
テーブル」。
このマニュアルの最適化に関するセクションでは、アプリケーションの調整方法の多種多様な局面について取り上げています。 See 項5.2.13. 「その他の最適化のヒント」。
RTS スレッドパッケージと MySQL の併用を試みたところ、以下の問題が発生しました。
これらのパッケージでは、多数の POSIX 呼び出しが使用されるほか、すべての関数のラッパを作成するのに非常に時間がかかります。そこで、スレッドライブラリを最新の POSIX 仕様に変更した方が簡単なのではないかと考えるようになりました。
一部のラッパは作成済みです。詳細については、mysys/my_pthread.c
を参照してください。
少なくとも以下を変更する必要があります。
pthread_get_specific
では 1
つの引数が使用されます。 sigwait
では 2 つの引数が使用されます。
多くの関数(少なくとも
pthread_cond_wait
、pthread_cond_timedwait
)
からエラー時にエラーコードが返される必要があります。ここでは
-1 が返され、errno
が設定されます。
もう 1
つの問題は、ユーザレベルのスレッドによって
ALRM
シグナルが使用され、そのために多くの関数(read
、write
、open
...)が中断されることです。
MySQL
では、中断されたすべての関数における割り込みに対して再試行する必要がありますが、確認するのは容易ではありません。
解決されていない最大の問題は以下のとおりです。
スレッドレベルのアラームを取得するため、mysys/thr_alarm.c
を変更し、pthread_cond_timedwait()
でアラームとアラームの間に待機しましたが、エラー
EINTR
で中断されました。原因を調べるためにスレッドライブラリのデバッグを試みたものの、簡単な解決策は見つかりませんでした。
MySQL と RTS スレッドの併用を試みる場合、以下を行うことをお奨めします。
MySQL で使用される関数をスレッドライブラリから POSIX に変更する。 変更するのに時間はかからない。
-DHAVE_rts_threads
ですべてのライブラリをコンパイルする。
thr_alarm
をコンパイルする。
実装に若干の差異がある場合、my_pthread.h
と my_pthread.c
の変更により修正することができる。
thr_alarm
を実行する。実行時に
``警告''、``エラー''、中断メッセージのいずれも表示されなかった場合、正常に実行されています。Solaris
で正常に実行された場合の例を以下に示します。
Main thread: 1 Thread 0 (5) started Thread: 5 Waiting process_alarm Thread 1 (6) started Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 1 (1) sec Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 2 (2) sec Thread: 6 Simulation of no alarm needed Thread: 6 Slept for 0 (3) sec Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 4 (4) sec Thread: 6 Waiting process_alarm thread_alarm Thread: 5 Slept for 10 (10) sec Thread: 5 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 5 (5) sec Thread: 6 Waiting process_alarm process_alarm ... thread_alarm Thread: 5 Slept for 0 (1) sec end
MySQL は、使用されるスレッドパッケージによって大きく左右されます。そのため、MySQL に適したプラットフォームを選択する場合、スレッドパッケージは極めて重要です。
スレッドパッケージには、少なくとも以下の 3 種類があります。
単一プロセス内のユーザスレッド。スレッドの切り替えはアラームによって管理され、スレッドライブラリがすべての非スレッドセーフ関数をロックによって管理する。実行中のスレッドがデータを待機しなければならない場合、読み取り、書き込み、選択などの操作は通常、別のスレッドに切り替えるスレッド固有の select で管理される。ユーザスレッドパッケージが標準ライブラリ(古いバージョンの FreeBSD および BSDI スレッド)に統合されている場合、そのパッケージに必要なオーバーヘッドは、すべての安全でない呼び出し(MIT-pthread、FSU Pthread、RTS thread)にマッピングしなければならないスレッドパッケージよりも少なくて済む。一部の環境(たとえば SCO)では、すべてのシステムコールがスレッドセーフなので、マッピングは非常に容易である(SCO における FSU Pthread)。欠点:マッピングされたすべての呼び出しに必要な時間はごくわずかであり、あらゆる状況に対処するのが極めて難しい。通常、スレッドパッケージによって処理されないシステムコールもいくつか存在する(MIT-pthread、ソケットなど)。スレッドのスケジュールは常に最適とは限らない。
個別プロセス内のユーザスレッド。スレッド切り替えはカーネルによって行われ、すべてのデータはスレッド間で共有される。スレッドパッケージは、スレッド間でデータが共有されるように標準スレッド呼び出しを管理する。この方法は LinuxThread で使用されている。欠点:プロセスが大量。スレッド作成が遅い。1 つのスレッドがクラッシュした場合、通常は残りのスレッドがハングしているので、それらをすべて強制終了した後に再起動しなければならない。スレッド切り替えには若干のコストがかかる。
カーネルスレッド。スレッド切り替えは、スレッドライブラリまたはカーネルによって行われ、極めて高速である。すべて
1
つのプロセスで処理されるが、一部のシステムでは
ps
によって異なったスレッドが表示されることがある。1
つのスレッドが中止されると、プロセス全体が中止される。多くのシステムはスレッドセーフであり、必要とされるオーバーヘッドはごくわずかである。Solaris、HP-UX、AIX、OSF/1
にはカーネルスレッドがある。
一部のシステムでは、システムライブラリ内のユーザレベルスレッドによってカーネルスレッドが管理される。そのような場合、スレッド切り替えはスレッドライブラリによってのみ可能であり、カーネルは実際には ``スレッド対応'' ではない。
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.