E. 移植到其他系统 / E.1. 调试MySQL服务器 / E.1.3. 在gdb环境下调试mysqld

如果mysqld崩溃了,在大多数系统上,你也可是从gdb启动mysqld来获取更多信息。

Linux上,有一些老版本的gdb,如果你想要能调试mysqld线程,你必须使用run --one-threadsome。在这种情况下,你可以一次只激活一个线程。我们推荐你升级到gdb 5.1 ASAP ,这个版本上线程调试工作得更好!

NTPL 线程(Linux上的新线程库)可能会在gdb下运行mysqld时遇到问题。一些症状如下:

  • mysqld 在启动过程中挂起(在它写ready for connections之前)。

  • mysqld 在调用pthread_mutex_lock()或pthread_mutex_unlock()过程中崩溃。

在这种情况下你应该在启动gdb之前在外壳上设置如下环境变量:

LD_ASSUME_KERNEL=2.4.1
export LD_ASSUME_KERNEL

gdb下运行mysqld时,你应该用--skip-stack-trace来禁止堆栈跟踪,以便能捕获gdb内的段错误。

在MySQL 4.0.14和以上版本,你应该对mysqld使用--gdb选项。 这会为SIGINT安装一个中断处理器(需要用^C停止mysqld来设置断点),并且禁止堆栈跟踪和核心文件处理。

gdb没有给旧线程释放内存的整个时间里,如果你做了大量的新连接,在gdb下调试MySQL是非常困难的。你可以通过带 -O thread_cache_size= 'max_connections +1' 启动mysqld 来避免这个问题。在多数情况下,只使用-O thread_cache_size=5'就受益无穷了!

如果mysqld带着SIGSEGV信号死掉了,而你想在Linux上转储核心,你可以带--core-file选项启动mysqld。这个核心文件可以被用来生成 向后跟踪,它可以帮你找出mysqld 为何死掉:

shell> gdb mysqld core
gdb>   backtrace full
gdb>   exit

请参阅A.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

把上面的输入写进一个用mysqlbug生成的邮件里,发送到综合MySQL邮件列表。请参阅1.7.1.1节,“MySQL 邮件列表”

如果mysqld 挂起,你可以试着用一些诸如strace 或 /usr/proc/bin/pstack 这样的系统工具连检查mysqld 在哪里挂起。

strace /tmp/log libexec/mysqld

如果你使用 Perl DBI 接口,你可以使用trace方法或设置DBI_TRACE环境变量来打开调试信息。