开发者学堂课程【从0到1数据库内核实战教程:Miniob drop table 实现解析】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/1083/detail/16141
Miniob drop table 实现解析
内容介绍:
一、MiniOB 框架介绍
二、代码解析
一、MiniOB 框架介绍
本次分享 MiniOB,去实现做 Google 源码级别的一个详细解析。都知道MiniOB是欧兴类似于华中科技大学联合研发的一套帮助零基础同学学习数据库原理开发的一个入门教程,与 MiniOB 配套,有一系列的题目做这个,就是我们最适合基础入门的一个题目,希望能够通过这一个题目,能够了解命UB的各个模块,然后各种调试,环境什么的都逐渐熟悉起来。如果对无线被子比赛有兴趣的同学,就更建议的去详细的来跟我们一起,去认真的敲一遍代码,能够让你很快的能够去上手练起来。回到正题,再来简单回顾一下整个的搜库语句的请求的一个流程,就是左边客户端发起请求之后,然后网络这块,收到交给一个司法解析模块,然后直接到relove模块,然后再到优化,这个也是现在没有,我们做推广直接通过relove到了aq的。让他会去经过一系列的执行,去通过网络模块反馈给客户端。我们现在就通过在代码上面来看一下这几个模块,它的流程是怎么样的,然后再去实现装修的这个功能。
二、代码解析
上图是一个代码,可以看一下,是几个模块,是在booking server soup下面有几个模块,这一系列的模块都是在这里面的,比如我们的词法解析,语法解析就是在power里面,也是在这个跨色里面的,可以直接跳到这个执行阶段,那先进来看一下跨色阶段,我们的一个词法,解析语法,还是回到正题,果是已经实现了词法解析,这个就可以进一步先跳过,作为词法解析的一个突分。
然后语法解析里面的drop table也是有的,可以看到,是在的语法,解题不是本身已经支持的,这里不需要修改代码,但是按照这个流程来走一遍。通常网络消息制造这个方式之后会导致疑问,然后去会请求,因为时间短,有些步骤我们过的快一点,然后经过一个解析,此外一个解析,解析出来之后会生成一个数据结构query,就是在这个,在这里面可以看到。
主要是一个命令,命令就是我这个键点,3.2这种操作,然后制定一个应命结构,应命结构就是具体的一个数据,就drop table是在这里可以看到的,解析之后,就去建立下一个预料的阶段。第二个是在这里还照明他的,用它会解释咱们一个语句,但是招聘,现在是没有做这个解析的,不过不影响,可以直接跳到下一个环节,就是这里有好几个环节是没有做任何事情,直接跳到执行阶段。
删除表
它在执行阶段可以看到这里有一个建表,这里有个删表,不过现在是没有实现的,就不往里面跳了,知道是没有实现的,那现在先跟着建表去走一遍流程,一会去按照这个流程去实现一个删表的一个一个动作,建表就是在这里实现建表的话就说我先拿到一个建表的一个语句相关的一个筛查文,然后再去找到当前的一个数据库数据库,然后再去建表,调用它的接口,那我们的数据库,也是可以直接连的,很直白,我们再看看它的一个实验,能看到就是一个。再过一下,就是说他先去判断当前有没有这个表,如果没有这个表,那就去计算一个数据结构中去结构,他自己这个里面去实现的一个创建的一个过程,然后再去把这个表加入到已经打开的表的列表之中。在初始化的启动的时候,你我被启动的时候,它就会把所有的当前已经创建的表去打开,直接一个打开动作,那我们在建表的时候,就直接来这里,我们来看一下,就是建表的有一些参数,这些参数可能写的不是太直白。
来解释一下,是一个pass参数,就是我们表,是有它的存放的原数据,这原数据是什么?就是当前的表的一个名字。当前表都有哪些字段,字段都是什么类型,或者还有哪些左眼灯都是在这里面记录的,然后一个接下来就是一个表名字,还有一个我们当前表是存放在哪个位置的,当前表填上来的位置是什么?是表除原数据组,还有一些数据文件还。还有比如索引什么的,都是放在这个目录下面的,接下来就是一个表的一个属性,你也可以就是理解为我们都有哪些字段,一共多少字段,字段都是什么类型,类型长度,可以在这里描述的,那来建小的一个流程,就是当前的一个参数检查,这就简单跳过去,然后去创建一个文件,就是这个原数据文件。
然后再去把我们的一个提出,卖的就是我们的一个表的原数据在这里数字化,根据字段信息,然后做一个数字化,再把它序列化下去写入到这个文件中,写的原数据文件中。
然后再去创建一个数据文件,数据文件就是存放真实的,是插入一条数据或者更新数据的,都是在这个文件里面去做维护的。数据文件,还需要去跟buffer去做关联,就是数据在读取的时候,不是直接从磁盘上直接读到读出来的,是新过一个buffer的。这里就先跳过去,不做详细的任务,然后接下来有一个是约翰的,约翰的是做什么?就是在数据文件里面,这个数据文件是用来存放记录的或者行数据的,那就有一个约翰的,它就是去处理,去管理这个函数据上面的文件的。
那接下来,这里就创建完成了,那就是返回到DB那里,然后再返回到执行器这里,它一个键表就结束了,它就会返回给我们的一个客户端,这个流程结束,那就从这个源码层面,一起来一步一步的去尝试着去做一遍这个删表的一个代码,刚才也知道,就是词法跟语段,因为不用写了,然后redoor什么的都不用,你都没有是就不用做,那可以是直接是从这个这里来做的。
RC Table::drop(constchar *path)
{
RC rc = RC ::SUCCESS;
//drop indexes frist
For(Indes *index : indexes_){
index->drop();
}
//destroy record handler
rc = record_handler_->destroy();
delete record_handler_;
record_handler_;=nullptr;
//destroy buffer poop and remove data file
std::string data_file = table_data_file(base_dir,name);
BuffrtPoolManager &bpm = BufferPoolManager::instance();
rc =bpm.remove_file(data_file.c_str());
//remove meta file
in remove_ret = ::remove(path);
Return rc;
}
然后这个DB,可能是没有招接口,这个接口的,招接口就是其实可以这是不需要其他信息的,应该是只需要我们的一个标准应用就可以了,这里都是蛮简单的,然后再给它把一个声明给它加上去。给它放在一起可以看到多个table,看看是在DP里面需不需要实现一下,就是上表表明的是什么。首先,要去先去把这个表找出来,接着可以做更多事情,比如可以先对这个表你做一下调研,当然这里就先省略了。加一个上表的一个这个上表的时候,再可以参考一下电表下表的时候其实是有一个,它需要一个这样的参数,告诉它原文件的一个位置,那其实它上表的时候,其实一个表它也收到了,同样去把这个参数给它,要去把这个表给删掉。这样写很清晰,然后这里没有关注这个关系的方式,其实正常应该去处理它,这里就简单调过去了,那再去看一下这个table 的事项,这table最关键的地址在这个,这里判断一下这个表是不是存在,如果不存在,就直接返回一个,应返回一个错误。我看看有没有错误,因为跟table相关,然后table的意思,其实还可以在上面加一些日志,等去调试,参考刚才的一个这样的一个过程,所以自己一个表,肯定知道是表的名字,看看这是建表的,那就在这里,下面去写一个删表的过程。
RC BufferPoolManager :: remove_file ( const char * file_name )
{
RC rc = close_file ( file_name );
int remove _ret =:: remove ( file_ name );
return rc;
}
看看这是一个原数据文件,其实它写的时候可以把这个变量写的更清晰一点,或者加上注释,可以看一下,它代表的一个过程,应该是先把不要的给释放掉,然后,是要把它的一个,包括后面的关联的数据文件删掉,然后关联的包括给释放掉。然后再看刚的就是元素的文件删掉,就按照这个思路来去写一下。这个申请的它是一个函数。那他是做了什么,它去找了一个数据文件,然后去关联了一个buffer 的manager,然后有一个,如果他去做了一下数量,那去把这个给释放掉,然后给它删掉,就是它的逆过程。
其实这里不应该判断反馈值,这里就简单的直接就然后再关联,然后把关联的这个把home数据文件给它清理掉,把这个拷贝过来。相当于希望是这里面有论文的时候,他把对应的数据文件的文件本身也去释放掉,那接下来就把原数据文件给清理掉,原数据文件,看到有数据文件,这是直接建的,那直接去给他删除就可以了。调原文的接口好。这里其实应该判断一下返回值,都没有做,这个看起来是就可以了,但是这里有个漏洞,来去就是表上面的关联的资源是不是都释放掉了,可以再看一下表的一个数据。
它有一个原数据文件,一个数据文件,还有一个记录管理,这三个都清理掉了,但是下面,还有一个索引,索引是没有清理掉的,按照这个逆过程,就是应该先删除索引,因为是在建表的时候,把一些数据文件什么的都建好了,才去创建索引,那反过来,就是先把索引给清理掉,清理索引,看看索引有什么接口,索引是没有drop接口的,有没有可以的接口,先看看,先假设它有个drop接口,待会去实现它,先给它加上这个因,索引就是一个蓄积类,它现在有一种索引,就是B+Tree索引,这样看起来流程也就正确了。所以然后清理一些技术的文件,还有一些有数据文件,那就刚才留了两个地方没有实现的,是加上来的,然后去把它实现掉,这个是没有实现的,在这个范围可以参考一下close,看一下close fire是怎么实现的,它是把找到了对应的buffer对象之后,然后把它给从我们的管理的内存里面去给它清理掉,然后再去删除掉这个对象,那么它相对于原木来说,它少了一个动作,就是没有把文件给清理掉,那待会再去把文件给清理掉就可以了。这个实现相对看起来是简单一点,粗暴一点,也不管返回值,再去把文件给删掉,这里其实可以加一些判断返回值和一些调试,这个很容易的实现了,那看索引,索引是不是也比较容易,索引的现在一个时间只有be plus three,看一下,这里是有一个create,但是也没有drop,给它加一个drop。这个不太对称,这个drop结构是一个存在的,去看一下the create怎么实现的,然后去模仿一下。
看create的时候,它会去初始化一个这最开始的一个初始化信息,
然后会创建一个in the end的,来看一下是什么,它是一个必加数的一个hand的,去做一个创建的一个动作,然后再做一些数字化,那也看一下open和close open的,Open也相对来说,也就是一个hand的一个打开的一个动作,Close看一下是index hand的一个close动作,那来模仿一下,这就不做这些多余的判断,直接来看,其实它有一个重接口就可以了。那也去先浏览一下他们的代码。创建的时候它也会有一个跟包括后去做关联,就是它也是算在文件里面,文件里面通过包括manage来去做管理,通过包括来去做磁盘跟内存的数据的一个交换,来去创建了一个包括有关联的文件数据。然后做了一些初始化,这个创建还是蛮复杂的,可以跳去来看看 close。
直接去调了报告库的一个close file,那就是他只需要把对应的召回去实现,只需要把对应的我们buffer后来去释放掉就可以了,这个代码不一定是最优的。报告库的文件名,这就是包括这个放到上面也看不到,这个包括的文件名是有的,看怎么拿掉,他没有接口返回文件名,直接把那个文件名露出来,给他加到下面去的代码风格,这个都和效率都不一定是最好的,可以来优化,现在就是做一个延时。这样就实现了一个,但是刚才好像没有在这里做声明。这里也多,那这里也实现了,就统统给删掉,到这里看起来就实现了,其实整个过程,也差不多是也就十几分钟,相对较快。
我们来快速演示一下,输入:
git co -b drop-table
ls
emacs
ls
git b
git stash
emacs
ls
git b
git status
git apply drop_table.patch
git diif
ls
vi drop_table.patch
cd build/
make -j
ls
./bin/observer -s miniob.sock ^c
ls
rm -rf miniob;
./bin/observer -s miniob.sock -f ../etc/observer.ini &;
Successfully load ../etc/observer.ini;
show tables;//查看有没有表
create table t(id int);//创建表
show tables;//查表
drop table t;//执行设备
show tables;
create table t(id int);//去创建同样的表,在写代码测试过程写的全一点
insert into t values(1);//插数据
create indes i_id on it (id);//建索引
show tables;
select * from t;
drop table t;
create table t(id int);
create indes i_id on it (id);