GDB调试MySQL

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 在学习Oracle的时候使用GDB调试,主要是关于学习Oracle的闩锁原理,那么,为什么要用GDB调试MySQL: 1.识别故障 2.场景重现 3.创建测试案例确认BUG 4.定位缺陷根源 5.测试和创建补丁修复BUG
GDB主要帮助我们完成下面四个方面的功能:
1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
3、当程序被停住时,可以检查此时你的程序中所发生的事。
4、你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。

在学习Oracle的时候使用GDB调试,主要是关于学习Oracle的闩锁原理,那么,为什么要用GDB调试MySQL:
1.识别故障
2.场景重现
3.创建测试案例确认BUG
4.定位缺陷根源
5.测试和创建补丁修复BUG

下面开始学习GDB调试MySQL
1、安装编译MySQL需要的软件包
yum install -y cmake make gcc gcc-c++ ncurses-devel bison gdb

2、编译MySQL
# git clone https://github.com/mysql/mysql-server.git
# cd mysql-server
# git checkout mysql-5.7.19
# cd BUILD; cmake .. -DDOWNLOAD_BOOST=1 -DWITH_DEBUG=1 -DWITH_UNIT_TESTS=off
# make
# make install

3、连接MySQL程序
3.1、查看MySQL进程ID
[root@debug ~]# ps -ef | grep mysql
root     24589     1  0 07:58 ?        00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --user=mysql
mysql    24794 24589  0 07:58 ?        00:00:01 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/usr/local/mysql/data/mysql-debug.log --pid-file=debug.pid --socket=/tmp/mysql.sock --port=3306
root     25009 24993  0 11:29 pts/2    00:00:00 grep mysql

3.2、GDB使用attach连接MySQL进程ID
[root@debug ~]# gdb
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-92.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) attach 24794
Attaching to process 24794
Reading symbols from /usr/local/mysql/bin/mysqld...done.
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done.
[New LWP 24969]
[New LWP 24824]
[New LWP 24821]
[New LWP 24820]
[New LWP 24819]
[New LWP 24818]
[New LWP 24817]
[New LWP 24816]
[New LWP 24815]
[New LWP 24814]
[New LWP 24813]
[New LWP 24812]
[New LWP 24811]
[New LWP 24810]
[New LWP 24809]
[New LWP 24808]
[New LWP 24806]
[New LWP 24805]
[New LWP 24804]
[New LWP 24803]
[New LWP 24802]
[New LWP 24801]
[New LWP 24800]
[New LWP 24799]
[New LWP 24798]
[New LWP 24797]
[New LWP 24796]
[New LWP 24795]
[Thread debugging using libthread_db enabled]
Loaded symbols for /lib64/libpthread.so.0
Reading symbols from /lib64/libcrypt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libcrypt.so.1
Reading symbols from /lib64/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/libdl.so.2
Reading symbols from /lib64/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/librt.so.1
Reading symbols from /usr/lib64/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib64/libstdc++.so.6
Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libgcc_s.so.1
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from /lib64/libfreebl3.so...(no debugging symbols found)...done.
Loaded symbols for /lib64/libfreebl3.so
Reading symbols from /lib64/libnss_files.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/libnss_files.so.2
0x00007f8801dfd383 in poll () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.209.el6_9.2.x86_64 libgcc-4.4.7-18.el6.x86_64 libstdc++-4.4.7-18.el6.x86_64 nss-softokn-freebl-3.14.3-23.el6_7.x86_64

4、设置断点
4.1、查看插入语句的源码sql_insert.cc的423行的函数 Sql_cmd_insert::mysql_insert
bool Sql_cmd_insert::mysql_insert (THD *thd,TABLE_LIST *table_list)
{
  DBUG_ENTER("mysql_insert");

  LEX *const lex= thd->lex;
  int error, res;
  bool err= true;
  bool transactional_table, joins_freed= FALSE;
  bool changed;
  bool is_locked= false;
  ulong counter= 0;
  ulonglong id;

4.2、在session1中的gdb设置insert的断点
(gdb) b Sql_cmd_insert::mysql_insert
Breakpoint 1 at 0x17bd1b9: file /root/mysql-server/sql/sql_insert.cc, line 423.

4.3、查看断点信息,从下往上看,使用到了多个MySQL函数。
(gdb) bt
#0  0x00007f8801dfd383 in poll () from /lib64/libc.so.6
#1  0x00000000016c1155 in Mysqld_socket_listener::listen_for_connection_event (this=0x45d8870)
    at /root/mysql-server/sql/conn_handler/socket_connection.cc:852
#2  0x0000000000ece89c in Connection_acceptor<Mysqld_socket_listener>::connection_event_loop (this=0x45b5ec0)
    at /root/mysql-server/sql/conn_handler/connection_acceptor.h:66
#3  0x0000000000ec6226 in mysqld_main (argc=17, argv=0x3ab4248) at /root/mysql-server/sql/mysqld.cc:5045
#4  0x0000000000ebd2d4 in main (argc=9, argv=0x7fffb2aa7408) at /root/mysql-server/sql/main.cc:25

4.4、在设置了断点之后,在另一个session2中登录数据库,发现无法登录,hung住了,在gdb中执行next(执行下一步代码),可以看到在socket_connection.cc源码第859行无法继续,代码大致是说要获取系统的socket,还有一些监听信息,由于太多了,直接在gdb中执行 continue (到下一个可执行的代码),此时session2已经登录成功。
(gdb) n
Single stepping until exit from function poll,
which has no line number information.
Mysqld_socket_listener::listen_for_connection_event (this=0x45d8870) at /root/mysql-server/sql/conn_handler/socket_connection.cc:859
859       if (retval < 0 && socket_errno != SOCKET_EINTR)
(gdb) n
871       if (retval < 0 || abort_loop)
(gdb) n
876       MYSQL_SOCKET listen_sock= MYSQL_INVALID_SOCKET;
(gdb) n
877       bool is_unix_socket= false;
(gdb) n
879       for (uint i= 0; i < m_socket_map.size(); ++i)
(gdb) n
881         if (m_poll_info.m_fds[i].revents & POLLIN)
(gdb) n
879       for (uint i= 0; i < m_socket_map.size(); ++i)
(gdb) n
881         if (m_poll_info.m_fds[i].revents & POLLIN)
(gdb) n
883           listen_sock= m_poll_info.m_pfs_fds[i];
(gdb) n
884           is_unix_socket= m_socket_map[listen_sock];
(gdb) n
885           break;
(gdb) n
904       for (uint retry= 0; retry < MAX_ACCEPT_RETRY; retry++)
(gdb) n
906         socket_len_t length= sizeof(struct sockaddr_storage);
(gdb) n
908                                           (struct sockaddr *)(&cAddr), &length);
(gdb) n
909         if (mysql_socket_getfd(connect_sock) != INVALID_SOCKET ||
(gdb) n
… ...
(gdb) c
Continuing.

4.5、session2此时的select操作都是一切正常的
[root@localhost:(none)][11:41:15am] MySQL-> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
[root@localhost:test][11:49:12am] MySQL-> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t              |
| t1             |
+----------------+
2 rows in set (0.00 sec)

[root@localhost:test][11:49:16am] MySQL-> select * from t;
+------+------+
| id   | name |
+------+------+
|    1 | aaa  |
|    2 | aaa  |
|    3 | aaa  |
|    4 | aaa  |
+------+------+
4 rows in set (0.00 sec)

4.6、session2做insert操作的时候,又一次hung住了,session1打印出了断点的信息,在mysql_insert:423行,直到执行continue,session2才能正常插入数据。
(gdb) c
Continuing.
[Switching to Thread 0x7f87e00b4700 (LWP 24824)]

Breakpoint 1, Sql_cmd_insert::mysql_insert (this=0x7f87f40147b8, thd=0x7f87f401bc60, table_list=0x7f87f4013fe0)
    at /root/mysql-server/sql/sql_insert.cc:423
423       DBUG_ENTER("mysql_insert");
(gdb) n
425       LEX *const lex= thd->lex;
(gdb) n
427       bool err= true;
(gdb) c
Continuing.
相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
目录
相关文章
|
4月前
|
NoSQL 搜索推荐 openCL
【C/C++ 调试 GDB指南 】gdb调试基本操作
【C/C++ 调试 GDB指南 】gdb调试基本操作
305 2
|
3月前
|
存储 安全 Java
基于Java+MySQL停车场车位管理系统详细设计和实现(源码+LW+调试文档+讲解等)
基于Java+MySQL停车场车位管理系统详细设计和实现(源码+LW+调试文档+讲解等)
|
24天前
|
NoSQL Linux C语言
Linux GDB 调试
Linux GDB 调试
44 10
|
26天前
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
|
25天前
|
NoSQL
技术分享:如何使用GDB调试不带调试信息的可执行程序
【8月更文挑战第27天】在软件开发和调试过程中,我们有时会遇到需要调试没有调试信息的可执行程序的情况。这可能是由于程序在编译时没有加入调试信息,或者调试信息被剥离了。然而,即使面对这样的挑战,GDB(GNU Debugger)仍然提供了一些方法和技术来帮助我们进行调试。以下将详细介绍如何使用GDB调试不带调试信息的可执行程序。
23 0
|
3月前
|
NoSQL Linux C语言
Linux gdb调试的时候没有对应的c调试信息库怎么办?
Linux gdb调试的时候没有对应的c调试信息库怎么办?
33 1
|
3月前
|
NoSQL Linux C语言
Linux gdb调试的时候没有对应的c调试信息库怎么办?
Linux gdb调试的时候没有对应的c调试信息库怎么办?
23 0
|
3月前
|
关系型数据库 MySQL 数据库
实时计算 Flink版操作报错合集之下载了mysql的cdc的demo,在本地调试时,报错:找不到这个包,该怎么办
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
158 0
|
3月前
|
NoSQL Linux C++
Linux C/C++ gdb调试正在运行的程序
Linux C/C++ gdb调试正在运行的程序
|
3月前
|
NoSQL Linux C++
Linux C/C++ gdb调试core文件
Linux C/C++ gdb调试core文件