范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

自己动手写SQL执行引擎

  作者:alchemystarlzy 来源:解bug之路
  在阅读了大量关于数据库的资料后,笔者情不自禁产生了一个造数据库轮子的想法。来验证一下自己对于数据库底层原理的掌握是否牢靠。在笔者的github中给这个database起名为Freedom。
  整体结构
  既然造轮子,那当然得从前端的网络协议交互到后端的文件存储全部给撸一遍。下面是Freedom实现的整体结构,里面包含了实现的大致模块:
  最终存储结构当然是使用经典的B+树结构。当然在B+树和文件系统block块之间的转换则通过Buffer(Page) Manager来进行。当然了,为了完成事务,还必须要用WAL协议,其通过Log Manager来操作。
  Freedom采用的是索引组织表,通过DruidSQL Parse来将sql翻译为对应的索引操作符进而进行对应的语义操作。
  MySQL Protocol结构
  client/server之间的交互采用的是MySQL协议,这样很容易就可以和mysql client以及jdbc进行交互了。
  query packet
  mysql通过3byte的定长包头去进行分包,进而解决tcp流的读取问题。再通过一个sequenceId来在应用层判断packet是否连续。
  result set packet
  mysql协议部分最复杂的内容是其对于result set的读取,在NIO的方式下加重了复杂性。
  Freedom通过设置一系列的读取状态可以比较好的在Netty框架下解决这一问题。
  row packet
  还有一个较简单的是对row格式进行读取,如上图所示,只需要按部就班的解析即可。
  由于协议解析部分较为简单,在这里就不再赘述。
  SQL Parse
  Freedom采用成熟好用的Druid SQL Parse作为解析器。事实上,解析sql就是将用文本表示
  的sql语义表示为一系列操作符(这里限于篇幅原因,仅仅给出select中where过滤的原理)。
  对where的处理
  例如where后面的谓词就可以表示为一系列的以树状结构组织的SQL表达式,如下图所示:
  当access层通过游标提供一系列row后,就可以通过这个树状表达式来过滤出符合where要求的数据。Druid采用了Parse中常用的visitor很方便的处理上面的表达式计算操作。
  对join的处理
  对join最简单处理方案就是对两张表进行笛卡尔积,然后通过上面的where condition进行过滤,如下图所示:
  Freedom对于缩小笛卡尔积的处理
  由于Freedom采用的是B+树作为底层存储结构,所以可以通过where谓词来界定B+树scan(搜索)的范围(也即最大搜索key和最小搜索key在B+树种中的位置)。考虑sqlselect a.*,b.* from t_archer as a join t_rider as b where a.id>=3 and a.id<=11 b.id and b.id>=19 b.id<=31
  那么就可以界定出在id这个索引上,a的scan范围为[3,11],如下图所示:
  b的scan范围为[19,31],如下图所示(假设两张表数据一样,便于绘图):
  scan少了从原来的15*15(一共15个元素)次循环减少到4*4次循环,即循环次数减少到7.1%
  当然如果存在join condition的话,那么Freedom在底层cursor递归处理的过程中会预先过滤掉一部分数据,进一步减少上层的过滤。B+Tree的磁盘结构
  leaf磁盘结构
  Freedom的B+Tree是存储到磁盘里的。考虑到存储的限制以及不定长的key值,所以会变得非常复杂。Freedom以page为单位来和磁盘进行交互。叶子节点和非叶子节点都由page承载并刷入磁盘。结构如下所示:
  一个元组(tuple/item)在一个page中分为定长的ItemPointer和不定长的Item两部分。
  其中ItemPointer里面存储了对应item的起始偏移和长度。同时ItemPointer和Item如图所示是向着中心方向进行伸张,这种结构很有效的组织了非定长Item。
  leaf和node节点在Page中的不同
  虽然leaf和node在page中组织结构一致,但其item包含的项确有区别。由于Freedom采用的是索引组织表,所以对于leaf在聚簇索引(clusterIndex)和二级索引(secondaryIndex)中对item的表示也有区别,如下图所示:
  其中在二级索引搜索时通过secondaryIndex通过index-key找到对应的clusterId,再通过
  clusterId在clusterIndex中找到对应的row记录。
  由于要落盘,所以Freedom在node节点中的item里面写入了index-key对应的pageno,
  这样就可以容易的从磁盘恢复所有的索引结构了。
  B+Tree在文件中的组织
  有了Page结构,我们就可以将数据承载在一个个page大小的内存里面,同时还可以将page刷新到对应的文件里。有了node.item中的pageno,我们就可以较容易的进行文件和内存结构之间的互相映射了。
  B+树在磁盘文件中的组织如下图所示:
  B+树在内存中相对应的映射结构如下图所示:
  文件page和内存page中的内容基本是一致的,除了一些内存page中特有的字段,例如dirty等。
  每个索引一个B+树
  在Freedom中,每个索引都是一颗B+树,对记录的插入和修改都要对所有的B+树进行操作。
  B+Tree的测试
  笔者通过一系列测试case,例如随机变长记录对B+树进行插入并落盘,修复了其中若干个非常诡异的corner case。
  B+Tree的todo
  笔者这里只是完成了最简单的B+树结构,没有给其添加并发修改的锁机制,也没有在B+树做操作的时候记录log来保证B+树在宕机等灾难性情况下的一致性,所以就算完成了这么多的工作量,距离一个高并发高可用的bptree还有非常大的距离。
  Meta Data
  table的元信息由create table所创建。创建之后会将元信息落盘,以便Freedom在重启的时候加载表信息。每张表的元信息只占用一页的空间,依旧复用page结构,主要保存的是聚簇索引和二级索引的信息。元信息对应的Item如下图所示:
  如果想让mybatis可以自动生成关于Freedom的代码,还需实现一些特定的sql来展现Freedom的元信息。这个在笔者另一个项目rider中有这样的实现。原理如下图所示:
  实现了上述4类SQL之后,mybatis-generator就可以通过jdbc从Freedom获取元信息进而自动生成代码了。
  事务支持
  由于当前Freedom并没有保证并发,所以对于事务的支持只做了最简单的WAL协议。通过记录redo/undolog从而实现原子性。
  redo/undo log协议格式
  Freedom在每做一个修改操作时,都会生成一条日志,其中记录了修改前(undo)和修改后(redo)的行信息,redo用来回滚,redo用来宕机recover。结构如下图所示:
  WAL协议
  WAL协议很好理解,就是在事务commit前将当前事务中所产生的的所有log记录刷入磁盘。
  Freedom自然也做了这个操作,使得可以在宕机后通过log恢复出所有的数据。
  回滚的实现
  由于日志中记录了undo,所以对于一个事务的回滚直接通过日志进行undo即可。如下图所示:
  宕机恢复
  Freedom如果在page全部刷盘之后关机,则可以由通过加载page的方式获取原来的数据。
  但如果突然宕机,例如kill -9之后,则可以通过WAL协议中记录的redo/undo log来重新
  恢复所有的数据。由于时间和精力所限,笔者并没有实现基于LSN的检查点机制。
  Freedom运行git clone https://github.com/alchemystar/Freedom.git// 并没有做打包部署的工作,所以最简单的方法是在java编辑器里面run alchemystar.freedom.engine.server.main
  以下是笔者实际运行Freedom的例子:
  join查询
  delete回滚
  Freedom todo
  Freedom还有很多工作没有完成,例如有层次的锁机制和MVCC等,由于工作忙起来就耽搁了。
  于是笔者就看了看MySQL源码的实现理解了一下锁和MVCC实现原理,并写了两篇博客。比起
  自己动手撸实在是轻松太多了^_^。
  MVCC
  https://my.oschina.net/alchemystar/blog/1927425
  二阶段锁
  https://my.oschina.net/alchemystar/blog/1438839
  尾声
  在造轮子的过程中一开始是非常有激情非常快乐的。但随着系统越来越庞大,复杂性越来越高,进度就会越来越慢,还时不时要推翻自己原来的设想并重新设计,然后再协同修改关联的所有代码,就如同泥沼,越陷越深。至此,笔者才领悟了软件工程最重要的其实是控制复杂度!始终保持简洁的接口和优雅的设计是实现一个大型系统的必要条件。
  收获与遗憾
  这次造轮子的过程基本满足了笔者的初衷,通过写一个数据库来学习数据库。不仅仅是加深了理解,最重要的是笔者在写的过程中终于明白了数据库为什么要这么设计,为什么不那样设计,仅仅对书本的阅读可能并不会有这些思考与领悟。
  当然,还是有很多遗憾的,Freedom并没有实现锁机制和MVCC。由于只能在工作闲暇时间写,所以断断续续写了一两个月,工作一忙就将这个项目闲置了。现在将Freedom的设计写出来,希望大家能有所收获。

啪啪漏风?想要改善就这样练很多人在生完孩子以后,觉得夫妻生活不如从前或很难达到高潮,大多会怪罪是生孩子让阴D变医学界妇产科频道以下文章来源于腾讯医典她知,作者知妹很多人在生完孩子以后,觉得夫妻生活不如从前或为了后代智商,甲减女性怀孕前后必须做到这八点甲减可使孕妇发生妊高症流产死胎,早产胎盘早剥低出生体重儿产后出血等并发症的风险大大增加。因此,孕前及孕期对母体甲功进行监测并给予及时恰当的治疗十分重要。没得到良好控制的甲减对于母婴不运动比肥胖更可怕每天20分钟快走延年益寿核心提示在沙发土豆越来越多的今天,缺乏锻炼致死的风险是肥胖所引起的两倍。而据英国每日邮报近日报道,美国的一项研究发现,每天只需20分钟的快走就有助于增加寿命。在沙发土豆越来越多的今甲减准妈妈请不要私自调整药量粉丝老师您好,我是备孕期间发现甲减一直在服用优甲乐。每月抽血查甲功,基本上三项(t3t4tsh)都在正常范围内。目前已经怀孕19周,在16周检查甲功都在正常范围内,但是tsh已经由甲减变胖?该怎么减肥?门诊接诊一位中年女性,近半年来明显发胖,但体力却越来越差,干什么都提不起精神,还总感觉怕冷,仔细给她做了检查,结果发现甲状腺明显肿大,血清甲状腺激素FT3FT4降低,促甲状腺激素T新生儿一过性TSH水平升高新生儿一过性TSH水平升高,就是甲功结果中除TSH水平升高外,其他项目都正常。医生您好,想咨询您一下朋友的小孩出生第8天抽了足底血去检查,第20天的时候医院筛查阳性,TSH24。然妈妈掐死1岁儿子判无期,悲剧已发生,很多人却视而不见卫士提醒产后甲状腺炎的发生率在生第一胎后大约是30,在生二胎后可以达到69。产后甲状腺炎有一个甲亢期和甲减期,很容易让产后宝妈出现抑郁症状。如果及时发现,及时治疗,就不会出现抑郁。小蝌蚪变形记原创马琳枝Hi!我是小蝌蚪,大家都知道我与卵子结合形成受精卵是人体发育的第一步,可你们知道吗?一个小蝌蚪从无到有再到发育成熟,会经历精细又复杂的过程,从发生到成熟要经过漫长的细胞分怀孕了,为什么一定要检查HCG和孕酮?在怀孕后,HCG孕酮对于维持妊娠来说,缺一不可。它们是相互刺激,相互依赖的。是一荣具荣,一损具损的关系。小珍,29岁,近日,平时规律的月经出现了问题,这个月的月经超期了。小珍急忙到甲减危象(黏液性水肿昏迷)甲减危象又叫黏液性水肿昏迷,是甲减最严重的并发症。即使及时治疗,死亡率也可达到50,治疗不及时死亡率更高。甲减危象多发生于如下情况下(1)老年人儿童孕妇等特殊群体(2)甲减病情较重反复口腔溃疡,为什么清热没有用?导读今天学习谢海洲先生本着急则治其标,缓则治其本的原则,治愈慢性口腔溃疡的经验。口疮病有久暂,症分虚实,新发者易图,久病者难疗。其与心脾小肠胃诸脏腑息息相关,病因病机非止一端。01
电影失孤原型找到了儿子,小心伸向你家孩子的手7月13日上午10时,公安部召开我为群众办实事系列新闻发布会,通报团圆行动最新成效,介绍电影失孤原型拐卖案件侦破情况,至此,郭刚堂儿子被拐卖的真相大白。近期一则新闻报道,一个被人贩电影缝纫机乐队的情怀本文来自于天贝兄闲谈。情怀,指含有某种感情的心境。而所谓卖情怀,就是打感情牌,为了利益和票房,抓住人们的人文情怀回忆做的电影。电影缝纫机乐队讲述的是集安市修车行老板胡亮邀请落魄的破黄奕拒绝女儿攀比式购物不倾听孩子内心的批评,影响孩子一生欢迎淼淼妈妈爱分享,一个有着10年幼教工作经验的宝妈,用专业与经验,陪您一起育儿!本文是自己原创第20篇,原创不易,请勿抄袭!采用网络图片,若有不适请联系立马删除。近日,黄奕教育女妈妈做好这3点,女儿更加优秀我有一名女宝,今年3岁,当了妈妈之后,我才知道,比起生产的痛,还有一种担忧更加痛。既想女儿以后的路走的长远,又担心她被沿途的危险伤害。伴随女儿的长大,这种矛盾的神经,如影随形。风靡爸爸们的烦恼如何成为女儿的靠谱老爸,教你四招,招招有效风靡全球的养育女儿这边书的作者史蒂夫,有个儿子,所以养育过男孩。后来又有了女儿,他用亲身经历告诉我们,在养育女孩的过程中,如果爸爸比较投入那么女儿通常都会表现得更自信,不管学业技能小S和女儿当闺蜜,是要付出代价的亲子闺蜜,到底该怎么处?欢迎淼淼妈妈爱分享,一个有着10年幼教工作经验的宝妈,用专业与经验,陪您一起育儿!本文是自己原创第23篇,原创不易,请勿抄袭!采用网络图片,若有不适请联系立马删除。为什么小S居然后张若昀首谈女儿,第一块尿布是自己换的做学习型父母有多重要?本文首发来源爸妈进化论(IDbmjhlc)欢迎淼淼妈妈爱分享,一个有着10年幼教工作经验的宝妈,用专业与经验,陪您一起育儿!本文是自己原创第25篇,原创不易,请勿抄袭!采用网络图片人类曾经被毁灭434大洪水以前,先哲们已经预见到大灾难将至阿拉伯古代历史学家马斯乌蒂,根据当时的资料作了如下记载一位洪水之前还活着的帝王斯利德,命令祭司们造两座大金字塔,将他们得到的知识和各种艺术以及科学成果藏在里面。这是为了使这些成果躲写作需要逻辑,不能总用蛮力来源女教授跟生活的死磕作者吉大秋果那么简单粗暴,你能写出论文吗?我在指导学生论文写作的时候,第1步要求他们在充分阅读的基础之上,提出一个要解决的问题第2步要求他们提供给我这个问题的划清界限别拿这儿当自己家当一个女人嫁给一个男人时,她必须和她的亲戚相处。如果家庭成员之间没有划清界限,就会产生很多矛盾,从而导致彼此关系紧张,甚至影响夫妻关系。婚后,考虑到婆婆的年龄,他们带她一起生活。她从问题兵到新兵班长的艰难历程本文来自于投稿,作者潘朝晖。自从我被打入冷宫,我就想着如何翻身,最后决定从头开始,从现在的施工队开始,我要重新积极要求进步!施工队的生活,枯燥而又简单。白天施工,晚上学习。政治学习