MySQL 调试环境搭建:VSCode + Docker

近期使用 gdb 调试比较多,发现了很多好用的功能,而在 Mac 上使用 gdb 调试,体验不太顺畅。

为此,基于 Docker 搭建了一套 CentOS 环境,结合 VSCode 和 gdb 来调试 MySQL,拿出来和大家分享。

本文基于 Mac + MySQL 8.0.32 版本,其它系统 + MySQL 其它版本也可以参考。

目录 [TOC]

正文

1. 下载 Docker Desktop

下载地址: https://www.docker.com/products/docker-desktop

下载界面:

Docker Desktop 下载完成之后,安装并运行,然后就可以​继续接下来的步骤了。​

2. 创建 Docker 容器

先在 Docker Desktop 中设置能够映射到容器中的宿主机目录

在第 3 个红框的处的输入框中,输入 /opt/data/docker,然后回车,把目录加入 FILE SHARING,表示允许把宿主机中该目录及其子目录映射到容器中,最后点击第 4 个红框中的 Apply & Restart,应用修改并重新启动 Docker Desktop。

宿主机执行以下命令,创建容器并运行:

 1# 获取 CentOS 7.9 镜像
 2docker pull centos:centos7.9.2009
 3
 4# 创建容器
 5# 这个 CentOS 容器专用于调试 MySQL
 6# 所以命名为【mysql】
 7# -d,表示以守护进程方式运行容器
 8# -t,表示需要打开终端
 9# --name,容器名字
10# -p,端口映射,格式【宿主机端口:容器端口】
11# -v,目录映射,格式【宿主机目录:容器目录】
12# centos:centos7.9.2009,镜像
13docker run \
14  --name mysql \
15  -p 3306-3310:3306-3310 \
16  -v /opt/data/docker/centos79_mysql:/opt/data \
17  --privileged -dt \
18  centos:centos7.9.2009

如果想在宿主机连接容器中的 MySQL,需要指定 -p 选项做端口映射,然后通过 宿主机 IP + 宿主机映射端口连接容器中的 MySQL 会比较方便。

我手上没有 Windows 系统环境,如果读者朋友有过 Windows 系统创建、运行 Docker 容器的经验,愿意把步骤分享出来,欢迎留言分享

3. 安装 VSCode 扩展

VSCode 扩展包含两部分:安装在宿主机的扩展、安装在容器中的扩展。

我们先打开 VSCode,安装宿主机 Docker 扩展

安装 Docker 扩展之后,我们就能在 VSCode 中看到之前创建的 mysql 容器了:

点击 Attach Visual Studio Code 会打开一个新的 VSCode 窗口,我们给它取个名字:mysql 容器窗口,后面会用到。

接下来,在 mysql 容器窗口安装扩展。

安装 C/C++ 扩展:

安装 CMake Tools 扩展:

4. 准备编译

宿主机执行以下命令,进入 mysql 容器

1docker exec -ti mysql /bin/bash

mysql 容器中执行以下命令,下载源码、安装依赖软件:

 1# 创建存放源码的目录
 2mkdir -p /opt/data/code
 3
 4# 进入存放源码的目录
 5cd /opt/data/code
 6
 7# 安装 wget、下载源码 & 解压
 8yum install wget
 9wget https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-boost-8.0.32.tar.gz
10tar zxvf mysql-boost-8.0.32.tar.gz
11
12# 修改源码目录名
13mv mysql-8.0.32 8.0.32
14
15# 用于安装 cmake3 的 yum 源
16yum -y install epel-release
17
18# 用于安装高版本 gcc、gcc-c++、make 的 yum 源
19yum -y install centos-release-scl
20
21# 安装依赖软件
22yum install devtoolset-11-gcc \
23  devtoolset-11-gcc-c++ \
24  devtoolset-11-make \
25  cmake3 \
26  openssl-devel \
27  ncurses-devel \
28  bison
29
30# 安装 gdb
31yum install devtoolset-11-gdb
32
33# 让 scl 环境临时生效
34source /opt/rh/devtoolset-11/enable
35
36# 让 scl 环境永久生效
37yum install vim
38vim /etc/profile.d/scl.sh
39
40# 把以下内容写入 scl.sh,然后保存退出
41source /opt/rh/devtoolset-11/enable

5. 编译

编译过程按以下步骤进行:

第 1 步,在 mysql 容器窗口中打开刚下载的 MySQL 源码目录:

第 2 步,创建 .vscode 目录:

第 3 步,新建 CMake 配置文件 settings.json

settings.json 文件内容如下:

 1{
 2  "cmake.buildBeforeRun": true,
 3  "cmake.buildDirectory": "${workspaceFolder}/output",
 4  "cmake.configureSettings": {
 5    "WITH_DEBUG": "1",
 6    "CMAKE_INSTALL_PREFIX": "${workspaceFolder}/output",
 7    "MYSQL_DATADIR": "/opt/data/8.0.32/data",
 8    "SYSCONFDIR": "/opt/data/8.0.32/etc",
 9    "MYSQL_TCP_PORT": "3306",
10    "MYSQL_UNIX_ADDR": "/opt/data/8.0.32/data/mysql-debug.sock",
11    "WITH_BOOST": "${workspaceFolder}/boost",
12    "DOWNLOAD_BOOST": "0"
13  },
14  "files.associations": {
15    "*.ipp": "cpp"
16  },
17  "cmake.parallelJobs": 8,
18  "cmake.cmakePath": "cmake3"
19}

cmake.parallelJobs 用于控制多少个线程同时进行编译,以加快编译速度,默认值为 0,CMake 会根据 CPU 核数自行确定并发线程数。

如果编译过程中报以下错误,有两种解决方案:

1c++: internal compiler error: Killed (program cc1plus)

方案 1:cmake.parallelJobs 设置的小一点,我在编译过程中把并发数设置为 10 会报错,后来改为 8 就能成功编译了。

方案 2:Docker Desktop 中调整容器能够使用的资源,如下:

想要编译的更快,可以把 cmake.parallelJobs 设置为 0,然后,在以上 Docker Desktop 界面中,把 CPU、Memory 两项调大。

第 4 步CMake 配置,生成 Makefile 文件:

选择编译器:

如果 CMake:配置执行过程中出现了错误,解决错误之后需要删除 CMakeCache.txt,然后重新执行 CMake:配置步骤。

CMakeCache.txt 文件路径为 /opt/data/code/8.0.32/output/CMakeCache.txt

第 5 步,编译服务端可执行程序 mysqld
在输入框中输入“> CMake: 生成目标”,选中第 2 个红框中的选项。

接着会出现另一个输入框,在其中输入 mysqld,然后回车,就开始编译 mysqld 了。

第 6 步,编译客户端可执行程序 mysql
在输入框中输入“> CMake: 生成目标”,下拉列表中只会筛选出 1 个选项,选中该选项(第 2 个红框所示)。

接着会出现另一个输入框,在其中输入 mysql,然后回车,就开始编译 mysql 了。

6. 初始化

接下来,依然是在 mysql 容器中执行以下命令:

 1# 创建配置文件目录 & 数据目录
 2mkdir -p /opt/data/8.0.32/{etc,data}
 3
 4# 创建用户 & 组
 5groupadd mysql
 6useradd -g mysql mysql
 7
 8# 创建配置文件
 9vim /opt/data/8.0.32/etc/my.cnf
10
11# 把以下内容下入 my.cnf
12[mysqld]
13user=mysql
14innodb_file_per_table=1
15server_id=100
16log_bin=ON
17lc-messages-dir=/opt/data/code/8.0.32/output/share
18log-error=/opt/data/8.0.32/error.log
19
20# 初始化数据目录
21/opt/data/code/8.0.32/output/bin/mysqld --initialize-insecure

7. 调试

经过前面一系列操作之后,就可以开始着手在 mysql 容器窗口中调试了。

第 1 步,新建配置文件 launch.json

launch.json 文件内容如下:

 1{
 2  "version": "0.2.0",
 3  "configurations": [
 4    {
 5      "name": "(gdb) 启动",
 6      "type": "cppdbg",
 7      "request": "launch",
 8      "program": "/opt/data/code/8.0.32/output/bin/mysqld",
 9      "args": [],
10      "stopAtEntry": false,
11      "cwd": "${fileDirname}",
12      "environment": [],
13      "externalConsole": false,
14      "MIMode": "gdb",
15      "setupCommands": [
16        {
17          "description": "为 gdb 启用整齐打印",
18          "text": "-enable-pretty-printing",
19          "ignoreFailures": true
20        },
21        {
22          "description": "将反汇编风格设置为 Intel",
23          "text": "-gdb-set disassembly-flavor intel",
24          "ignoreFailures": true
25        }
26      ]
27    }
28  ]
29}

第 2 步,启动调试,launch.json 文件配置完成之后,运行和调试下拉框就能看到刚刚添加的配置,点击 (gdb) 启动前面的小三角,启动 MySQL,然后就可以开始调试了。

第 3 步,在 mysql 容器的命令行中,通过前面编译的客户端可执行程序 mysql,连接 MySQL:

1cd /opt/data/code/8.0.32/output/bin
2./mysql -h127.0.0.1 -uroot

第 4 步,连接 MySQL 成功之后,在 MySQL 源码中打个断点,先打开 sql/sql_parse.cc 文件:

然后在 mysql_execute_command() 函数入口处打上断点:

第 5 步,执行一条 SQL:

1SELECT host, user FROM mysql.user;

程序在断点处暂停之后,就可以查看一系列运行时信息了,查看断点所在函数的局部变量:

查看断点处的调用栈:

也可以在调试控制台中,用命令行执行更多 gdb 命令:

VSCode + Docker 调试,需要在命令之前加上 -exec,上图中命令 p thd->m_query_string 前面就加上了 -exec

8. 总结

本文介绍了 VSCode + Docker + CentOS 7.9 搭建 MySQL 调试环境的完整流程。

如果读取朋友们在搭建环境的过程碰到了问题,以及有相应的解决方案,都欢迎在留言区和大家交流分享。




欢迎扫码关注公众号,我们一起学习更多 MySQL 知识: