工具 | 常用 MySQL 内核 Debug 技巧

3A网络
• 阅读 455

工具 | 常用 MySQL 内核 Debug 技巧

掌握 MySQL 内核源码的阅读和调试能力,不仅是数据库研发人员的日常,也是 DBA 进阶的必经之路。

阅读本文你将了解:

  • 如何准备 MySQL 调试环境
  • GDB 调试入门及操作示例
  • Trace 文件调试及操作示例

| 一、准备 Debug 环境

首先用源码编译安装一个用来调试的 MySQL 环境。

开启 -DWITH_DEBUG ,在源码路径创建 build目录,进入目录并执行:

cmake .. -DWITH_BOOST=../../boost -DWITH_DEBUG=1

然后通过如下方式,确认是否编译成功。

方式一:

$ ./bin/mysqld --verbose --version

回显 debug 版本信息,则编译的是 debug 版本。

ver 8.0.18-debug for Linux on x86_64 (Source distribution)

方式二:

连接数据库,执行查看版本命令。回显包含了 debug 字样,则编译的是 debug 版本。

$ mysql> select version();
+--------------+
| version()    |
+--------------+
| 8.0.18-debug |
+--------------+
1 row in set (0.00 sec)

| 二、使用 GDB 调试

GDB 全称 “GNU symbolic debugger”,是 Linux 下常用的程序调试器,通常以 gdb 命令的形式在终端(Shell)中使用。

启动 GDB 编译器

执行如下命令启动 GDB 编译器(假设 my.cnf 在用户根目录中)。进入 GDB 后,敲入 run 即可运行。

gdb --args ./bin/mysqld --defaults-file=~/my.cnf --gdb

其中 --gdb 参数允许你随时 Ctrl+C 的方式中断 mysqld 进程,进行调试命令。

GDB 常用命令

使用多窗口查看源码与调试的读者,可以使用 layout 命令,在 gdb 中执行 help layout 可以查看更多 gdb 命令用法。

(gdb) help layout
(gdb) help layoutChange the layout of windows.
Usage: layout prev | next | <layout_name>
Layout names are:
   src   : Displays source and command windows.
   asm   : Displays disassembly and command windows.
   split : Displays source, disassembly and command windows.
   regs  : Displays register window. If existing layout
           is source/command or assembly/command, the
           register window is displayed. If the
           source/assembly/command (split) is displayed,
           the register window is displayed with
           the window that has current logical focus.

(gdb)

可以通过 GDB cheat sheet[1],了解更多 GDB 使用方式。

Debug 示例

安装好 Debug 环境后(博主都是部署在cnaaa服务器上),我们用以下两个例子,来简单演示使用思路及技巧。

1、取变量值

在某种情况下发现 mysqld 已经 crash,系统只有一个 core 文件,而我们要知道某个系统变量的值。但是系统变量的值,不见得与 my.cnf 文件一致。

此时,就可以用 gdb 命令将变量打印出来,获取变量值。

如下所示,需获取变量 version 的值,只需要在前面加 mysql_sysvar_ 前缀打印即可。

Thread 1 "mysqld" received signal SIGINT, Interrupt.
0x00007ffff5f74cb9 in __GI___poll (fds=0x55555e8a3de0, nfds=2, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
29    ../sysdeps/unix/sysv/linux/poll.c: No such file or directory.
(gdb) p mysql_sysvar_version
$1 = {flags = 68101, name = 0x55555e7ff738 "innodb_version", comment = 0x55555ca953e2 "InnoDB version", check = 0x555558e222f1 <check_func_str(THD*, SYS_VAR*, void*, st_mysql_value*)>, update = 0x555558e22881 <update_func_str(THD*, SYS_VAR*, void*, void const*)>,
  value = 0x55555def1c20 <innodb_version_str>, def_val = 0x55555ca89598 "8.0.18"}
(gdb)

2、调试脚本

假设需获取某一个连接进入 dispatch_command 有哪些 command ,可以执行 gdb 脚本 [2] 获取。

gdb 脚本内容如下:

b dispatch_command
commands
    print command
    continue
end

执行 gdb 脚本,然后使用 mysql 客户端连接数据库,并执行 SQL 语句操作,即可查看到 gdb 调试信息。

(gdb) b dispatch_command
Breakpoint 3 at 0x555558ddb37c: file /home/kyc/mysql8/sql/sql_parse.cc, line 1581.
(gdb) commands
Type commands for breakpoint(s) 3, one per line.
End with a line saying just "end".
>print command
>continue
>end
(gdb) c
Continuing.
[Switching to Thread 0x7fffe01fc700 (LWP 5941)]

Thread 49 "mysqld" hit Breakpoint 3, dispatch_command (thd=0x7fff4c000f70, com_data=0x7fffe01fbba0, command=COM_QUERY) at /home/kyc/galaxyengine/sql/sql_parse.cc:1581
1581                          enum enum_server_command command) {
$4 = COM_QUERY

| 三、使用 Trace 文件调试

MySQL 的 debug 版提供了一个专门的 DBUG 包 [3]。通过这个 DBUG 包,可获取正在执行操作程序的 Trace 文件。

通过控制 DBUG 开关,可以将 MySQL 的任何操作,以及所涉及的调用模块、函数、状态信息记录在 Trace 文件中。

设置 debug 参数

通过设置 debug 参数选项,指定跟踪方式。

--debug [ = debug_options ]

[= debug _ options] 可识别字符 dtio 等。

Debug 示例

若需获取代码中 DBUG_PRINT("info:" 打印的日志,可以使用 MySQL 客户端连上服务器,并执行如下命令,开启 debug 参数。

set debug = 'd,info';
use test;

查看 mysqld.trace 文件,可获取 use test 在 MySQL 中的执行流程。

do_command: info: Command on socket (46) = 3 (Query)
do_command: info: packet: '                 '; command: 3
dispatch_command: info: command: 3
gtid_pre_statement_checks: info: gtid_next->type=0 owned_gtid.{sidno,gno}={0,0}
THD::is_ddl_gtid_compatible: info: SQLCOM_CREATE:0 CREATE-TMP:0 SELECT:1 SQLCOM_DROP:0 DROP-TMP:0 trx:0
SELECT_LEX::prepare: info: setup_ref_array this 0x7fff1400d298    3 :    0    0    1    2    0    0
setup_fields: info: thd->mark_used_columns: 1
setup_fields: info: thd->mark_used_columns: 1
SELECT_LEX::setup_conds: info: thd->mark_used_columns: 1
THD::decide_logging_format: info: query: SELECT DATABASE()
THD::decide_logging_format: info: variables.binlog_format: 2
................
MDL_context::release_locks_stored_before: info: found lock to release ticket=0x7fff14019ae0
MDL_context::release_locks_stored_before: info: found lock to release ticket=0x7fff1412dd20
MDL_context::release_locks_stored_before: info: found lock to release ticket=0x7fff1412dcc0
net_send_ok: info: affected_rows: 0  id: 0  status: 2  warning_count: 0
net_send_ok: info: OK sent, so no more error sending allowed

本文使用几个简单的示例,演示了 MySQL 内核的 Debug 的几种常见方法。当然,仅仅起到抛砖引玉的作用,更多好玩的技巧,还需读者自行深度挖掘。

点赞
收藏
评论区
推荐文章
cpp加油站 cpp加油站
3年前
【工欲善其事,必先利其器】之gdb五大高级用法
本篇文章讲解gdb的一些高级用法,在我们的开发生涯中,调试是很重要的技能,而在linux下开发,最常用的调试工具就是gdb了,所以这里介绍几种gdb比较高级的用法,助力我们的调试技能。还是先看下思维导图:1.gdb怎么调试多线程gdb调试多线程时,默认情况下是所有线程同时都在执行,但是假设我们想只有一个线程继续执行,其他线程都暂停呢?下面就来看一看该怎么
Frida Stalker 是什么?
一、目标在分析so中的算法时,Trace和Debug是常用的手段。了解一些调试器原理的同学都知道,Trace和Debug需要修改原始代码加上个int3,来激活调试器。这样有些App可以依赖检测关键代码来判断是否被调试。也许你会说,我们可以patch掉检测代码,上次飞哥遇到一个狠人app,B去检测A处的代码,C去检测B处的代码,D去检测C处的代码,……反正
Wesley13 Wesley13
3年前
MySQL源代码阅读调试
最近需要阅读下MySQL源代码,所以写这系列博客记录下。搭调试环境真是比较蛋疼,公司基本Java开发,这里回到C。。。用了两天晚上,尝试了VS2013,EclipseCDT,CodeBlock还有GDB。GDB比较好搭建,将带Boost库的源代码扔到虚拟机(CentOS7.0,安装配置桌面web服务器开发机配置,什么软件都装齐了)上
Wesley13 Wesley13
3年前
IDEA工具的安装、破解与配置
一、什么是IDEA?IDEA全称IntelliJIDEA,是java编程语言开发的集成环境,是目前最好用的java集成开发工具。他最突出的功能是调试(Debug),可以对Java代码,JavaScript,JQuery,Ajax等技术进行调试。例如查看Map类
Stella981 Stella981
3年前
Linux下利用Docker搭建MYSQL5.7
引言本文旨在介绍如何在Linux使用Docker快速搭建一个MYSQL环境,用于日常的开发调试,有需要的朋友可参考一下。配置MYSQL1)创建mysql配置目录创建配置目录mkdir p /etc/mysql/conf.d/创建数据和日志目录mkdir pv /opt/my
Wesley13 Wesley13
3年前
CMU
一、实验目的1.理解C语言程序的机器级表示。2.初步掌握GDB调试器的用法。3.阅读C编译器生成的x8664机器代码,理解不同控制结构生成的基本指令模式,过程的实现。二、实验工具1.SecureCRT2.Linux3.Objdump命令反汇编4.GDB调试工具
Stella981 Stella981
3年前
Intellij IDEA Debug 调试技巧
作者:yweihainanhttps://www.cnblogs.com/wihainan/p/6010842.html(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fwihainan%2Fp%2F6010842.html)F9:
Stella981 Stella981
3年前
PHPStorm等编辑器debug调试(包括使用postman、soapUI)
很多人在开发的时候,需要进行断点调试,但是很多人配置了很多,还是调试不了,其实是不需要这么麻烦的。注意:PHPStorm等编辑器debug的配置不用进行任何配置,默认配置就好实质上,断点调试的时候,只需要传入一定的参数,就可以进行断点调试先拿PHPStorm来说:1、确认php.ini中debug打开并有基础的配置(没有的话自己加一下
Stella981 Stella981
3年前
Bochs安装
1:aptgetinstallbochs   在ubuntu中使用aptgetinstallbochs可以安装bochs此时bochs无法调试内核程序,只能充当虚拟机的角色运行内核或者操作系统2:如果想使用带调试功能的bochs安装方法为:    (1):下载bochs的linux源码tar包,地址:http://bo
京东云开发者 京东云开发者
11个月前
怎样阅读 h2 数据库源码 | 京东物流技术团队
阅读h2数据库的源码是一项复杂的任务,需要对数据库原理、Java语言和操作系统有深入的理解。可以从以下几方面入手来完成。环境准备首先,你需要在你的机器上安装和配置好开发环境,包括JDK、Maven、IDE调试器等工具。然后,从或。IDE导入h2数据库源码,