利用GDB调试 MSQL(1)

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 利用GDB调试 MSQL

啃完O'reilly的《高性能mysql》、姜老师的《MySQL技术内幕》,再加上个2,3年的实战经验,就基本可以成为一名能独立处理问题的DBA了。但有些时候遇到些很刁钻的疑难杂症的话,那就束手无策了。所以要想技术水平更进一步的话,源码调试是避不开的。

GDB 简介

GDB 是 Linux 系统中,非常常见的调试工具,它有以下功能:

  • Start your program, specifying anything that might affect its behavior.
  • Make your program stop on specified conditions.
  • Examine what has happened, when your program has stopped.
  • Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another.

常用的参数命令:

  • info threads:查看全部线程
  • thread n:指定某个线程
  • b:在某处打断点
  • c:继续往下走
  • s:执行一行代码,如果代码函数调用,则进入函数
  • n:执行一行代码,函数调用不进入
  • p:打印某个变量值
  • list:打印代码的文本信息
  • bt:查看某个线程的栈帧
  • info b:查看当前所有断点信息

调试环境搭建

直接在 linux 下面使用 gdb,这种应该是目前市面上最简单有效的方式。

1. 安装gdb
yum install -y cmake make gcc gcc-c++ ncurses-devel bison gdb
2. 下载、解压源码
wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-boost-5.7.25.tar.gz

tar zxvf mysql-boost-5.7.25.tar.gz
mkdir -p /gdb/mysql/
mkdir -p /gdb/data/
3. 安装数据库
cmake -DCMAKE_INSTALL_PREFIX=/gdb/mysql/ -DMYSQL_DATADIR=/gdb/data/ -DSYSCONFDIR=/gdb/mysql/ -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DWITH_FEDERATED_STORAGE_ENGINE=1 -DWITH_PARTITION_STORAGE_ENGINE=1 -DMYSQL_UNIX_ADDR=/gdb/mysql/mysql3.sock -DMYSQL_TCP_PORT=3306 -DENABLED_LOCAL_INFILE=1 -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DMYSQL_USER=mysql -DWITH_BINLOG_PREALLOC=ON -DWITH_BOOST=/gdb/mysql-5.7.25/boost/boost_1_59_0 -DWITH_DEBUG=1

-DWITH_DEBUG=1 是最关键的,它的作用是开启DBUG

make&&make install
4. 初始化数据库
vim /etc/my.cnf
#简易配置下my.cnf文件
[client]
port = 3306
socket = /gdb/data/mysqld.sock
[mysqld]
port = 3306
socket =/gdb/data/mysqld.sock
skip-external-locking
key_buffer_size = 8M
max_allowed_packet = 1M
table_open_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 128K
read_rnd_buffer_size = 256K
myisam_sort_buffer_size = 8M
lower_case_table_names=1
innodb_buffer_pool_size=300M
log-bin=mysql-bin
character_set_server=utf8
binlog_format=row
datadir=/gdb/data
log-error =/gdb/data/error.log
pid-file = /gdb/data/mysql.pid
innodb_log_file_size=512M
innodb_log_files_in_group = 3
sql_mode=''
autocommit=1
server-id = 1
max_connections=1500
wait_timeout=70
interactive_timeout=70
skip-name-resolve
[mysqldump]
quick
max_allowed_packet = 16M
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
5. 启动数据库

赋权,以便mysql用户有权限在该目录下生成文件:

chown -R mysql:mysql /gdb/data

初始化数据库命令:

cd /gdb/mysql/bin
./mysqld --initialize --user=mysql --basedir=/gdb/mysql --datadir=/gdb/data

启动数据库:

cd /gdb/mysql/support-files
./mysql.server start

insert 断点调试

1. 查看 mysql 进程 id

[root@ops sql]# ps aux | grep mysql
root 629 0.0 0.0 112724 972 pts/2 S+ 14:52 0:00 grep -E --color=auto mysql
root 20926 0.0 0.0 113312 1628 pts/0 S 11:15 0:00 /bin/sh /gdb/mysql/bin/mysqld_safe --datadir=/gdb/data --pid-file=/gdb/data/mysql.pid
mysql 21357 0.0 5.8 1740820 223820 pts/0 Sl 11:15 0:01 /gdb/mysql/bin/mysqld --basedir=/gdb/mysql --datadir=/gdb/data --plugin-dir=/gdb/mysql/lib/plugin --user=mysql --log-error=/gdb/data/error.log --pid-file=/gdb/data/mysql.pid --socket=/gdb/data/mysqld.sock --port=3306

可以看到此时mysql的进程号为:20926

2. gdb 中 attach mysql 进程

[root@ops ~]# gdb
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-119.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html&gt;
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/&gt;.
(gdb) attach 21357
Attaching to process 21357
Reading symbols from /gdb/mysql/bin/mysqld...done.
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done.
[New LWP 21617]
[New LWP 21387]
[New LWP 21386]
[New LWP 21384]
[New LWP 21383]
[New LWP 21382]
[New LWP 21381]
[New LWP 21380]
[New LWP 21379]
[New LWP 21378]
[New LWP 21377]
[New LWP 21376]
[New LWP 21375]
[New LWP 21374]
[New LWP 21373]
[New LWP 21369]
[New LWP 21368]
[New LWP 21367]
[New LWP 21366]
[New LWP 21365]
[New LWP 21364]
[New LWP 21363]
[New LWP 21362]
[New LWP 21361]
[New LWP 21360]
[New LWP 21359]
[New LWP 21358]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
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 /lib64/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /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...Reading symbols from /lib64/libfreebl3.so...(no debugging symbols found)...done.
(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
Reading symbols from /lib64/libnss_sss.so.2...Reading symbols from /lib64/libnss_sss.so.2...(no debugging symbols found)...done.
(no debugging symbols found)...done.
Loaded symbols for /lib64/libnss_sss.so.2
0x00002b15ce803f0d in poll () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.17-222.el7.x86_64 libgcc-4.8.5-39.el7.x86_64 libstdc++-4.8.5-39.el7.x86_64 nss-softokn-freebl-3.34.0-2.el7.x86_64 sssd-client-1.16.0-19.el7.x86_64
(gdb)

3. 找到断点

这次看的是 insert 插入的流程,找到 sql_insert.cc 文件:

image.png

源码中的函数为:Sql_cmd_insert::mysql_insert

4. 设置断点

(gdb) b Sql_cmd_insert::mysql_insert
Breakpoint 1 at 0x175aed9: file /gdb/mysql-5.7.25/sql/sql_insert.cc, line 423.

然后查看下线程的栈帧:

(gdb) bt
#0 0x00002b15ce803f0d in poll () from /lib64/libc.so.6
#1 0x0000000001667f87 in Mysqld_socket_listener::listen_for_connection_event (this=0x3967430) at /gdb/mysql-5.7.25/sql/conn_handler/socket_connection.cc:852
#2 0x0000000000eb15cc in Connection_acceptor<Mysqld_socket_listener>::connection_event_loop (this=0x4f882e0) at /gdb/mysql-5.7.25/sql/conn_handler/connection_acceptor.h:66
#3 0x0000000000ea904a in mysqld_main (argc=38, argv=0x383c248) at /gdb/mysql-5.7.25/sql/mysqld.cc:5149
#4 0x0000000000ea01bd in main (argc=9, argv=0x7ffc73765b88) at /gdb/mysql-5.7.25/sql/main.cc:25

5. 数据库登陆

gdb断点设置完后,起个新的数据库连接:

image.png

会发现此时无法登陆,在gdb中执行next:

(gdb) n
Single stepping until exit from function poll,
which has no line number information.
Mysqld_socket_listener::listen_for_connection_event (this=0x3967430) at /gdb/mysql-5.7.25/sql/conn_handler/socket_connection.cc:859
859 if (retval < 0 && socket_errno != SOCKET_EINTR)

通过输出可以知道数据库处于获取系统 socket 状态。接下来需要跳过的步骤有些多,我们直接使用 continue (直接到下一段可执行代码)

(gdb) c
Continuing.

新起客户端连接成功:

[root@ops bin]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 5.7.25-debug-log Source distribution
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>


            </div>
相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
SQL NoSQL 关系型数据库
利用GDB调试 MSQL(2)
利用GDB调试 MSQL
|
NoSQL 关系型数据库 MySQL
利用GDB调试 MSQL(1)
利用GDB调试 MSQL
124 0
利用GDB调试 MSQL(1)
|
存储 安全 Java
解密SimpleDateFormat类的线程安全问题和六种解决方案!
提起SimpleDateFormat类,想必做过Java开发的童鞋都不会感到陌生。没错,它就是Java中提供的日期时间的转化类。这里,为什么说SimpleDateFormat类有线程安全问题呢?有些小伙伴可能会提出疑问:我们生产环境上一直在使用SimpleDateFormat类来解析和格式化日期和时间类型的数据,一直都没有问题啊!接下来,我们就一起看下在高并发下SimpleDateFormat类为何会出现安全问题,以及如何解决SimpleDateFormat类的安全问题。
1391 1
解密SimpleDateFormat类的线程安全问题和六种解决方案!
|
SQL 监控 druid
Spring Boot 整合 Druid 指南
Spring Boot 整合 Druid 指南
21500 2
|
SQL 关系型数据库 MySQL
Python进阶——pymysql查询
概述 使用pymysql进行查询操作
551 0
|
NoSQL 关系型数据库 MySQL
利用GDB调试 MSQL(1)
利用GDB调试 MSQL
123 0
利用GDB调试 MSQL(1)
|
SQL 存储 JSON
JSON_TABLE 两全其美
在这篇博客文章中,我将向您展示如何做到这一点,并讨论JSON_TABLE如何启用使用SQL处理JSON数据的新方法。
6310 0
|
Web App开发 JavaScript 前端开发
html img Src base64 图片显示
大家可能注意到了,网页上有些图片的src或css背景图片的url后面跟了一大串字符。 比如:data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAA...
4504 0
|
缓存 资源调度 Java
阿里巴巴DevOps实践指南(十七)| 提升构建的效率
构建是将源码变成制品的过程。构建包括编译,但不等同于编译。即使对于不需要编译的解释型语言,也要构建成一个压缩包或 Docker 镜像再去部署。无论是在开发阶段还是 CICD 阶段,都离不开构建过程,构建的质量和效率对持续交付影响很大。影响构建效率的因素,包括源码以及构建的依赖。
阿里巴巴DevOps实践指南(十七)| 提升构建的效率

热门文章

最新文章