Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
EPUB - 7.5Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


24.4.1.4 gdb での mysqld のデバッグ

ほとんどのシステムでは、mysqld がクラッシュした場合に詳細な情報を取得するために、gdb からも mysqld を起動できます。

Linux の一部の古い gdb バージョンでは、mysqld のスレッドをデバッグできるようにするには、run --one-thread を使用する必要があります。この場合、一度にアクティブにできるのは 1 つのスレッドのみです。スレッドのデバッグは gdb 5.1 のほうがより良く機能するため、このバージョンにアップグレードすると最適です。

gdbmysqld を実行すると、NPTL スレッド (Linux の新しいスレッドライブラリ) に起因する問題が発生することがあります。次のような現象が発生します。

  • mysqld が起動中 (「接続準備完了」と出力される前) にハングアップする。

  • mysqldpthread_mutex_lock() または pthread_mutex_unlock() の呼び出し中にクラッシュする。

この場合、gdb を起動する前に、シェルで次の環境変数を設定してください。

LD_ASSUME_KERNEL=2.4.1
export LD_ASSUME_KERNEL

gdbmysqld を実行するときは、--skip-stack-trace を使用してスタックトレースを無効にし、gdb 内でセグメンテーション違反を捕捉できるようにする必要があります。

MySQL 4.0.14 以降では、mysqld--gdb オプションを使用してください。これにより、SIGINT 用の割り込みハンドラ (mysqld^C で停止してブレークポイントを設定するために必要となります) がインストールされ、スタックトレースおよびコアファイル処理が無効になります。

新しい接続が常時多数発生する場合、gdb は古いスレッドのメモリーを解放しないため、gdb で MySQL をデバッグすることは非常に困難です。この問題を回避するには、thread_cache_sizemax_connections + 1 に等しい値に設定して mysqld を起動します。ほとんどの場合、--thread_cache_size=5' を使用するだけでもかなり改善されます。

SIGSEGV シグナルが発生して mysqld が異常終了したときに Linux でコアダンプを取得する場合は、--core-file オプションを指定して mysqld を起動します。このコアファイルは、mysqld が異常終了した理由を見つけるために役立つことがあるバックトレースを作成するために使用できます。

shell> gdb mysqld core
gdb>   backtrace full
gdb>   quit

セクションB.5.4.2「MySQL が繰り返しクラッシュする場合の対処方法」を参照してください。

Linux で gdb 4.17.x 以降を使用している場合は、次の情報を持つ .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

上記の出力をバグレポートに含め、セクション1.7「質問またはバグをレポートする方法」の手順を使用してバグレポートを提出できます。

mysqld がハングアップした場合は、strace/usr/proc/bin/pstack などのシステムツールを使用して、mysqld がハングアップした場所を調査できます。

strace /tmp/log libexec/mysqld

Perl の DBI インタフェースを使用している場合は、trace メソッドを使用するか、DBI_TRACE 環境変数を設定することによって、デバッグ情報をオンにできます。


User Comments
  Posted by Martin Mokrejs on November 4, 2002
On Solaris you can use instead of strace system
utility called truss. For example, "truss
-t\!ioctl,\!lseek,\!stat,\!fstat,\!fstat64 -e
-vall -xall -a -f ./mysqld"
  Posted by Martin Mokrejs on November 4, 2002
To debug under a newly started process, chdir() to
the source tree, compile mysql using -g3 CFLAGS
option at the best and run:

# gdb ./sql/mysqld

(gdb) set args --datadir=/data/mysql2
--basedir=/usr/local/mysql-BK20021104
--pid-file=/usr/local/mysql/var/kulan.pidd
--port=3307 --socket=/tmp/mysql2.sock

(gdb) break mysqld.cc:2039

(gdb) break open() <- stop on every open() call

(gdb) run <- run until we reach our breakpoint

(gdb) where <- where are we now in the sources?

(gdb) l <- list source code

(gdb) s <- step

(gdb) n <- next

(gdb) p varname <- print variable contents

(gdb) quit
  Posted by Martin Mokrejs on November 20, 2002
To debug an already running mysqld process and see
what happens to it if you issue a specific SQL
command from the interactive mysql session, you
have to figure out first to which PID you have to
connect. Issue from you client commands line
"SELECT 3+3" and figure out the PID. (Sinisa says
that you can in principle connect to any mysqld
process and switch context to access another
thread, but NOT on Linux these days yet. Use `info
threads' command at the gdb prompt in such case)

chdir() to unpacked source tree. At the best,
compile next time mysql using CFLAGS="-g3".

# gdb
(gdb) attach 1234
(gdb) detach
(gdb) break sql_parse.cc:981
(gdb) b pthread_mutex_unlock
(gdb) info break
(gdb) attach 12345
(gdb) c
(gdb) s
(gdb) n
(gdb) where
(gdb) l
(gdb) detach
(gdb) quit
  Posted by Martin Mokrejs on January 16, 2003
Where to set breakpoints as a general start place?
In client in real_connect(). On the server in handle_connections(), but in version above 4.0.8 it got renamed, so use handle_one_connection() for example.
Sign Up Login You must be logged in to post a comment.