跟随一条insert语句,进入tidb的源码世界(上)

lijingshanxi lijingshanxi     2022-12-15     407

关键词:

TiDB是google F1的开源实现;

TiDB实现了基于mvcc的乐观锁,在线表结构变更,基于时间戳的数据线性一致性,等等;

为了可靠性,TiDB和Oracle一样,维护了百万级别的自动化测试用例,跑在k8s搭建的集群之上;

TiDB里面用到的算法,都会写测试程序验证,以证明算法的正确性;

自 google F1开始,数据库被分成了两类:

  一类是传统sql,代表如Oracle,依赖于高速网络和磁盘阵列来实现海量数据的扩容和数据的高可靠,成本及其高昂,大部分银行都用了Oracle的系统;

  另一类是NewSQL,代表如F1和TiDB,依赖于各种算法,使数据库服务能运行在由廉价服务器搭建的集群之上,同样保证了海量数据的扩容和数据的高可靠;

在看TiDB源码之前, 再简单回顾一下TiDB的结构:

技术图片

 

本篇文章涉及的内容是上述橙色部分---TiDB-Server的代码;

TiDB-Server 是用go实现的,go的代码组织非常友好, 相比之下, C++ 和 Java 的各种编译脚本和代码依赖仓库管理非常复杂而且容易出错;

TiDB-Server编译之后生成的可执行文件是 tidb-server, 可以单独运行, 没有 tipd 和 tikv也能启动,实际上代码里面对 tipd和tikv实现了mock;你可以把 tidb-server理解成一个mysql-server;

因为篇幅所限, 这里只介绍一下大体流程; 让我们对数据库的实现有一个简单的认识;

假设我们在mysql客户端执行了一条insert语句---"insert into t1 values("zhangshan", 5000000);" ,这条语句是怎样被TiDB-Server执行的呢? 

先看看mysql客户端接入部分的代码:

技术图片

 

连接上来之后, 会读取mysql客户端数据, 按照mysql 客户端服务端协议进行解析;

技术图片

 

 注:我们下面对代码里面的变量举例时,用的都是这条sql---"insert into t1 values("zhangshan", 5000000);"

 我们看看cc.dispatch的实现

 技术图片

 

query类型的sql在 clientConn.handleQuery 里面处理:

技术图片

 

 一连串调用之后来到了session.execute, 我们看看实现:

技术图片

 

 session.execute里面做了这几件事:

  1. 通过语法和词法分析将sql解析为抽象语法树,进而生成一个InsertStmt结构体;

    语法分析和词法分析使用的是go语言版的yacc和lex;

    tidb用了一个工具ebnf2y(EBNF文法转 .y文件)将mysql的sql BNF文法转为了 parser.y,可以参见 github.com\\pingcap\\parser\\parser.y;

    值得一提的是,pingcap将sql解析器从tidb独立出来,可以方便的供其他项目使用;

  2. 优化sql, 生成执行计划;

    

  3. 执行sql;

    对于 insert 语句,将数据插入到 kv 中;

    tidb-server 中 mock kv 是直接把键值对保存在了 go 语言版的 leveldb 中;

 我们看看Insert语句对应的结构体:

技术图片

限于篇幅,暂时讲到这里,下篇我们一起进入 session.executeStatement 函数;

看 tidb 是怎样将列数据编码为 kv,插入到 go leveldb 中的;

 

如何打造3d立体世界?跟随图片一同探寻

...re图形等领域能力全面开放,使能3D数字世界创新。请跟随图片一起进入HMSCore打造的3D立体世界吧。了解更多详情>>访问华为开发者联盟官网获取开发指导文档华为移动服务开源仓库地址:GitHub、Gitee关注我们, 查看详情

求一条插入并返回的sql语句

面试的时候面试官跟我提了这样一个问题,就是插入一条记录了之后将这条记录的ID返回出来,注意,可能同一时间提交了很多条,不可能insert了之后还select,这样可能不准确。将OUTPUTINTO用于简单INSERT语句下例向ScrapReason表插入... 查看详情

简单的insert语句(代码片段)

...插入数据,比如执行下面的语句就可以向T_Person表中插入一条数据:INSERTINTOT_Person(FName,FAge,FRemark)VALUES("Tom",18,"USA");这句SQL向T_Person表中插入了一条数据,其中FName字段的值为"Tom",FAge字段的值为18,而FRemark字段的值为"USA"。VALUES前... 查看详情

带着问题读tidb源码:hive元数据使用tidb启动报错

《带着问题读源码系列》-开篇在TiDB社区活跃较久的伙伴们应该知道,过去我们有被称为24章经的《TiDB源码阅读系列文章》,也有面向TiKV的《TiKV源码解析系列文章》以及《DeepDiveTiKV系列文章》。这些系列文章的内容非常... 查看详情

【sql求助:insert语句加判断条件】insert一条数据入库时,判断数据库里面是不是存在。

...device设备表中有<ID,code设备编号,type设备类型>当Insert一条新的设备数据时,想判断数据库中是否已存在code为0047的设备,如果不存在,则新增。在网上搜到的ifisnot和ifNOTEXISTS都是不行的,我用的是mysql插入前先判断一下是否存... 查看详情

mysql和tidb在snapshot隔离级别上的区别(代码片段)

...c;mysql并不是事务开始的时候获得一个snapshot而是在执行第一条SQL语句的时候获得snapshot的;而TiDB是在事务开始的时候获得一个snapshot参考https://pingcap.com/blog-cn/tikv-source-code-reading-12/TiDB在事务开始 查看详情

带着问题读tidb源码:powerbidesktop以mysql驱动连接tidb报错(代码片段)

常有人说,阅读源码是每个优秀开发工程师的必经之路,但是在面对像类似TiDB这样复杂的系统时,源码阅读是一个非常庞大的工程。而对一些TiDBUser来说,从自己日常遇到的问题出发,反过来阅读源码就是一... 查看详情

简化的insert语句(代码片段)

...某些字段没有值,我们可以忽略这些字段。下面我们插入一条没有备注信息的数据:INSERTINTOT_Person(FAge,FName)VALUES(22,"LXF")执行SELECT*FROMT_Person来查看表中的数据:INSERT语句还有另一种用法,可以不用指定要插入的表列,这种情况下... 查看详情

用insertinto怎么添加多条记录

...是查询的字段,然后加values,后面跟记录值;用括号表示一条记录,添加多条记录只要每条记录中间加逗号隔开就行了。3、输入sql语句之后,点击上方的执行按钮,如果执行成功会在下面输出提示。4、最后来到part表中,即可看... 查看详情

insert语句执行速度慢应该怎么解决

参考技术A通常大数据插入的话都不会一条一条插入,使用bulkinsert等方法。如果是程序限制的话,一批一批的提交BEGINTRANSACTIONINSERT…INSERT…INSERT…COMMITTRANSACTION另外去掉索引,把日志设为简单都能提高一点效率 参考技术BOracle的... 查看详情

用一条insert插入多行数据的方法(代码片段)

今天需要用一条insert语句来插入多行数据,觉得这个真的挺实用,不用再用程序来for循环一遍一遍的插入了,事物处理也方便,不同数据库有不同的写法,下面我就来给大家分享一下吧!MySqL数据库:Sq... 查看详情

sqlserver——批量操作(批量添加,删除)

批量添加数据:一条insert语句批量插入多条记录常见的insert语句,向数据库中,一条语句只能插入一条数据:insert into persons (id_p, lastname , firstName, city )values(204,‘haha‘ , ‘deng‘ ,  查看详情

批量插入数据

...会遇到向数据表中插入多条记录的情况,用INSERT语句可以一条一条地插入数据,但这样做明显比较麻烦,这时可以进行批量插入数据,提高工作效率。接下来分为两个方面讲解,一个是为所有列批量插入数据,另一个是为指定列... 查看详情

同表复制一条数据,除主键外,其他值相同

...levalue()。今天使用SQL的Insert语句时。实现一个功能,复制一条数据,主键不同,数据相同。举例如下:1、表结构   环境为SqlServer2008。2、Code  (1)把Value句换成select语句,  (2)select语句中把主键换为插入语句的主... 查看详情

用excel批量生成insert语句

...&"‘,‘"&C2&"‘)")  可以看到就自动生成了一条insert语句。然后定位到D2列,将鼠标放在D2的右下角位置,就出现了一个黑色的十字形状,然后选中直接往下拖,就可以批量的生成insert语句了   查看详情

如何用sql语句向一个表中插入多行记录

insert一般是用来给表插入一条指定的列值的,但是,insert还存在另一种形式,可以利用它将一条select语句的结果插入表中。这就是所谓的insertselect,顾名思义,它是由一条insert语句和一条select语句组成的。假如你从另一张表中合... 查看详情

insert语句返回值

...不排列的话就是最下面的一列不过也难说,看你有没有这一条的某些数据或者标示,最好有才更好查找些 参考技术BWITHTB_TEMPAS(SELECTROW_NUMBER()OVER(ORDERBYIDDESC)ASROWIDFROMTB_1);SELECT*FROMTB_TEMPWHEREROWID=(SELECTMAX(ROWID)FROMTB_TEMP); 参考技术C没有... 查看详情

反射生成insert多个对象的sql语句

...rderInfo>,那么接口的实现就需要将List<OrderInfo>转为一条完整的SQL语句。如:insertintoperson(name,age,info)values(‘18岁的郑斌‘,1 查看详情