工具 | 常用 MySQL 内核 Debug 技巧
作者:柯煜昌 顾问软件工程师
目前从事 RadonDB MySQL 容器化研发,华中科技大学研究生毕业,有多年的数据库内核开发经验。
掌握 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 环境后,我们用以下两个例子,来简单演示使用思路及技巧。
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 ] 可识别字符 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 的几种常见方法。当然,仅仅起到抛砖引玉的作用,更多好玩的技巧,还需读者自行深度挖掘。
参考
[1]: GDB cheat sheet:https://gist.github.com/rkubik/b96c23bd8ed58333de37f2b8cd052c30
[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
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
是的,我们又获奖了!
喜事连连!优麒麟在获得中国信息通信研究院颁发的“可信开源项目”评估证书之后,再获“优秀开源创新企业”、“2021 年度 OSCHINA 优秀技术团队”称号。 “优秀开源创新企业” “优秀开源创新企业”评选由中国开源云联盟组织开展,其目的是推动国内开源生态产业发展,从贡献者、项目、应用案例、企业四个维度综合评选得出。优麒麟是由麒麟软件有限公司主导开发的全球开源项目,通过投票、答辩、专家评审,最终荣获中国开源云联盟授予的“2021 优秀开源创新企业”称号。 “2021年度OSCHINA优秀技术团队” “2021 年度 OSCHINA 优秀技术团队”由 OSCHINA 开源技术社区评选颁发。在综合评估优麒麟社区运营活跃度、技术文章产出质量等多方面的维度后,为优麒麟颁发了“2021 年度 OSCHINA 优秀技术团队”奖项。 此番获奖不仅是优麒麟社区的荣誉,也是全体社区成员的共同荣誉,是大家共同努力的结果,促使优麒麟社区蓬勃发展。未来,优麒麟将在营造良好开源生态和技术发展方面持续努力,也期待越来越多的爱好者参与进来,为建设开源、贡献开源添砖加瓦! 优麒麟社区自 2013 年成立以来,已累计发...
- 下一篇
鲸鲮 JingOS V1.1.1 新版发布
国产移动操作系统——JingOS又有新消息! 近日,JingOS又发布更新版本 V1.1.1,对视频、网络、触控等问题进行了优化。同时,解决了部分已知的Android App (安卓应用)支持问题,进一步提升了系统整体的稳定性和兼容性。 JingOS V1.1.1发版日志: 支持本地视频硬解码 支持WP2/WPA3兼容AP 支持触控板单指按下+滑动,及双指按下操作 文件管理器支持MTP功能 优化视频/音频/图片插件性能 Android兼容V0.7发版说明 注意 Android 应用程序支持包 (JAAS) 已集成到操作系统中。 但是,您仍然需要使用以下命令来安装环境。 如果您想测试 JAAS,请不要安装其他 android 容器。 1.支持4种Input设备:键盘,触控板(鼠标),触摸屏,手写笔 2.支持输入法 3.重启后黑屏、快捷面板图标丢失且重启无法恢复的问题 4.竖屏应用的显示问题(目前改为强制横屏) 镜像下载地址: JingOS官方论坛 gitee GitHub Google Drive
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果