共计 4637 个字符,预计需要花费 12 分钟才能阅读完成。
导读 | 近期使用 gdb 调试比较多,发现了很多好用的功能,而在 Mac 上使用 gdb 调试,体验不太顺畅。为此,基于 Docker 搭建了一套 CentOS 环境,结合 VSCode 和 gdb 来调试 MySQL,拿出来和大家分享。本文介绍了 VSCode + Docker + CentOS 7.9 搭建 MySQL 调试环境的完整流程。 |
本文基于 Mac + MySQL 8.0.32,对于在其它系统上搭建 MySQL 调试环境,安装好 Docker Desktop 之后的步骤也是可以借鉴的。
下载地址:https://www.docker.com/products/docker-desktop
下载界面:
Docker Desktop 下载完成之后,安装并运行,然后就可以继续接下来的步骤了。
先在 Docker Desktop 中设置能够映射到容器中的宿主机目录:
在第 3 个红框处的输入框中,输入 /opt/data/docker,然后按回车键把目录加入 FILE SHARING,表示允许把宿主机中该目录及其子目录映射到容器中,最后点击第 4 个红框处的 Apply & Restart,应用并重启 Docker Desktop,让修改生效。
在宿主机执行以下命令,创建容器并运行:
获取 CentOS 7.9 镜像 | |
docker pull centos:centos7.9.2009 | |
# 创建容器 | |
这个 CentOS 容器专用于调试 MySQL | |
所以命名为【mysql】# -d,表示以守护进程方式运行容器 | |
-t,表示需要打开终端 | |
--name,容器名字 | |
-p,端口映射,格式【宿主机端口: 容器端口】# -v,目录映射,格式【宿主机目录: 容器目录】# centos:centos7.9.2009,镜像 | |
docker run \ | |
--name mysql \ | |
-p 3306-3310:3306-3310 \ | |
-v /opt/data/docker/centos79_mysql:/opt/data \ | |
--privileged -dt \ | |
centos:centos7.9.2009 |
在 Mac 宿主机上,连接容器中的 MySQL,需要指定 -p 选项做端口映射,然后通过 宿主机 IP + 映射的宿主机端口连接容器中的 MySQL。
VSCode 扩展包含两部分:安装在宿主机的扩展、安装在容器中的扩展。
我们先打开 VSCode,安装宿主机 Docker 扩展:
安装 Docker 扩展之后,我们就能在 VSCode 中看到之前创建的 mysql 容器了:
点击 Attach Visual Studio Code 会打开一个新的 VSCode 窗口,我们给它取个名字:mysql 容器窗口,后面会用到。
接下来,在 mysql 容器窗口安装扩展。
安装 C/C++ 扩展:
安装 CMake Tools 扩展:
在宿主机执行以下命令,进入 mysql 容器:
docker exec -ti mysql /bin/bash
在 mysql 容器中执行以下命令,下载源码、安装依赖软件:
# 创建存放源码的根目录 | |
mkdir -p /opt/data/code | |
# 进入存放源码的根目录 | |
cd /opt/data/code | |
# 安装 wget、下载源码 & 解压 | |
yum install wget | |
wget https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-boost-8.0.32.tar.gz | |
tar zxvf mysql-boost-8.0.32.tar.gz | |
# 修改源码目录名 | |
mv mysql-8.0.32 8.0.32 | |
# 用于安装 cmake3 的 yum 源 | |
yum -y install epel-release | |
# 用于安装高版本 gcc、gcc-c++、make 的 yum 源 | |
yum -y install centos-release-scl | |
# 安装依赖软件 | |
yum install devtoolset-11-gcc \ | |
devtoolset-11-gcc-c++ \ | |
devtoolset-11-make \ | |
cmake3 \ | |
openssl-devel \ | |
ncurses-devel \ | |
bison | |
# 安装 gdb | |
yum install devtoolset-11-gdb | |
# 让 scl 环境临时生效 | |
source /opt/rh/devtoolset-11/enable | |
# 让 scl 环境永久生效 | |
yum install vim | |
vim /etc/profile.d/scl.sh | |
# 把以下内容写入 scl.sh,然后保存退出 | |
source /opt/rh/devtoolset-11/enable |
编译过程按以下步骤进行:
第 1 步,在 mysql 容器窗口中打开刚下载的 MySQL 源码目录:
第 2 步,创建 .vscode 目录:
第 3 步,新建 CMake 配置文件 settings.json:
settings.json 文件内容如下:
{ | |
"cmake.buildBeforeRun": true, | |
"cmake.buildDirectory": "${workspaceFolder}/output", | |
"cmake.configureSettings": { | |
"WITH_DEBUG": "1", | |
"CMAKE_INSTALL_PREFIX": "${workspaceFolder}/output", | |
"MYSQL_DATADIR": "/opt/data/8.0.32/data", | |
"SYSCONFDIR": "/opt/data/8.0.32/etc", | |
"MYSQL_TCP_PORT": "3306", | |
"MYSQL_UNIX_ADDR": "/opt/data/8.0.32/data/mysql-debug.sock", | |
"WITH_BOOST": "${workspaceFolder}/boost", | |
"DOWNLOAD_BOOST": "0" | |
}, | |
"files.associations": {"*.ipp": "cpp"}, | |
"cmake.parallelJobs": 8, | |
"cmake.cmakePath": "cmake3" | |
} |
cmake.parallelJobs 用于控制多少个线程同时进行编译,以加快编译速度,默认值为 0,CMake 会根据 CPU 核数自行确定并发线程数。
如果编译过程中报以下错误,有两种解决方案:
c++: internal compiler error: Killed (program cc1plus)
方案 1:把 cmake.parallelJobs 设置的小一点,我在编译过程中把并发数设置为 10 会报错,后来改为 8 就能成功编译了。
方案 2:在 Docker Desktop 中调整容器能够使用的资源,如下:
想要编译的更快,可以把 cmake.parallelJobs 设置为 0,然后,在以上 Docker Desktop 界面中,把 CPU、Memory 两项调大。
第 4 步,CMake 配置,生成 Makefile 文件:在 mysql 容器窗口顶部的输入框中,输入 > CMake: 配置,然后选择下面列出来的 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: 生成目标”,选中第 2 个红框中的选项。
接着会出现另一个输入框,在其中输入 mysql,然后回车,就开始编译 mysql 了。
接下来,依然是在 mysql 容器中执行以下命令:
# 创建配置文件目录 & 数据目录 | |
mkdir -p /opt/data/8.0.32/{etc,data} | |
# 创建用户 & 组 | |
groupadd mysql | |
useradd -g mysql mysql | |
# 创建配置文件 | |
vim /opt/data/8.0.32/etc/my.cnf | |
# 把以下内容下入 my.cnf | |
[mysqld] | |
user=mysql | |
innodb_file_per_table=1 | |
server_id=100 | |
log_bin=ON | |
lc-messages-dir=/opt/data/code/8.0.32/output/share | |
log-error=/opt/data/8.0.32/error.log | |
# 初始化数据目录 | |
/opt/data/code/8.0.32/output/bin/mysqld --initialize-insecure |
经过前面一系列操作之后,就可以开始着手在 mysql 容器窗口中调试了。
第 1 步,新建配置文件 launch.json:
launch.json 文件内容如下:
{ | |
"version": "0.2.0", | |
"configurations": [ | |
{"name": "(gdb) 启动", | |
"type": "cppdbg", | |
"request": "launch", | |
"program": "/opt/data/code/8.0.32/output/bin/mysqld", | |
"args": [], | |
"stopAtEntry": false, | |
"cwd": "${fileDirname}", | |
"environment": [], | |
"externalConsole": false, | |
"MIMode": "gdb", | |
"setupCommands": [ | |
{ | |
"description": "为 gdb 启用整齐打印", | |
"text": "-enable-pretty-printing", | |
"ignoreFailures": true | |
}, | |
{ | |
"description": "将反汇编风格设置为 Intel", | |
"text": "-gdb-set disassembly-flavor intel", | |
"ignoreFailures": true | |
} | |
] | |
} | |
] | |
} |
第 2 步,启动调试,launch.json 文件配置完成之后,运行和调试下拉框就能看到刚刚添加的配置,点击 (gdb) 启动前面的小三角,启动 MySQL,然后就可以开始调试了。
第 3 步,在 mysql 容器的命令行中,通过前面编译的客户端可执行程序 mysql,连接 MySQL:
cd /opt/data/code/8.0.32/output/bin | |
./mysql -h127.0.0.1 -uroot |
第 4 步,连接 MySQL 成功之后,在 MySQL 源码中打个断点,先打开 sql/sql_parse.cc 文件:
然后在 mysql_execute_command() 函数入口处打上断点:
第 5 步,执行一条 SQL:
SELECT host, user FROM mysql.user;
程序在断点处暂停之后,就可以查看一系列运行时信息了,查看断点所在函数的局部变量:
查看断点处的调用栈:
也可以在调试控制台中,用命令行执行更多 gdb 命令:
VSCode + Docker 调试,需要在命令之前加上 -exec,上图中命令 p thd->m_query_string 前面就加上了 -exec。
本文介绍了 VSCode + Docker + CentOS 7.9 搭建 MySQL 调试环境的完整流程。
