分享MySQL常用 内核 Debug 几种常见方法

分享MySQL常用 内核 Debug 几种常见方法,第1张

分享MySQL常用 内核 Debug 几种常见方法 目录
  • 一、准备Debug环境
  • 二、使用GDB调试
    • 启动GDB编译器
    • GDB常用命令
    • Debug示例
      • 1、取变量值
      • 2、调试脚本
  • 三、使用Trace文件调试
    • 设置debug参数
      • Debug示例

      阅读本文你将了解:

      • 如何准备 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)

      Debug 示例

      安装好 Debug 环境后,我们用以下两个例子,来简单演示使用思路及技巧。

      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
       = {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) {
       = COM_QUERY

      三、使用 Trace 文件调试

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

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

      设置 debug 参数

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

      --debug [ = debug_options ]
      
      

      [ = debug _ options ] 可识别字符 d、t、i 、o 等。

      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 的几种常见方法。当然,仅仅起到抛砖引玉的作用,更多好玩的技巧,还需读者自行深度挖掘。

      参考:

      [2]: GDB 脚本调试:https://sourceware.org/gdb/current/onlinedocs/gdb/Commands.html#Commands

      [3]: DBUG Package[:https://dev.mysql.com/doc/refman/8.0/en/dbug-package.html

      欢迎分享,转载请注明来源:内存溢出

      原文地址:https://outofmemory.cn/sjk/2997227.html

      (0)
      打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
      上一篇 2022-09-26
      下一篇2022-09-26

      随机推荐

      • 被迫营业是什么意思?来看看这些在家&ldquo;被迫营业&rdquo;的孩子们都经历了什么

        被迫营业,就是被迫开始工作的意思,虽不情愿但也要完成的工作,带点强颜欢笑的色彩。比如:下班了,刚准备休息,结果微信等各种工作群响个不停,偶尔还会被小窗,只能“被迫营业”。被迫营业通常指虽不情愿但也要完

        2022-12-06
        000
      • 兽人永不为奴什么意思

        兽人永不为奴,来自于《魔兽世界:德拉诺之王》宣传CG中格罗姆·地狱咆哮之口。战歌氏族族长为了胜利不息带领手下并第一个喝下恶魔之血并且变成绿皮肤的兽人格罗姆地狱咆哮。并且‌‌‌‌‌‌‌受到嗜血的诅咒。视

      • 饭圈用语pb是什么意思

        pb,在饭圈是“photobook(写真集相册)”的意思。通常为站所追明星通告或活动时拍出的照片所集合成的相册集,一般这类照片集作为会作为周边进行售出。pb里有什么:1、photobook 站姐把拍的

        2022-12-06
        000
      • 网络语神颜、神仙颜值是什么意思

        神仙颜值,简称神颜,形容某人或某物的脸实在太好看了,简直就是人间极品,绝艳美色堪比天上仙人之颜,一般都用粉丝对作明星的彩虹屁。可以用来夸爱豆颜值。就是非常美,美到无法形容。一般描述神仙颜值下面是要配图

      • 贝勒是皇帝的什么人

        贝勒是清朝皇室爵位的一种,贝勒可以是皇帝的儿子,可以是亲王郡王的儿子,也可以是清朝宗室之后。清朝皇帝儿子中没有爵位的被称为阿哥,有了爵位的话就会被封为贝勒,亲王等等,贝勒跟皇帝不一定是父子关系,但一

        2022-12-06
        000
      • 嘉庆皇帝死了谁继位了

        很多人爱看清宫剧,不过清宫剧中大多是清朝从康熙到乾隆的历史,康熙、雍正、乾隆三位皇帝的历史剧多的数不胜数。关于乾隆帝之后很多人都知道是令妃的儿子也就是嘉庆皇帝

        2022-12-06
        000
      • 吕布怎么死的

        吕布是被曹操缢死的。吕布骁勇善战,有人称他为三国第一武将,武功了得却刚愎自用,有勇无谋,不识忠奸,甚至有些荒淫无度。如果说兵败被曹军杀死是果的话,那么个人的性

        2022-12-06
        000
      • 弘治皇帝为什么短命

        朱祐樘驾崩于乾清宫,年仅36岁。根据史料记载弘治帝病死前乐忠于求丹药长生,大多数人认为弘治帝是食用了含重金属的丹药后中毒而死的。历史上很多皇帝寿命不长,英年早逝似乎是很多君王的命运。他在弥留之际病重,

        2022-12-06
        000
      • 养心殿是干什么的

        养心殿一开始是皇帝们建起来休养生息的,但是从清朝雍正那一代开始就成了皇帝的正宫,自此以后就没有皇帝再居住过乾清宫了。养心殿的历史也比较悠久了,从明朝的嘉靖年间建立起来以后就没有再进行较大的修缮,而且有

      发表评论

      登录后才能评论

      评论列表(0条)

        保存