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

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 中的;

原文地址:https://www.cnblogs.com/lijingshanxi/p/10958729.html

时间: 2024-08-01 15:23:07

跟随一条insert语句, 进入TiDB的源码世界(上)的相关文章

一条insert语句批量插入多条记录 AND 多条件游标更新 变CASE WHEN更新法提高速度

一条insert语句批量插入多条记录 常见的insert语句,向数据库中,一条语句只能插入一条数据: insert into persons (id_p, lastname , firstName, city ) values(204,'haha' , 'deng' , 'shenzhen'); (如上,仅插入了一条记录) 怎样一次insert插入多条记录呢? 使用示例: insert into persons (id_p, lastname , firstName, city ) values

laravel 获取上一条insert语句产生的id

<?php //頭部引入DB類 use Illuminate\Support\Facades\DB; //在方法中獲取获取上一条insert语句产生的id $id = DB::getPdo()->lastInsertId(); 原文地址:https://www.cnblogs.com/clubs/p/9936652.html

管窥Android中的滑动条SeekBar的父类AbsSeekBar的源码

Android中的控件中有一类是ProgressBar,其子类中有一个是AbsSeekBar.相信有不少童鞋对这个拖动条的父类比较感兴趣吧!尤其是看到网易云音乐的进度条上面是可以处理播放与暂停事件,是不是很羡慕的哈~  俺在这里告诉大家,不用羡慕,看了我下面的代码分析,你也是可以做出那样的效果的哦.Let's go. 下面先给大家列表一下AbsSeekBar的成员变量有哪些. //当前的矩形 private final Rect mTempRect = new Rect(); //可以拖动的滑块

一条insert语句插入数据库

CREATE TABLE test_main ( id INT NOT NULL, value VARCHAR(10), PRIMARY KEY(id) ); oracle插入方式:INSERT INTO test_main(id, value) SELECT 1, 'ONE' FROM dual UNION ALLSELECT 2, 'TWO' FROM dual; mysql.postgresql插入方式: INSERT INTO test_main(id, value) values(1,

Hibernate格式化sql语句实体类 BasicFormatterImpl 源码

package com.util; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; import java.util.StringTokenizer; public class BasicFormatterImpl { private static final Set<String> BEGIN_CLAUSES = new HashSet<String>(); private

MySQL insert语句中中value和values的区别(二)

最近公司事情太忙,作为以一挑十的测试,只能苦逼的累死累活的.好不容易临近上线,可以偷个懒写个文章. 简单的说说如何向表中插入数据: 1.向表中所有的列插入数据(插入多行数据): insert  into  表名 values (列值1,列值2,列值3...列值n), (列值a,列值b,列值c...列值n), ........... (列值A,列值B,列值C...列值N) 2.向表中指定的列插入数据(插入单行数据): insert  into  表名(列名1,列名2,列名3...列名n) valu

用excel批量生成insert语句

excel表格中有A.B.C三列数据,分别对应TableName的UserId.UserName.UserPwd三个字段.如下图所示 在excel的D2的位置,也就是A.B.C列的后面一列,添加下面公式 =CONCATENATE("INSERT INTO TABLENAME(UserId,UserName,UserPwd) VALUES('"&A2&"','"&B2&"','"&C2&"'

一条诡异的insert语句

问题背景 有同事反馈在mysql上面执行一条普通的insert语句,结果报错, execute failed due to >>> Incorrect string value: '\xA1;offl...' for column 'biz_info' at row 1 经过半天的折腾,终于搞清楚了来龙去脉,这里简单给大家分享下.为了方便说明,我将测试例子中的表和语句简化,但不影响问题重现. 问题复现 连接字符集:UTF8 表结构: CREATE TABLE `ggg` (   `id`

用一条SQL语句查出每门课都大于80分的学生的姓名

用一条sql语句查询出所有课程都大于80分的学生名单: name cource score 张三 语文 81 张三 数学 75 李四 语文 76 李四 数学 90 王五 语文 81 王五 数学 100 王五 英语 90 1 SET FOREIGN_KEY_CHECKS=0; 2 3 -- ---------------------------- 4 -- Table structure for grade 5 -- ---------------------------- 6 DROP TABL