在某些操作系统上,如果mysqld意外终止,则错误日志包含堆栈跟踪。您可以使用它来找出mysqld在哪里(也许为什么)
死了。请参阅第 5.4.2 节,“错误日志”。要获得堆栈跟踪,您不得使用
gcc 选项编译mysqld 。-fomit-frame-pointer
请参阅
第 5.8.1.1 节,“编译 MySQL 以进行调试”。
错误日志中的堆栈跟踪看起来像这样:
mysqld got signal 11;
Attempting 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_bottom = 0x41fd0110 thread_stack 0x40000
mysqld(my_print_stacktrace+0x32)[0x9da402]
mysqld(handle_segfault+0x28a)[0x6648e9]
/lib/libpthread.so.0[0x7f1a5af000f0]
/lib/libc.so.6(strcmp+0x2)[0x7f1a5a10f0f2]
mysqld(_Z21check_change_passwordP3THDPKcS2_Pcj+0x7c)[0x7412cb]
mysqld(_ZN16set_var_password5checkEP3THD+0xd0)[0x688354]
mysqld(_Z17sql_set_variablesP3THDP4ListI12set_var_baseE+0x68)[0x688494]
mysqld(_Z21mysql_execute_commandP3THD+0x41a0)[0x67a170]
mysqld(_Z11mysql_parseP3THDPKcjPS2_+0x282)[0x67f0ad]
mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0xbb7[0x67fdf8]
mysqld(_Z10do_commandP3THD+0x24d)[0x6811b6]
mysqld(handle_one_connection+0x11c)[0x66e05e]
如果跟踪的函数名称解析失败,则跟踪包含的信息较少:
mysqld got signal 11;
Attempting 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_bottom = 0x41fd0110 thread_stack 0x40000
[0x9da402]
[0x6648e9]
[0x7f1a5af000f0]
[0x7f1a5a10f0f2]
[0x7412cb]
[0x688354]
[0x688494]
[0x67a170]
[0x67f0ad]
[0x67fdf8]
[0x6811b6]
[0x66e05e]
在后一种情况下,您可以使用 resolve_stack_dump实用程序通过以下过程 确定 mysqld死在哪里:
将堆栈跟踪中的数字复制到一个文件中,例如
mysqld.stack
. 数字不应包括周围的方括号:0x9da402 0x6648e9 0x7f1a5af000f0 0x7f1a5a10f0f2 0x7412cb 0x688354 0x688494 0x67a170 0x67f0ad 0x67fdf8 0x6811b6 0x66e05e
为mysqld服务器 创建一个符号文件:
$> nm -n libexec/mysqld > /tmp/mysqld.sym
如果mysqld不是静态链接的,请改用以下命令:
$> nm -D -n libexec/mysqld > /tmp/mysqld.sym
如果要解码 C++ 符号,请使用 nm
--demangle
(如果可用) 。如果您的 nm版本没有此选项,则必须在生成堆栈转储后 使用c++filt命令来分解 C++ 名称。执行以下命令:
$> resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stack
如果您无法在您的符号文件中包含 demangled C++ 名称,请 使用c++filt处理resolve_stack_dump输出 :
$> resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stack | c++filt
这打印出mysqld死亡的地方。如果这不能帮助您找出 mysqld 死机的原因,您应该创建错误报告并将前面命令的输出包含在错误报告中。
然而,在大多数情况下,仅仅通过堆栈跟踪并不能帮助我们找到问题的原因。为了能够定位错误或提供解决方法,在大多数情况下,我们需要知道杀死 mysqld的语句,最好是测试用例,以便我们可以重复问题!请参阅 第 1.6 节,“如何报告错误或问题”。
较新版本的glibc
堆栈跟踪函数还会打印相对于对象的地址。在
glibc
基于 的系统 (Linux) 中,插件中意外退出的跟踪类似于:
plugin/auth/auth_test_plugin.so(+0x9a6)[0x7ff4d11c29a6]
要将相对地址 ( +0x9a6
) 转换为文件名和行号,请使用以下命令:
$> addr2line -fie auth_test_plugin.so 0x9a6
auth_test_plugin
mysql-trunk/plugin/auth/test_plugin.c:65
addr2line实用程序是
binutils
Linux 上软件包
的一部分。
在 Solaris 上,过程是相似的。Solaris
printstack()
已经打印出相对地址:
plugin/auth/auth_test_plugin.so:0x1510
要翻译,请使用此命令:
$> gaddr2line -fie auth_test_plugin.so 0x1510
mysql-trunk/plugin/auth/test_plugin.c:88
Windows 已经打印出地址、函数名称和行:
000007FEF07E10A4 auth_test_plugin.dll!auth_test_plugin()[test_plugin.c:72]