这是我参与「第三届青训营 -后端场」笔记创作活动的第五篇笔记。
1.RDBMS 事务 ACID
- 事务(Transaction):是由一组SQL语句组成的一个程序执行单元(Uint),他需要满足ACID特性
//小呆鸟抢到1亿红包为例
BEGIN;
UPDATE account_tablne SET balance = balance - 1亿 WHERE name = "抖音"
UPDATE account_tablne SET balance = balance + 1亿 WHERE name = "小呆鸟"
COMMIT;
ACID
- 原子性(Atomicity): 事务是一个不可在分割的工作单元,事务中的操作要么都发生,要么不发生。
- 一致性(Consistency): 数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。
- 隔离性(Isolation): 多个事务并发访问的时,事务之间是隔离的,一个事务不应该影响其他事务运行效果。
- 持久性(Durability): 在事务完成以后,该事务所对数据库所做的更改便持久到保存在数据库之中,并不会被回滚。
2.关键技术
2.1 一条SQL的一生
Parser(语法解析器)
: 需要解析SQL语句,SQL语句只是对人友好,对机器并不友好AST(语法树)
: 将UPDATE等语言生成语法树。Optimizer(优化器)
: 根据语法树生成我这个SQL应该怎么执行Executor(执行器)
: 它拿着优化器的产物plan(树状结构),进行执行,从文件中读取数据,并写入日志,将数据返回给用户
SQL引擎:Parser,Optimizer,Executor 存储引擎:Data File,Log File
2.2 SQL引擎
Parser
Executor
向量化
- 每个Operator每次操作计算的不再是一行数据,而是一批数据(Batch N行数据),计算完成后向上层算子返回一个Batch
优点
: - 函数调用次数降低为1/N
- CPU cache命中率更高
- 可以利用CPU提供的SIMD(Single Instruction Multi Date)机制。(一条CPU指令可以计算多条数据,例如16个数据加法,可能加16次,但是用SIMD机制,一次性就能把16个数据加在一起)
编译执行
将用户的代码全部都写在一个函数里面。把所有用户的SQL全部写在一个函数也是不太可能的,因用户是千变万化的,之前为了拆分成不同的算子,就是为了解决用户千变万化的。
为了解决把用户SQL全部写在一个函数中,引入LLVM动态编译执行技术
2.3 存储引擎
InnlDB
Buffer Pool
- 每个页面是16k,每个chunk是128兆,生成一个个小的页面,每个页面用来存储数据。
- 把整个数据库生成多个instance,这就使得每次访问一个页面,他一定是在某一个instance,可以降低页面访问的冲突
- 在数据库中通过
LRU
的机制管理内存,把老的数据淘汰掉,把新的数据保留下来(内存的容量比磁盘的容量,小的多) - 当访问数据的时候,内存中的数据是不足的,此时就需要从磁盘上访问数据,如果磁盘访问后,内存此时放不下数据了,这就需要
LRU
机制,进行淘汰
Page
B+ Tree
2.4 事务引擎
事务引擎;ACID