接上文:vscode + docker容器 快速部署开发MiniOB
初始界面
我们需要运行的主要是observer程序,所以我们找到src里面的observer文件夹,main是它的入口程序。observer的代码从这个文件开始执行。
如何调试observer程序呢?
1. 创建launch.json文件
点击左边debug小虫子的图标进入调试窗口
vscode的调试依赖于launch.json文件,我们先创建一个,选择gdb启动调试
各个参数如图填入即可:
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: Debug code with Visual Studio Code
"version": "0.2.0",
"configurations": [
{
"name": "client", //调试器的名字
"type": "cppdbg",
"request": "launch",
"program": "/root/miniob/build/bin/observer", //可执行程序的路径
"args": ["-f", "../etc/observer.ini", "-P", "cli"], //启动时需要附加的命令行参数
"stopAtEntry": false,
"cwd": "/root/miniob",//工作目录
"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. 添加断点
在main的第一行打上红色的断点,除此之外在一些关键的地方打上断点,如init_server:
可以通过ctrl + 点击函数的方式跳转到函数的实现部分
自己抉择哪些是重要的代码,哪些是不重要的代码。其实大部分网络初始化的代码都是不重要的代码。可以不用不看,主要关注sql语句进入到系统内是如何被处理的。
3. 启动调试
启动之前配置好的调试器,画面如图,首先在第一个断点处停下了
然后我们可以点击单步进入或者逐过程的符号,单步进入可以进入函数内部,逐过程则会一次把函数执行完,不会进入函数内部:
这样我们就可以看到代码是如何走的。
4. 重要断点
init_server函数里面136行根据输入参数来决定server的类型,我们调试器配置的输入参数是cli,所以这里会走到CliServer
初始化server之后会调用server的serve函数,我们单步调试进入该函数内部
内部的核心函数只有handle_event函数,所以该函数是必须要看的,因为核心逻辑就在里面
此时首先会通过read_event读取输入的sql语句,所以我们需要在终端先输入sql语句,比如输入 create table food(id int,name char(20));然后按回车。
这部分代码负责把输入载入系统中
执行完这里之后在调试器的变量中可以看到我们输入的sql语句了。
由于这是核心逻辑,所以这里面的每个函数最好都进去看一下,并加断点避免错过。
handle_sql这个函数为我们演示了miniob是如何把一个sql语句一步步经过各种阶段,如(parse_stage(SQL解析),resolve_stage(语义解析),optimize_stage(查询优化)),然后执行完成的。所以我们要做的就是跟随着单步调试一步步进入这些函数,然后看看经历了哪些步骤,再通过调试器的变量变化来观察变量是如何变化的。
5. 实现新的功能
比如如果需要新增删除table功能,我们就需要看看创建table做了什么事,从而实现对应的相反逻辑即可。
由于SQL解析已经包含了drop table的功能(因为执行的时候没有报语法错误)
所以只需要看后续的阶段
比如
在这个语义解析阶段会执行create_stmt函数,那我们就进这个函数看看
这里我们发现创建table会通过一个flag进入到CreateTableStmt::create
那么在删除的时候,我们就需要思考删除有没有对应的flag来标识,这个flag是从哪来的,已经删除的DropTableStmt有没有实现,然后我们就根据CreateTableStmt的内容照猫画虎地写DropTableStmt的逻辑。
后面其他阶段也会有类似的行为,所以需要靠大家动脑去思考,等大家想明白了,也就对数据库内核的实现会有更深层次的理解了。
注意:如果调试的时候错过了自己想要看的代码,就只能点击绿色的重新调试按钮。
如对本文档有任何疑问或建议,请联系作者