调试MySQL源码的完整指南 #
一、环境准备 #
1. 更新系统软件包列表 #
sudo apt update
2. 安装编译所需的基本工具和库 #
sudo apt install build-essential cmake libncurses5-dev libssl-dev bison libboost-all-dev
3. 安装其他可能需要的库和工具 #
sudo apt install libpthread-stubs0-dev libaio-dev libprotobuf-dev protobuf-compiler libnuma-dev libmecab2 mecab mecab-ipadic git
4. 验证GCC版本(需要8.0以上) #
gcc --version
如果GCC版本低于8.0,可以使用以下命令安装GCC 8:
sudo apt install gcc-8 g++-8
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 80 --slave /usr/bin/g++ g++ /usr/bin/g++-8
5. 验证CMake版本(需要3.5以上) #
cmake --version
如果CMake版本低于3.5,可以使用以下命令安装CMake 3.5:
wget https://github.com/Kitware/CMake/releases/download/v3.5.2/cmake-3.5.2.tar.gz
tar -xvf cmake-3.5.2.tar.gz
cd cmake-3.5.2
./configure
make
sudo make install
如果在安装CMake 3.5时遇到问题,可以参考以下步骤:
a. 完成CMake 3.5.2的构建和安装:
cd cmake-3.5.2
make
sudo make install
b. 检查CMake 3.5.2是否已经正确安装:
/usr/local/bin/cmake --version
c. 如果步骤b正常,将/usr/local/bin
添加到PATH
环境变量的最前面:
export PATH=/usr/local/bin:$PATH
可以将这一行添加到.bashrc
文件的末尾,以使更改永久生效。
d. 再次尝试cmake --version
,应该会输出CMake 3.5.2的版本信息。
6. 安装pkg-config #
sudo apt install pkg-config
7. 如果需要LDAP认证插件,安装LDAP开发库 #
sudo apt install libldap2-dev
8. 如果需要FIDO认证插件,安装libudev开发库 #
sudo apt install libudev-dev
二、源码获取 #
1. 安装Git #
sudo apt install git
2. 从GitHub克隆MySQL 8.0.33的源码 #
git clone --depth 1 --branch mysql-8.0.33 https://github.com/mysql/mysql-server.git
3. 进入源码目录 #
cd mysql-server
三、编译源码 #
1. 在源码目录下,创建一个单独的编译目录 #
mkdir build
cd build
2. 下载Boost库 #
wget https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/boost_1_77_0.tar.bz2
3. 将下载的boost_1_77_0.tar.bz2
文件移动到/home/grok/mysql-server/build/boost
目录
#
mkdir boost
mv boost_1_77_0.tar.bz2 ./boost
4. 使用CMake生成Makefile #
cmake .. -DDOWNLOAD_BOOST=1 -DWITH_BOOST=./boost -DCMAKE_BUILD_TYPE=Debug -DWITH_DEBUG=1
如果您的系统已经安装了Boost库,可以去掉-DDOWNLOAD_BOOST
和-DWITH_BOOST
选项。
5. 编译源码 #
make -j$(nproc)
编译过程可能会花费较长时间,请耐心等待。如果编译出错,请仔细查看错误信息,解决相应的依赖问题或编译选项问题。
6. 编译完成后,可以在build/bin
目录下找到编译出的mysqld
可执行文件
#
ls ./bin/mysqld
四、调试前的准备 #
1. 初始化数据目录 #
./bin/mysqld --initialize-insecure --datadir=./data
这里使用--initialize-insecure
选项进行初始化,不设置root密码。
2. 启动mysqld服务器,并指定Unix域套接字文件的路径 #
./bin/mysqld --datadir=./data --socket=./data/mysql.sock
这样,MySQL服务器将使用./data/mysql.sock
作为Unix域套接字文件。
3. 打开另一个终端,使用MySQL客户端连接到mysqld服务器,指定相同的套接字文件路径 #
./bin/mysql -uroot -S./data/mysql.sock
4. 在MySQL客户端中,创建一个测试数据库和表 #
CREATE DATABASE test;
USE test;
CREATE TABLE t1 (id INT, name VARCHAR(10));
INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc');
5. 正确地关闭MySQL服务器 #
您可以在MySQL客户端中执行SHUTDOWN
命令:
mysql> SHUTDOWN;
或者在另一个终端中使用mysqladmin
工具:
./bin/mysqladmin -uroot -S./data/mysql.sock shutdown
如果以上方法无法关闭服务器,您可以在服务器进程所在的终端中按下Ctrl+\
(反斜杠),或者使用kill
命令发送SIGTERM
或SIGKILL
信号。但是这些方法可能会导致数据损坏或不一致,只应在其他方法失败时使用。
五、使用GDB调试MySQL源码 #
1. 在MySQL源码的build
目录下,使用GDB启动mysqld进程(建议使用绝对路径,下面根据实际情况修改)
#
gdb --args ./bin/mysqld --datadir=/home/grok/mysql-server/build/data/ --socket=/home/grok/mysql-server/build/data/mysql.sock
2. 在GDB中设置断点 #
为避免初始连接问题,建议设置断点于某个查询执行或特定逻辑处理的代码段。例如,如果想要在执行具体的SQL命令时停下来看看发生了什么,可以在处理该SQL命令的函数处设置断点。找到该函数的准确位置需要您根据当前的MySQL源码进行查找。例如:
(gdb) break sql_parse.cc:执行SQL命令的函数
3. 使用run
命令运行mysqld进程
#
(gdb) run
4. 打开另一个终端,使用MySQL客户端连接到mysqld服务器,并执行会触发断点的SQL语句 #
./bin/mysql -uroot -S/home/grok/mysql-server/build/data/mysql.sock
USE test;
SELECT * FROM t1;
5. 切换回GDB所在的终端,此时GDB会停在断点处。您可以使用GDB命令进行调试: #
n
(next): 单步执行,不进入函数。s
(step): 单步执行,进入函数。p
(print): 打印变量值,如p thd->query().str
。bt
(backtrace): 查看调用栈。up
/down
: 在调用栈中向上或向下移动。f
(frame): 切换到指定的栈帧。c
(continue): 继续执行,直到下一个断点。
6. 如果要在调试过程中动态地设置或删除断点,可以使用以下命令: #
(gdb) break 文件名:行号
(gdb) break 文件名:函数名
(gdb) info breakpoints
(gdb) delete 断点编号
7. 调试完成后,使用quit
命令退出GDB
#
(gdb) quit
六、其他调试技巧和建议 #
-
在调试之前,先要对MySQL的整体架构和执行流程有一个大致的了解。可以参考MySQL官方文档、书籍、博客等资料。
-
从一些核心模块入手,如SQL解析、查询优化、执行器、存储引擎等,逐步深入理解MySQL的内部原理。
-
多使用断点和单步执行,仔细观察变量的值和调用栈的变化,理解代码的执行过程。
-
善用GDB的条件断点和观察点功能,可以在特定条件下触发断点,或者在变量值发生变化时停下来。
-
使用GDB的脚本功能,可以自动化一些调试操作,提高效率。
-
在调试过程中,可以适当添加一些日志打印语句,跟踪关键变量和执行路径。
-
调试过程中遇到任何问题,可以查阅GDB手册或在网上搜索解决方案。 希望这份指南能够为您的MySQL源码探索之旅提供有力的指导和帮助。